Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Tutorial Question: Ends With Function

Tags:

python

I have a python tutorial question which i couldn't get past. The question as follow:

Ends With
Given two strings, return True if either of the strings appears at the very end of the other string, ignoring upper/lower case differences (in other words, the computation should not be "case sensitive").

My solution:

def end_other(a,b):     
    s1=a.lower()    
    s2=b.lower()   
    if len(s1)>len(s2):  
        if s1[-len(s2)]==s2[-len(s2)]:  
            return True  
    if len(s1)<len(s2):  
        if s1[-len(s1)]==s2[-len(s1)]:  
            return True  
    if len(s1)==len(s2):  
        if s1[-len(s1)]==s2[-len(s2)]:  
            return True  
    else:  
         return False  

But the Error Message window shows: All the public tests passed but some private tests failed. You need to generalize your solution.

What is the problem lies in my solution? Or is there somethings i missed?

like image 678
user573756 Avatar asked Nov 28 '22 18:11

user573756


2 Answers

What about using python's builtin str.endswith() method?

def end_other(a, b):
    a_lower = a.lower()
    b_lower = b.lower()
    return a_lower.endswith(b_lower) or b_lower.endswith(a_lower)
like image 146
ThiefMaster Avatar answered Jan 03 '23 20:01

ThiefMaster


I think this is what you were actually trying to do:

def end_other ( a, b ):
    a = a.lower()
    b = b.lower()
    if a == b:
        return True
    elif len( a ) > len( b ):
        return b == a[-len( b ):]
    else:
        return a == b[-len( a ):]

You had a couple of mistakes in your solution:

  • s1[-len(s2)] or generally s1[x] just gets a single character. So if anything, you are just comparing a single character, but not an actual sequence of characters. You splice a sequence out of a string by s[x:y] (see the manual).
  • s2[-len(s2)], even with the colon as explained above, doesn't make much sense. You are accessing s2 using its own length. But as s2 is already the smaller string, you can compare it as a whole.
  • When one of your outer ifs matches a situation, there is no way any other of the outer situations can follow. For example if a is longer than b, there is no way that a will be shorter or of the same length as b later on. As such you should make your if structure support that. Instead of if ... if ... if ... else make a chain: if ... elif ... elif ... else. Then one automatically knows that only one of those cases can apply.
  • When you do that, you can also leave off the last if expression. Because when neither x < y nor y < x equals to true, then x is equal to y.
  • You also need to change the way you return from within the function. As of now you have a conditional exit within each of your outer if cases. Now if the first if case applies (i.e. s1 is longer than s2) and the inner if does not apply (s1 does not end with s2), then you already know that the function should return False. Because there is no way that any other condition later in the code says otherwise, so you should return False immediately there (especially when there is other code that might execute later). And when you have if x: return True else: return False then you can just return x.
  • s1[-len(s1)]==s2[-len(s2)]: As other as already said you will have a problem when s1 and s2 are empty strings. len( "" ) = 0 and if both strings are empty, then both lengths are identical. And then your code tries to use an index range on an empty string, which will always fail (as there is not a single character). Instead, when you already know that two strings are of the same size, just compare both as a whole. This also helps against empty strings.

Anyway, if you didn't need to implement it on your own, you should really use str.endswith instead.

like image 29
poke Avatar answered Jan 03 '23 19:01

poke