0

I was trying to do a codewar quiz, which needs to take in a string of text, and break up the camel case, and separate them into a list of words, I was expecting the result to be

['break', 'Camel', 'Case', 'Ez']

but I can't figure out which part of my code is causing problem

word_list = []
def solution(s):
    global word_list
    if any([char.isupper() for char in s][1:]):
        # print([char.isupper() for char in s][1:])
        for i, char in enumerate(s):
            if i == 0:
                continue
            if char.isupper():
                word_list.append(s[:i])
                solution(s[i:])
    else:
        word_list.append(s)

    return word_list
# print("breakCamelCaseEz")
print(solution("breakCamelCaseEz"))

the result I'm getting is

['break', 'Camel', 'Case', 'Ez', 'CamelCase', 'Ez', 'breakCamel', 'Case', 'Ez', 'breakCamelCase', 'Ez']

Also when I tried to add a counter to the function trying to find the problem, I get more problem

word_list = []
indexing = 0
def solution(s):
    global word_list, indexing
    indexing += 1
    if any([char.isupper() for char in s][1:]):
        print([char.isupper() for char in s][1:])
        # break it down
        for i, char in enumerate(s):
            if i == 0:
                continue
            if char.isupper():
                word_list.append(s[:i])
                print("{}-{}".format("loop", indexing))
                solution(s[i:])
    else:
        print("{}-{}-{}".format("else", indexing, s))
        word_list.append(s)

    return word_list
# print("breakCamelCaseEz")
print(solution("breakCamelCaseEz"))

I've read through the code for multiple times but still can't figure it out

*edited first part

vid Proli
  • 27
  • 4
  • Please, explain what you would like the ideal result to be and how it differs from the result shown in your question – Wippo Dec 05 '20 at 14:44
  • "I was trying to do a codewar quiz"- can you please mention what the question exactly is? – a121 Dec 05 '20 at 14:44
  • 2
    You're recursing every time you see a capital letter (except at the very beginning). So `solution("fooBarBaz")` will call `solution("BarBaz")` and `solution("Baz")` and `solution("BarBaz")` will also call `solution("Baz")`. So `solution("Baz")` is called twice and `Baz` ends up in the list twice. Further, right before `solution("fooBarBaz")` calls `solution("Baz")`, it will add `"fooBar"` to the list, which is wrong because that's two words. As far as I can see, the recursion serves no purpose here except to confuse things. You should try to implement just using a loop. – sepp2k Dec 05 '20 at 15:21
  • Even if you were to get a recursive solution to work, you shouldn't use a global variable, rather you'd ideally return the result of `word_list.extend(solution(s[i:]))` – OneCricketeer Dec 05 '20 at 15:36
  • 1
    By the way https://stackoverflow.com/questions/2277352/split-a-string-at-uppercase-letters#comment71487355_2277363 – OneCricketeer Dec 05 '20 at 15:39
  • @sepp2k Thx so much :D, ur answer helped me see where the problem was – vid Proli Dec 05 '20 at 15:46
  • @OneCricketeer Thx for your advice, I've only heard best not to use globals, but haven't touch on them yet. I'll go check infos about them now. And I didn't know regex could do string editing, the link was really helpful too :D – vid Proli Dec 05 '20 at 15:51
  • You've touched them... `global word_list, indexing` – OneCricketeer Dec 05 '20 at 17:59

2 Answers2

1
def break_camel(string):
    output = []
    currword =[]
    for c in string:
        if c.islower():
            currword.append(c)
        else:
            output.append( ''.join(currword))
            currword = []
    return output
Kevin Smeeks
  • 185
  • 10
1

Could also do the trick

import re

def solution(word):
    return list(filter(None, re.split('([A-Z][a-z]*)', word)))

print(solution("breakCamelCaseEz"))

Output:

['break', 'Camel', 'Case', 'Ez']

I've used filter to remove the empty values from the list and then used list on the filter object to convert it back to a list.

Crapy
  • 352
  • 1
  • 8