Home > Back-end >  is there a simpler way to complete the following exercise? I am adding elements to a string, dependi
is there a simpler way to complete the following exercise? I am adding elements to a string, dependi

Time:06-29

From Google Python Class

D. Verbing :

Given a string, if its length is at least 3, add 'ing' to its end. Unless it already ends in 'ing', in which case add 'ly' instead. If the string length is less than 3, leave it unchanged. Return the resulting string.

 def verbing(s):

    if len(s) < 3:
      return s

    if len(s) >= 3 and s[-3:] == 'ing':
       s = s   'ly'
       return s

    elif s[:-3] != 'ing':
      s = s   'ing'
      return s

Test Cases

  print 'verbing'

  test(verbing('hail'), 'hailing')

  test(verbing('runt'), 'runting')

  test(verbing('swiming'), 'swimingly')

  test(verbing('do'), 'do')

  test(verbing('hi'), 'hi')

CodePudding user response:

You can use str.endswith:

test_cases = ["ing", "webbing", "xy", "house"]


def verbing(s):
    return s if len(s) < 3 else (s   "ly" if s.endswith("ing") else s   "ing")


for t in test_cases:
    print(t, verbing(t))

Prints:

ing ingly
webbing webbingly
xy xy
house houseing

CodePudding user response:

Your control flow statements (if/elif/else) all end with return s, so you could restructure things to eliminate the redundant return s statements:

def verbing(s):
    if len(s) >= 3:
        if s[-3:] == 'ing':
            s = s   'ly'
        elif s[:-3] != 'ing':
            s = s   'ing'
    return s

This also eliminates the if len(s) < 3 line, since if len(s) isn't greater than or equal to 3, that must mean it is less than 3, so there isn't much of a point in checking for that explicitly.

Similarly, since the if s[-3:] == 'ing' line asks "does this end in -ing? yes or no?", if the answer is not "yes", it must be "no" (or in this case, False). So the elif statement can be replaced with a simpler and more efficient else (more efficient since it's not checking & evaluating another condition). You can also shorten s = s something statements to s = something, which is a bit shorter and nicer to read:

def verbing(s):
    if len(s) >= 3:
        if s[-3:] == 'ing':
            s  = 'ly'
        else:
            s  = 'ing'
    return s

Finally, there's a shorter way to write simple if/else statements which in other languages is known as the ternary operator, which applied here would look something like this:

def verbing(s):
    if len(s) >= 3:
        # the parentheses are not needed but do 
        # help make it more clear what's going on
        s  = ('ly' if s[-3:] == 'ing' else 'ing') 
    return s

This ('ly' if s[-3:] == 'ing' else 'ing') statement gets evaluated in the same way as the previous if/else statement, just written in a different way. It can be read as "this statement should be equal to 'ly' if the string ends in 'ing'; otherwise, this statement should be equal to 'ing'." The value of that statement is what will get tacked onto the end of the string s.

Ultimately, I think the code you began with is a good place to start, since it does in fact work. And you're right to want to review that code to see if there are places where it could be cleaner, shorter, and/or more efficient. This is roughly how I personally go about these sorts of things and I hope this may help you in the process of improving and refactoring the code you write in future. Good luck and have fun!

CodePudding user response:

Here's what I could come up with on a short notice:

def verbing(string: str) -> str:
    if len(string) >= 3:
        if not string.endswith("ing"):
            string  = "ing"
        else:
            string  = "ly"
    return string

Hope that helps.

CodePudding user response:

There are many different ways to solve this problem. I think that first you need to ask yourself why your solution isn't good enough. Maybe if you will run import this you will understand better how code in python should look like and what are the values that you should follow.

Although this pattern is way to much for this small problem, for education purpose I will intrude another pattern that can be handy if the problem should be address from the scale point of view.

def cond_ing(st):
    return st[-3:] != "ing"

def add_ing(st):
    return st   "ing"

def cond_ly(st):
    return st[-3:] == "ing"

def add_ly(st):
    return st   "ly"


d = {
    cond_ing: add_ing,
    cond_ly: add_ly
}

now you can run a simple for loop and every one can just add which condition that they would like. something like:

for s in tests:
    if len(s) <= 3:
        print(s)
        continue
    for con in d:
        if con(s):
            print(d[con](s))
  • Related