Skip to content

Convert snake_case to camelCase or PascalCase (#7028) #7034

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions strings/snake_case_to_camel_pascal_case.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
def snake_to_camel_case(input: str, use_pascal: bool = False) -> str:
"""
Transforms a snake_case given string to camelCase (or PascalCase if indicated)
(defaults to not use Pascal)

>>> snake_to_camel_case("some_random_string")
'someRandomString'

>>> snake_to_camel_case("some_random_string", use_pascal=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a few more tests...

Suggested change
>>> snake_to_camel_case("some_random_string", use_pascal=True)
>>> snake_to_camel_case("SOME___RaNdOm_32_string", use_pascal=True)
>>> snake_to_camel_case("_some_random_string_", use_pascal=True)
>>> s = "some_random_string"
>>> snake_to_camel_case(snake_to_camel_case(s, use_pascal=True), use_pascal=False) == s
True

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't get the last test, it is to convert from snake to camel/pascal, that test is converting the snake to pascal and later try to convert from pascal to camel and compare to the original snake one.

Copy link
Member

@cclauss cclauss Oct 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We want to make sure that decode(encode(s)) == s proves that we can "roundtrip" if we have good input.

Like:
% python3

>>> "Lüsai".encode()  # Convert a str into bytes
b'L\xc3\xbcsai'
>>> "Lüsai".encode().decode() == "Lüsai"  # Roundtrip: str --> bytes --> str
True

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the function is not to encode/decode, is to transform from snake to other.

Your given example would be more like

>>> "Lüsai".encode()  # Convert a str into bytes
b'L\xc3\xbcsai'
>>> "Lüsai".encode().encode() == "Lüsai"  # str --> bytes --> bytes
True

I think the issue is the parameter use_pascal, which signals to instead of converting snake to camel, converts it to pascal instead, thought that could make it more useful and show an example of the equivalent to other languages ternary operator. I could remove it or create snake_to_camel_case(input) and snake_to_pascal_case(input).

If you consider it necessary I can add Camel/Pascal to snake

'SomeRandomString'

>>> snake_to_camel_case("some_random_string_with_numbers_123")
'someRandomStringWithNumbers123'

>>> snake_to_camel_case("some_random_string_with_numbers_123", use_pascal=True)
'SomeRandomStringWithNumbers123'

>>> snake_to_camel_case(123)
Traceback (most recent call last):
...
ValueError: Expected string as input, found <class 'int'>

>>> snake_to_camel_case("some_string", use_pascal="True")
Traceback (most recent call last):
...
ValueError: Expected boolean as use_pascal parameter, found <class 'str'>
"""

if not isinstance(input, str):
raise ValueError(f"Expected string as input, found {type(input)}")
if not isinstance(use_pascal, bool):
raise ValueError(
f"Expected boolean as use_pascal parameter, found {type(use_pascal)}"
)

words = input.split("_")

start_index = 0 if use_pascal else 1

words_to_capitalize = words[start_index:]

capitalized_words = [word[0].upper() + word[1:] for word in words_to_capitalize]

initial_word = "" if use_pascal else words[0]

return "".join([initial_word] + capitalized_words)


if __name__ == "__main__":
from doctest import testmod

testmod()