Alvaro
Alvaro

Reputation: 21

Python List Indexing Error

def getPrimeList(check):
    storedprimes = []
    i = 2
    while i <= check:
        if isPrime(check):
            storedprimes = storedprimes + [i]
        i = i + 1
    return storedprimes
def getPrimeFact(check):
    primelist = getPrimeList(check)
    prime_fact = []
    i = 0
    while check !=1:
        if check%primelist[i]==0:
            prime_fact=prime_fact+[primelist[i]]
            check = check/primelist[i]
        i = i + 1
        if i == len(primelist):
            i = 0
    return prime_fact
def getGCF(checks):
    a=0
    listofprimefacts=[]
    while a<len(checks):
        listofprimefacts=listofprimefacts+[getPrimeFact(checks[a])]
        a=a+1
    b=0
    storedprimes=[]
    while b<len(primefactlist):
        c=0
        while c<len(listofprimefacts[b]):
            if listofprimefacts[b][c] not in storedprimes:
                storedprimes=storedprimes+[listofprimefacts[b][c]]
            c=c+1
        b=b+1
    prime_exp=[]
    d=0
    while d<len(storedprimes):
        prime_exp=prime_exp+[0]
        d=d+1

    e=0
    while e<len(storedprimes):
        f=0
        while f<len(listofprimefacts):
            if f==0:
                prime_exp[e]=listofprimefacts[f].count(storedprimes[e])
            elif prime_exp[e]-(listofprimefacts[f].count(storedprimes[e]))>0:
                prime_exp[e]=listofprimefacts[f].count(storedprimes[e])                
            f=f+1
        e=e+1
    g=0
    GCF=1
    while g<len(primelist):
        GCF=GCF*(storedprime[g]**prime_exp[g])
        g=g+1
    return GCF

I am creating a program that will use these functions for the purpose of calculating fractions; however, after testing my GCF function in the shell I keep getting a list indexing error. I have no idea, where the error is coming from considering im 99% sure there is no problems with my indexes, usually i would not post such a "fixable" problem in SO but this time i just have no idea what the problem is, thanks again.

Oh and heres the exact error

File "<pyshell#1>", line 1, in <module>
    getGCF(checks)
  File "E:\CompProgramming\MidtermFuncts.py", line 31, in getGCF
    listofprimefacts=listofprimefacts+[getPrimeFact(checks[a])]
  File "E:\CompProgramming\MidtermFuncts.py", line 20, in getPrimeFact
    if check%primelist[i]==0:
IndexError: list index out of range

Upvotes: 0

Views: 123

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1121564

You mixed up i and check in your getPrimeList() function; you test if check is a prime, not i; here is the correct function:

def getPrimeList(check):
    storedprimes = []
    i = 2
    while i <= check:
        if isPrime(i):  # *not* `check`! 
            storedprimes = storedprimes + [i]
        i = i + 1
    return storedprimes

This, primelist will be set to an empty list (as getPrimeList(check) returns an empty list) and your primelist[i] (for any i) will fail with an index error.

Another way for primelist to be empty is when isPrime() never returns True; you don't show us that function to verify it.

Your next error is in getGCF(); you define a listofprimefacts variable (a list) first, but later refer to a non-existing primefactlist variable, leading to a NameError. The next name error is going to be primelist further in that function.

You really want to re-read the Python tutorial; you are missing out on many python idioms in your code; specifically on how to create loops over sequences (hint: for check in checks: is easier to use than a while loop with an index variable) and how to append items to a list.

My personal toolkit defines this:

from math import sqrt

def prime_factors(num, start=2):
    """Return all prime factors (ordered) of num in a list"""
    candidates = xrange(start, int(sqrt(num)) + 1)
    factor = next((x for x in candidates if (num % x == 0)), None)
    return ([factor] + prime_factors(num / factor, factor) if factor else [num])

which doesn't need a isPrime() test.

Upvotes: 0

Blender
Blender

Reputation: 298136

You might want to re-think how you attack this problem. In its current form, your code is really hard to work with.

Here's how I'd do it:

def is_prime(n):
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False

    return True

def prime_factors(number):
    factors = []

    for i in range(2, number / 2):
        if number % i == 0 and is_prime(i):
            factors.append(i)

    return factors

def gcf(numbers):
    common_factors = prime_factors(numbers[0])

    for number in numbers[1:]:
        new_factors = prime_factors(number)
        common_factors = [factor for factor in common_factors if factor in new_factors]

    return max(common_factors)

This line right here:

common_factors = [factor for factor in common_factors if factor in new_factors]

Is a list comprehension. You can unroll it into another for loop:

temp = []

for factor in common_factors:
    if factor in new_factors:
        temp.append(factor)

common_factors = list(temp)  # Pass by value, not by reference

Upvotes: 1

Related Questions