Horai Nuri
Horai Nuri

Reputation: 5578

Converting uppercase to lowercase with hyphen

I'm processing some CSS code using Python, since they came from a JSON file (JSON doesn't accept hyphens) they have a particular notation eg.. font-size = fontSize, I'd like to convert every uppercases letter and put them back in the right CSS format inserting a hyphen right before the uppercase.

string = 'borderRadius: 0px, zIndex: 2, transform: translate(170px, 195px) skew(-30deg, 0deg), fontSize:30px'

def getIndices(string):
    // get position of each capital letters.
    index = [i for i, c in enumerate(string) if c.isupper()] 

    // code below would be inserted here.

    // insert hyphen right before the upperscase
    for i in index:
        string = string[:i] + '-' + string[i:]

    // once done, set string to lowercase since there are no uppercases in CSS properties
    string = string.lower()
    return string

getIndices(string)

The issue is that each time a hyphen is insered, the position of capital letters becomes off hence the insertion are off too.

I thought about enumarting the index and increasing each int in list by their index number, but I'm probably doing something not quite right.

...
index = [25, 35, 58]
for i, value in enumerate(index):
    value = value + (i)
    index[i] = value

Any suggestion would be helpful!

Upvotes: 1

Views: 2147

Answers (2)

Dan D.
Dan D.

Reputation: 74655

You could simply do your insertions in reverse. Otherwise the first ones will change the offset of the last ones. This can be done by calling reversed on the index list before looping over it.

def getIndices(string):
    # get position of each capital letters.
    index = [i for i, c in enumerate(string) if c.isupper()] 

    # code below would be inserted here.

    # insert hyphen right before the upperscase
    for i in reversed(index):
        string = string[:i] + '-' + string[i:]

    # once done, set string to lowercase since there are no uppercases in CSS properties
    string = string.lower()
    return string

But it would be better to avoid:

string = string[:i] + '-' + string[i:]

As it makes four new strings every loop iteration.

By building a list and then calling '-'.join. The following works:

def getIndices(string):
    # get position of each capital letters.
    index = [i for i, c in enumerate(string) if c.isupper()] 

    # code below would be inserted here.

    # insert hyphen right before the upperscase
    l = []
    e = len(string)
    for i in reversed(index):
        l.append(string[i:e])
        e = i
    l.append(string[:e])
    l.reverse()
    string = '-'.join(l)

    # once done, set string to lowercase since there are no uppercases in CSS properties
    string = string.lower()
    return string

I'd like to do:

l = []
e = len(string)
for i, c in reversed(enumerate(string)):
   if c.isupper():
      l.append(string[i:e])
      e = i
l.append(string[:e])
l.reverse()
string = '-'.join(l)

[The code above does not work as it results in TypeError: argument to reversed() must be a sequence but the error is misleading the argument must either be a sequence or an object that has __reversed__ defined]

But when they added reversed they didn't think about making it applicable to all built-in iterator functions by defining __reversed__ that returns the reverse they are iterating over an iterable that has a __reversed__. I've implemented an enumerate that works that way and find it Pythonic. Oddly it works on xrange but not on enumerate so the code becomes:

def getIndices(string):

    l = []
    e = len(string)
    for i in reversed(xrange(len(string))):
       if string[i].isupper():
          l.append(string[i:e])
          e = i
    l.append(string[:e])
    l.reverse()
    string = '-'.join(l)

    string = string.lower()
    return string

Upvotes: 1

Peko Chan
Peko Chan

Reputation: 364

If I got it right, this is one way of doing it

 for c in my_string:
      print c
      if c.isupper():
          my_string = my_string.replace(c,"-%s" % c.lower())

 print my_string # will print fontSize = font-size

Upvotes: 1

Related Questions