Proto
Proto

Reputation: 71

String index out of range (Python3)

I keep getting string index out of range on line 4 (if s[i] != s[end-i]:) but I can't figure out why. I ran my code on visualizer but that didn't help me. The code is supposed to give me the longest palindromic substring after I input a string s

here is my code:

def isSubPalindrome (s,start,end):
    isPal = True
    for i in range (start,end):
        if s[i] != s[end-i]:
            isPal = False
    return isPal

def longestPalSubsB (s):

    MaxLen = 0
    for i in range (len(s)-1):
        for j in range (i,len(s)-1):
            st = ""
            for k in range (i,j):
                st = st + s[k]
                if isSubPalindrome (st,i,j) == True and len(st)>MaxLen:
                    MaxLen = len (st)
                    start = i
                    end = j

    return s[start,end]

s = input("Enter a string: ")

print (longestPalSubsB(s))
Enter a string: aceexcivicgrfdds
Traceback (most recent call last):

  File "<ipython-input-6-64661b5bf324>", line 1, in <module>
    runfile('/Users/Rayan/Desktop/AUB Spring 2019/EECE 230 /HW/Homework 4/Problem2b.py', wdir='/Users/Rayan/Desktop/AUB Spring 2019/EECE 230 /HW/Homework 4')

  File "/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 704, in runfile
    execfile(filename, namespace)

  File "/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 108, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "/Users/Rayan/Desktop/AUB Spring 2019/EECE 230 /HW/Homework 4/Problem2b.py", line 35, in <module>
    print (longestPalSubsB(s))

  File "/Users/Rayan/Desktop/AUB Spring 2019/EECE 230 /HW/Homework 4/Problem2b.py", line 24, in longestPalSubsB
    if isSubPalindrome (st,i,j) == True and len(st)>MaxLen:

  File "/Users/Rayan/Desktop/AUB Spring 2019/EECE 230 /HW/Homework 4/Problem2b.py", line 12, in isSubPalindrome
    if s[i] != s[end+1-i]:

IndexError: string index out of range

Upvotes: 1

Views: 211

Answers (3)

Proto
Proto

Reputation: 71

this is the working code :)

def isSubPalindrome (s,start,end):
    isPal = True
    st = s[start:end]
    mid = int(len(st)/2)
    n = len(st)
    for i in range (mid):
        if st[i] != st[n-1-i]:
            isPal = False

    return isPal

def longestPalSubsB (s):

    MaxLen = 0
    start = 0
    end = 0
    for i in range (len(s)):
        for j in range (i,len(s)):
            st = []
            Len = 0
            for k in range (i,j+1):
                st.append(s[k])
                Len = len (st)
                if Len > MaxLen and isSubPalindrome (s,i,j+1):
                    MaxLen = Len
                    start = i 
                    end = j + 1
    return s[start:end]


s = input("Enter a string: ")

print (longestPalSubsB(s))

Upvotes: 0

Genie
Genie

Reputation: 129

There are multiple issues with your code including logic to check for palindrome.

Synactical Errors:

In longestPalSubsB function, variable 'i' ranges from 0 to len(s)-1. range(n) ranges from 0 to n-1. Hence for i in range(len(s)): syntax should be used. Similar syntax is applicable for j.

Suppose str = "STARWARS", str[0:1] returns 'S' and str[1:4] returns "TAR".

return s[start,end] throws syntax error. It should be s[start:end+1]

Logical Errors:

In isSubPalindrome function, variable i should be used to compare last and first characters, second last and second characters and so on. Below code should do the trick.

def isSubPalindrome (s):
    isPal = True
    n = len(s)
    mid = int(n/2)
    for i in range(mid):
        if s[i] != s[n-1-i]:
            isPal = False
    return isPal

You don't need third loop of k in longestPalSubsB function. Use st = s[i:j+1], isSubPalindrome (st)

You may want to check syntax by using interactive python shell which can spawned by typing python in your terminal or cmd. python -i test.py gives a interactive python shell which has variable values of your code. Happy Python coding!!

Upvotes: 1

adrtam
adrtam

Reputation: 7241

Python range(start, end) give you a sequence of numbers from start to end-1 inclusive. For example, range(10, 14) is 10, 11, 12, 13. Now consider this loop:

for i in range (start,end):
    if s[i] != s[end-i]:
        isPal = False

the if part, if using my example of range(10, 14), is comparing s[10] != s[14-10] up to s[13] != s[14-13]. Obviously not what you intended to do.

Possibly you mean this:

for i in range(end-start):
    if s[start+i] != s[end-i]:
        isPal = False

To solve your problem, there is a (long) one-liner to do it:

print(max([s[i:j+1] for i in range(len(s)) for j in range(i+1, len(s)) if s[i:j+1] == "".join(reversed(s[i:j+1]))], key=lambda x: len(x)))

Upvotes: 1

Related Questions