1
>>> def lcm(a,b):
    if a<<b:
        c=a
        a=b
        b=c
    c=0
    lit=[a,b,c]
    n=3
    while (not lit[n%3]%lit[(n%3)+1]==0):
        lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
        if lit[(n%3)+2]==0:
            d=lit[(n%3)+2]
            print d
        else:
            n=n+1

This is the code, trying to build a function lcm that finds the least common multiplier of a and b. Not really the cleanest code of the bunch, but sadly this was all I could do. It would really be nice if this lump of code could be a little lighter.

So, err, back to the point, I called for lcm, and it just blurts out error messages.

This is what it says:

>>> lcm(78696,19332)

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    lcm(78696,19332)
  File "<pyshell#1>", line 10, in lcm
    lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
IndexError: list assignment index out of range

Aaaaand I have got absolutely no idea what I am supposed to do now.
What can I do now?

  • [Catch the exception](https://docs.python.org/2.7/tutorial/errors.html#handling-exceptions) and in the except suite, print out ```n``` and ```len(lit)```. I'm pretty sure the error is saying that you are trying to assign a value to an index of ```lit``` that doesn't exist - like ```len(lit)``` is 2 and you are trying to do ```lit[4] = 'foo'``` – wwii Feb 18 '17 at 06:09
  • For me, it would be easier on my eyes if a variable named ```n_mod3``` was used for all those subscripts - it could be calculated twice, once before the loop and again when ```n``` changes. – wwii Feb 18 '17 at 06:17

2 Answers2

0

n%3 can be as big as 2. so n%3 + 1 could be as much as 3. The list lit has only 3 items, so at this line,

lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]

if n%3 == 2, then accessing lit[(n%3)+1] will lead to index out of range error.

Fallen
  • 4,435
  • 2
  • 26
  • 46
0

Python lists are zero-indexed.

So lit[0] = a, lit[1] = b, and lit[2] = c.

lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]

If n = 1, then (n%3)+2 equals 3. If n = 2, then (n%3)+2 equals 4.

If you want to guarantee that you're accessing your list at a valid index, then you want to % by the length of the list- which you're doing, just not at the right place.

Without looking too deeply into your code, I think it's just another lesson that order of operations matters. Try (n+2)%3 instead of (n%3)+2.

x%3 will always be within the range [0, 2]- so that's why you want to mod at the very end. (x%3+n ends up in the range [n, 2+n].)

knyte
  • 3
  • 3