-1

So I'm taking a python class online. I would like help spotting the differences between my code and the correct answer code. I didn't annotate mine but the answer is annotated and every thing you need should be there to figure out what I'm trying to do. I wrote my answer independently at first and it turns out to be pretty similar to the correct answer code given by the class. However, my code keeps returning the error

Traceback (most recent call last):
  File "submission.py", line 11, in isIn
    middle = aStr[midIndex]
IndexError: string index out of range

Here is my code

def isIn(char, aStr):
    '''
    char: a single character
    aStr: an alphabetized string

    returns: True if char is in aStr; False otherwise
    '''
    # Your code here
    midIndex = len(aStr)//2 
    middle = aStr[midIndex]

    if len(aStr) == 0:
        return False
    if len(aStr) == 1 or char == middle:
        return True
    else:
        if char > middle:
            return isIn(char,aStr[:middle])
        else:
            return isIn(char,aStr[middle +1:])

here is the correct answer given to me by the class:

def isIn(char, aStr):
   '''
   char: a single character
   aStr: an alphabetized string

   returns: True if char is in aStr; False otherwise
   '''
   # Base case: If aStr is empty, we did not find the char.
   if aStr == '':
      return False

   # Base case: if aStr is of length 1, just see if the chars are equal
   if len(aStr) == 1:
      return aStr == char

   # Base case: See if the character in the middle of aStr equals the 
   #   test character 
   midIndex = len(aStr)//2
   midChar = aStr[midIndex]
   if char == midChar:
      # We found the character!
      return True

   # Recursive case: If the test character is smaller than the middle 
   #  character, recursively search on the first half of aStr
   elif char < midChar:
      return isIn(char, aStr[:midIndex])

   # Otherwise the test character is larger than the middle character,
   #  so recursively search on the last half of aStr
   else:
      return isIn(char, aStr[midIndex+1:])

midIndex for my code is middle_nummber and midChar for my code is just middle.

Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997
Jk128711
  • 13
  • 2

1 Answers1

0

Your version has 4 errors; two in handling the edge cases, and the other two in determining what half to search in.

Your code isn't handling the 'empty string' case correctly. For a string of length 0, midIndex will be 0, but aStr[0] won't exist.

This is why the annotated answer starts with

if aStr == '':
    return False

If the input is empty, you can't find the searched-for string. You do test for that case, but you do it too late. This is what causes the traceback you shared:

>>> aStr = ''
>>> midIndex = len(aStr)//2
>>> midIndex
0
>>> aStr[midIndex]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range

Next, you are handling the len(aStr) == 1 edge-case wrong too. Your test is:

if len(aStr) == 1 or char == middle:
    return True

If aStr is set to 'z', then len(aStr) is true, and it doesn't matter what char is set to. So aStr = 'z';char = 'a', will produceTrue` from your function, which is clearly not correct:

>>> aStr = 'z'
>>> char = 'a'
>>> middle = 'z'
>>> len(aStr) == 1 or char == middle
True

The correct answer instead simply tests if aStr == char is true for the length-is-1 case; I'd stick to that, or at least replace or with and:

>>> len(aStr) == 1 and char == middle
False
>>> char = 'z'
>>> len(aStr) == 1 and char == middle
True

Your next error is in what half you search in. You test:

if char > middle:

so the searched for character is greater than the mid-point. You want to search in the second, upper half of your sorted input string. Instead, your version searches in the opposite, lower half:

if char > middle:
    return isIn(char,aStr[:middle])  # slicing up to the middle

Using digits instead of letters to illustrate this better, the input string '12345' has a midpoint '3', so if char is either '4' or '5', you want to find it in the second half.

Your 4th and last error is in that aStr[:middle] expression. middle is a single character, not an integer index. You want to use midIndex:

if char > middle:
    return isIn(char, aStr[:midIndex])
else:
    return isIn(char, aStr[midIndex + 1:])
Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997