How to acheive this in Python?

Converting the string "HelloPythonWorld" to "HELLO_PYTHON_WORLD"

How far have you tried/brainstormed?
Hint: Check os.path.join() and lower() function

Hi
I am new to Python. I did this perl as given below. But now URGENTLY need this in Python. So I posted it.

$str = HelloWorld;
$str =~ s/[A-Z]/_$&/g;
$str =~ s/^_//;
$str = uc($str);
print "$str";

Thanks.

Python code is actually very similar to your Perl code, just a bit more readable:

# Convert string "HelloPythonWorld" to "HELLO_PYTHON_WORLD"

s1 = "HelloPythonWorld"
s2 = ""
for index, c in enumerate(s1):
    if c.isupper() and index > 0:
        s2 += '_' + c
    else:
        s2 += c

s2 = s2.upper()
print s2  # HELLO_PYTHON_WORLD
$str = HelloWorld;
$str =~ s/[A-Z]/_$&/g;
$str =~ s/^_//;
$str = uc($str);
print "$str";

This one's a little closer to your perl method:

import re
text = re.sub(r'([A-Z]+)',lambda x:'_'+x.group(0).lower(),'HelloPythonWorld')
text = re.sub(r'^_', r'', text)
print text.upper()

You don't really need to be using regular expressions on something this simple though...

Yeah but it sounds like it's some type of built-in function to a larger utility that he used to run in perl. There's certainly better ways to build it, but he said it was URGENT so it must be life-or-death.

As they say, crises precipitate change....

Very true. And seeing as he basically did that in Perl I'm sure he won't find the Python syntax too confusing.

Very true. And seeing as he basically did that in Perl I'm sure he won't find the Python syntax too confusing.

I am using Python 2.2 and above two methods are not working in that. Is there any dependency on Python version?

For the first solution, I got the following error:
"NameError: name 'enumerate' is not defined"
Added a class for enumerate as follows by searching in net. But now my doubt is, this is printing the 's2' by two times. Don't know why? Please someone clarify.

class enumerate:
      def __init__(self, seq):
           self.seq = seq
      def __getitem__(self, inx):
           return inx, self.seq[inx]

s1 = "HelloPythonWorld"
s2 = ""
for index, c in enumerate(s1):
    if c.isupper() and index > 0:
        s2 += '_' + c
    else:
        s2 += c

s2 = s2.upper()
print s2

That makes no sense. Python 2.3 though is when the built-in enumerate function was introduced... your custom one should work fine though. It's outputting "HELLO_PYTHON_WORLD" two times?...

How about an (ugly) alternative method?

s1 = "HelloPythonWorld"
s2 = ""
index = 0
while index < len(s1):
    if c.isupper() and index > 0:
        s2 += '_' + c
    else:
        s2 += c
    index += 1

s2 = s2.upper()
print s2

This doesn't use that custom enumerate class you made. What output does this give you?

Yes, Its outputting "HELLO_PYTHON_WORLD" two times.
Similarly for the second solution, I got the following error:

File "./string.py", line 5, in ?
text = re.sub(r'([A-Z]+)',lambda x:'_'+x.group(0).lower(),'HelloPythonWorld')
AttributeError: 'module' object has no attribute 'sub'

Is this also due to version conflict? Which one is the latest version?

That error makes no sense. Is the section of code you posted oh here the entirety of it? Or is this a segment of something larger which might be causing the issue? As far as I know, re has sub available even in Python 2.2

Technically, the newest version of Python is 3.0, but I wouldn't go for that yet. It has large overhauls and is not backwards compatible. Plus third-party stuff isn't really updated to it yet. Most people (myself included) stick with 2.6 (or 2.5 too) as it's the best to date cause Python 3.0 is still too new. I'd really strongly recommend upgrading to 2.6 unless you're forced to stick with 2.2.

That makes no sense. Python 2.3 though is when the built-in enumerate function was introduced... your custom one should work fine though. It's outputting "HELLO_PYTHON_WORLD" two times?...

How about an (ugly) alternative method?

s1 = "HelloPythonWorld"
s2 = ""
index = 0
while index < len(s1):
    if c.isupper() and index > 0:
        s2 += '_' + c
    else:
        s2 += c
    index += 1

s2 = s2.upper()
print s2

This doesn't use that custom enumerate class you made. What output does this give you?

Yes, This one working fine. In this you missed one line

s1 = "HelloPythonWorld"
s2 = ""
index = 0
while index < len(s1):
    c = s1[index]
    if c.isupper() and index > 0:
        s2 += '_' + c
    else:
        s2 += c
    index += 1

s2 = s2.upper()
print s2

Thanks for your reply.

For the second solution (import re), i pasted only the segmentation of error return and here pasted the full error

Traceback (most recent call last):
File "./string.py", line 3, in ?
import re
File "/usr/lib/python2.2/re.py", line 27, in ?
from sre import *
File "/usr/lib/python2.2/sre.py", line 98, in ?
import sre_parse
File "/usr/lib/python2.2/sre_parse.py", line 16, in ?
import string, sys
File "./string.py", line 5, in ?
text = re.sub(r'([A-Z]+)',lambda x:'_'+x.group(0).lower(),'HelloPythonWorld')

Ah thanks for catching that one line where I forgot to assign the list's value to "c". That's what I get for not testing code! :P

And I think that re.sub may be broken in Python 2.2... well, using a pattern like you did (the preceeding "r" in front of the string). If you give this mail a quick read, you'll see that Guido said it was broken with raw strings.

This question has already been answered. Start a new discussion instead.