Search code examples
pythonloopserror-handlingprime-factoring

Python: Wrong output and ValueError: Prime Factors Creator


I've created a program that successfully detects whether a number is prime, or not, it also will return a list of the factors of the number if it isn't, but that part is not successful.

Here is my code:

def prime_num():

    num = int(input("Give me a number...: "))
    prime = True

    if num == 1:
        prime = False
    elif num == 2:
        prime = True

    for x in range(2, num):
        if num % x == 0:
            prime = False
            break

    if prime == False:
        print("That's not a prime number!")
        factors(num)
    elif prime == True:
        print("That's a prime number!")


def factors(num):

    factors = []

    for x in range(1, num+1):
        if num % x == 0:
            factors.append(x)
    print("The factors for " + str(num) + " are: ", factors)

    for x in factors:
        for y in range(1, x):
            if x % y == 0:
                factors.remove(x)
    print("The prime factors for " + str(num) + " are: ", factors)

When I use this function with a "num" value of 25 I get this output...

prime_num()

Give me a number...: 25
That's not a prime number!
The factors for 25 are:  [1, 5, 25]
The prime factors for 25 are:  [1, 25]

Which isn't the correct output for prime factors, I just want it to return: [5] (I'm not concerned about the multiplicity of the factors at this time)

However, when I try the number 50, as my "num". I get this output with a valueError:

prime_num()

Give me a number...: 50
That's not a prime number!
The factors for 50 are:  [1, 2, 5, 10, 25, 50]
Traceback (most recent call last):

  File "<ipython-input-19-12c785465e2a>", line 1, in <module>
   prime_num()

  File "C:/Users/x/Desktop/Python/Python Practice/primes.py", line 25, in prime_num
   factors(num)

  File "C:/Users/x/Desktop/Python/Python Practice/primes.py", line 40, in factors
   factors.remove(x)

ValueError: list.remove(x): x not in list

I realize this means somehow my x isn't in factors, but I'm not sure how considering I'm specifically iterating through factors.


Solution

  • This should make it clear what your problem is:

    factors = [1,5,25]
    
    for x in factors:
        for y in range(1,x):
            print x,y
    
    5 1
    5 2
    5 3
    5 4
    25 1
    25 2
    25 3
    25 4
    25 5
    25 6
    25 7
    25 8
    25 9
    25 10
    25 11
    25 12
    25 13
    25 14
    25 15
    25 16
    25 17
    25 18
    25 19
    25 20
    25 21
    25 22
    25 23
    25 24
    

    You're iterating over your factors in such a way that you ignore 1 and ignore the x % x combination. range(1,1) is the empty list, and then you simply stop short because you've increased the start point by 1 (from zero) but not the end point, leaving what you iterate over too short.

    The reason you get a ValueError is because any non-square number (ie, not 4, 9, 16, 25, etc.) will be removed twice. For 6, for example, it will remove for the 2,3 combo and when it gets to the 3,2 combo it's already been removed, thus the error. One way to fix this is to make the code only go halfway minus one to your total, so that inverted numbers aren't removed twice. For example, stop at 2 for 6, 4 for 10, etc.