0

I've written a small piece of code that should detect if there are any matching characters in the same place in the 2 strings. If there is , the score in incremented by 1, if there is 2 or more consecutive matching characters , the score is incremented by 3, if there is no matching character, the score is decremented by 1. The problem is though , when i try to run the code, it gives me a error: string index out of range. What might be wrong ? thank you very much.

def pairwiseScore(seqA, seqB):
    count = 0
    score = 0
    while count < len(seqA):
        if seqA[count] == seqB[count]:
            score = score + 1
            count = count + 1
            while seqA[count] == seqB[count]:  # This is the line the error occurs
                score = score + 3
                count = count + 1 
        elif seqA[count] != seqB[count]:
            score = score - 1
            count = count + 1
    return score
3
  • "What might be wrong?" you said it yourself "string index out of range". Don't get me wrong I understand it's homework but google is your friend and this is the time to get your debugging skills up and running Commented Apr 1, 2012 at 22:11
  • I'm sorry, I don't know the meaning of this error. From what i understand, it means that if a string is 8 characters long, and the index is [8], the error occurs. But, in my code, the index isn't longer than the lenght of the string. Commented Apr 1, 2012 at 22:15
  • @geekkid: see my answer. You ARE indexing past the length of the string. Commented Apr 1, 2012 at 22:18

7 Answers 7

1

Do both strings have the same lenght? otherwise you should consider using something like:

while count < min(len(seqA), len(seqB)):

Sign up to request clarification or add additional context in comments.

1 Comment

yes, both of the strings should have the same lenght. But non the less, thank you for your remark, as i didn't even know the min function exists :D .
1

Also, the zip function might come in handy here to pair off the letters in each word. It is a python builtin. e.g.

def letter_score(s1, s2):
    score = 0
    previous_match = False

    z = zip(s1, s2)
    for pair in z:
        if pair[0] == pair[1]:
            if previous_match:
                score += 3
            else:
                score += 1
                previous_match = True
        else:
            score -= 1
            previous_match = False
    return score

Comments

0

Indexes are numberd 0 to n.

len(someString)

will give you n + 1.

Let's say that your string is length 10, and the indexes are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Your while loop checks the condition that count is < 10. So far so good.

Ok now let's say that count is equal to 9. Immediately within the first while loop, you increment count.

So now count = 10.

Now attempting to access someString[count] will give you an IndexError because the indices only go up to 9.

Comments

0

The error message says it: You're trying to access a character beyond the boundaries of your string. Consider this:

>>> s = "hello"
>>> len(s)
5
>>> s[4]
'o'

Now when (at the start of the first while loop) count is 1 below len(seqA), then you're incrementing count and then you're doing seqA[count] which will throw this exception.

Let's assume you're calling pairwisescore("a", "a"):

score = 0
count = 0
while count < len(seqA):                   # 0 < 1 --> OK 
    if seqA[count] == seqB[count]:         # "a" == "a" --> OK
        score = score + 1                  # score = 1
        count = count + 1                  # count = 1
        while seqA[count] == seqB[count]:  # seqA[1] doesn't exist!

Comments

0

In the second while loop you must test that count is less than len(seqA):

while count < len(seqA) and seqA[count] == seqB[count]:
   ...

and, also there's possibly other bug: If the length of seqB is less than length of seqA, you'll again see runtime exception. so, you should change every occurence of count < len(seqA) with count < min(len(seqA), len(seqB)).

Comments

0
def pairwiseScore(seqA, seqB):
    count = 0
    score = 0
    isOne = False
    isTwoOrMore = False
    while count < min(len(seqA), len(seqB)):
        if seqA[count] == seqB[count]:
            if isTwoOrMore:
                score = score + 3
                count = count + 1
            else:
                if isOne:
                    isTwoOrMore = True
                score = score + 1
                count = count + 1
                isOne = True
        elif seqA[count] != seqB[count]:
            score = score - 1
            count = count + 1
            isOne = False
            isTwoOrMore = False
    return score

a = 'apple'
b = 'aplle'
print(pairwiseScore(a, b))

I think this one solve the problem, I added a "counting" bool variable. And to respond to the question, your program didn't compare the length of the second string.

while count < min(len(seqA), len(seqB)):

Comments

0

The problem is that you do this:

    count = count + 1

Both before the inner while loop and at the end of it. But you then continue using seqA[count] before checking it against len(seqA) again - so, once it goes too high, Python will try to read past the end of seqA, and you'll get that error (when, if the condition had been checked again after incrementing, the loop would have ended).

Using a Python for loop will get around bugs like this, since Python will manage count for you:

for a,b in zip(seqA, seqB):
     if a == b:
        score += 1

You can implement the extra-points bit easily in this by keeping track of whether the previous character is a match, rather than trying to work out how many after this one are. A boolean variable last_matched that you keep updated would help with this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.