Skip to main content
Commonmark migration
Source Link

Since you are using Python 3.x you could take advantage of the new type hints. According to PEP 484:

This PEP aims to provide a standard syntax for type annotations, opening up Python code to easier static analysis and refactoring, potential runtime type checking, and (perhaps, in some contexts) code generation utilizing type information.

 

Of these goals, static analysis is the most important. This includes support for off-line type checkers such as mypy, as well as providing a standard notation that can be used by IDEs for code completion and refactoring.

Even if you don't use static code analysis at the moment, type hints still have the advantage of making the code easier to read and understand.


The count_spaces function could return directly from the list comprehension expression (type hints added).

The addition of the in_ prefix to the function parameters really doesn't add much value, as function parameters are always a form of input by definition. Since Python does not really use the term "array", calling it a list more be more appropriate.

def count_spaces(char_list: list) -> int:
    return sum(1 for char in char_list if char == ' ')

Since you are using Python 3.x you could take advantage of the new type hints. According to PEP 484:

This PEP aims to provide a standard syntax for type annotations, opening up Python code to easier static analysis and refactoring, potential runtime type checking, and (perhaps, in some contexts) code generation utilizing type information.

 

Of these goals, static analysis is the most important. This includes support for off-line type checkers such as mypy, as well as providing a standard notation that can be used by IDEs for code completion and refactoring.

Even if you don't use static code analysis at the moment, type hints still have the advantage of making the code easier to read and understand.


The count_spaces function could return directly from the list comprehension expression (type hints added).

The addition of the in_ prefix to the function parameters really doesn't add much value, as function parameters are always a form of input by definition. Since Python does not really use the term "array", calling it a list more be more appropriate.

def count_spaces(char_list: list) -> int:
    return sum(1 for char in char_list if char == ' ')

Since you are using Python 3.x you could take advantage of the new type hints. According to PEP 484:

This PEP aims to provide a standard syntax for type annotations, opening up Python code to easier static analysis and refactoring, potential runtime type checking, and (perhaps, in some contexts) code generation utilizing type information.

Of these goals, static analysis is the most important. This includes support for off-line type checkers such as mypy, as well as providing a standard notation that can be used by IDEs for code completion and refactoring.

Even if you don't use static code analysis at the moment, type hints still have the advantage of making the code easier to read and understand.


The count_spaces function could return directly from the list comprehension expression (type hints added).

The addition of the in_ prefix to the function parameters really doesn't add much value, as function parameters are always a form of input by definition. Since Python does not really use the term "array", calling it a list more be more appropriate.

def count_spaces(char_list: list) -> int:
    return sum(1 for char in char_list if char == ' ')
Remove large part of the question that went again the challenge's rules
Source Link
Phrancis
  • 20.4k
  • 6
  • 68
  • 154

I had a hard time with the premise of the problem itself, as I thought that the approach was highly inflexible because it made 2 assumptions that would make actually using this code in reality very impractical.

You may assume that (1) the string has sufficient space at the end to hold the additional characters and (2) that you are given the true length of the string.

This became apparent when I started writing a docstring to explain what the function does...

def urlify(char_list: list, true_length: int) -> list:
    """
    Replace each space '_' character element within a character list with 
    the characters '%20' as individual character elements.
    NOTE: This logic assumes that the true_length of the string, i.e., the total amount of characters
    minus all trailing spaces, will be provided, and that the input string will have exactly
    as many trailing spaces as are needed to replace each ' ' space with 3 characters.
    """

For instance, I would expect with a function like this, that I could do something like this:

hello_string = 'Hello, World!'
urlified_string = urlify(list(hello_string), len(hello_string)) 

Which satisfies the exact length criteria just fine, but since it is missing the extra spaces, I get a IndexError: list assignment index out of range. So I have to do some extra work to make sure to add just the right amount of trailing spaces...

urlified_string = urlify(list(hello_string + '  '), len(hello_string)) 

So the question now becomes:

###Can we make this code more flexible and reusable?

First, since this code is meant to take a string and turn it into a "URLified" string, we should adapt our functions accordingly, to avoid making the caller do the conversions to lists, etc.

def count_spaces_in_string(string: str) -> int:
    return sum(1 for char in list(string) if char == ' ')
    
count_spaces_in_string('Mr John Smith    ') #-> 6

We could also limit ourselves to only counting the spaces that matter, by stripping any trailing and leading spaces with string.strip(). This way, we can approach the challenge differently and not have to rely on assumption (1) to be true:

def count_spaces_in_string(string: str) -> int:
    return sum(1 for char in list(string.strip()) if char == ' ')
    
count_spaces_in_string('Mr John Smith    ') #-> 2

This will of course cause your bigger function to no longer work correctly until we make a few changes to it.


We can also do away with the need for assumption (2) by, again, using string.strip() to get the true_length within the function, thus eliminating the need to pass it as argument:

def urlify_string(string: str) -> str:
    """
    Replace each space '_' character element within a string with 
    the escape characters '%20'.
    """
    true_length = len(string.strip()) #-> 13
    num_spaces = count_spaces_in_string(string) #-> 2
    urlified_length = true_length + (2 * num_spaces) #-> 17

Notice that I shortened the docstring to how the function should really behave.


Once you free yourself of all those assumptions, the logic to actually do what you want to do to any string becomes extremely simple. In fact with this updated logic, we don't even need to account for the length of the string ("true" or otherwise) or the number of spaces at all, making the first function obsolete. Here is a runnable demo on repl.it

Don't ask me about the time and space complexity of this approach; I'm not sure. I would argue this version is far simpler to use and to understand, and in my opinion that has a lot of value, often more than marginal complexity optimizations.

def urlify_string(string: str) -> str:
    """
    Replace each space '_' character element within a string with 
    the escape characters '%20'.
    """
    true_string = string.strip()
    char_list = []
    for char in list(true_string):
        if char == ' ':
            char_list.append('%')
            char_list.append('2')
            char_list.append('0')
        else:
            char_list.append(char)
    return ''.join(char_list)

print(urlify_string('Mr John Smith    ')) #-> Mr%20John%20Smith
print(urlify_string('Mr John Smith'))     #-> Mr%20John%20Smith
print(urlify_string('            Mr John Smith                   ')) #-> Mr%20John%20Smith
print(urlify_string('Hello, World!'))     #-> Hello,%20World!

I had a hard time with the premise of the problem itself, as I thought that the approach was highly inflexible because it made 2 assumptions that would make actually using this code in reality very impractical.

You may assume that (1) the string has sufficient space at the end to hold the additional characters and (2) that you are given the true length of the string.

This became apparent when I started writing a docstring to explain what the function does...

def urlify(char_list: list, true_length: int) -> list:
    """
    Replace each space '_' character element within a character list with 
    the characters '%20' as individual character elements.
    NOTE: This logic assumes that the true_length of the string, i.e., the total amount of characters
    minus all trailing spaces, will be provided, and that the input string will have exactly
    as many trailing spaces as are needed to replace each ' ' space with 3 characters.
    """

For instance, I would expect with a function like this, that I could do something like this:

hello_string = 'Hello, World!'
urlified_string = urlify(list(hello_string), len(hello_string)) 

Which satisfies the exact length criteria just fine, but since it is missing the extra spaces, I get a IndexError: list assignment index out of range. So I have to do some extra work to make sure to add just the right amount of trailing spaces...

urlified_string = urlify(list(hello_string + '  '), len(hello_string)) 

So the question now becomes:

###Can we make this code more flexible and reusable?

First, since this code is meant to take a string and turn it into a "URLified" string, we should adapt our functions accordingly, to avoid making the caller do the conversions to lists, etc.

def count_spaces_in_string(string: str) -> int:
    return sum(1 for char in list(string) if char == ' ')
    
count_spaces_in_string('Mr John Smith    ') #-> 6

We could also limit ourselves to only counting the spaces that matter, by stripping any trailing and leading spaces with string.strip(). This way, we can approach the challenge differently and not have to rely on assumption (1) to be true:

def count_spaces_in_string(string: str) -> int:
    return sum(1 for char in list(string.strip()) if char == ' ')
    
count_spaces_in_string('Mr John Smith    ') #-> 2

This will of course cause your bigger function to no longer work correctly until we make a few changes to it.


We can also do away with the need for assumption (2) by, again, using string.strip() to get the true_length within the function, thus eliminating the need to pass it as argument:

def urlify_string(string: str) -> str:
    """
    Replace each space '_' character element within a string with 
    the escape characters '%20'.
    """
    true_length = len(string.strip()) #-> 13
    num_spaces = count_spaces_in_string(string) #-> 2
    urlified_length = true_length + (2 * num_spaces) #-> 17

Notice that I shortened the docstring to how the function should really behave.


Once you free yourself of all those assumptions, the logic to actually do what you want to do to any string becomes extremely simple. In fact with this updated logic, we don't even need to account for the length of the string ("true" or otherwise) or the number of spaces at all, making the first function obsolete. Here is a runnable demo on repl.it

Don't ask me about the time and space complexity of this approach; I'm not sure. I would argue this version is far simpler to use and to understand, and in my opinion that has a lot of value, often more than marginal complexity optimizations.

def urlify_string(string: str) -> str:
    """
    Replace each space '_' character element within a string with 
    the escape characters '%20'.
    """
    true_string = string.strip()
    char_list = []
    for char in list(true_string):
        if char == ' ':
            char_list.append('%')
            char_list.append('2')
            char_list.append('0')
        else:
            char_list.append(char)
    return ''.join(char_list)

print(urlify_string('Mr John Smith    ')) #-> Mr%20John%20Smith
print(urlify_string('Mr John Smith'))     #-> Mr%20John%20Smith
print(urlify_string('            Mr John Smith                   ')) #-> Mr%20John%20Smith
print(urlify_string('Hello, World!'))     #-> Hello,%20World!
added 51 characters in body
Source Link
Phrancis
  • 20.4k
  • 6
  • 68
  • 154

Since you are using Python 3.x you could take advantage of the new type hintstype hints. According to PEP 484:

def urlify_string(string: str) -> str:
    """
    Replace each space '_' character element within a string with 
    the escape characters '%20' as individual character elements.
    """
    true_length = len(string.strip()) #-> 13
    num_spaces = count_spaces_in_string(string) #-> 2
    urlified_length = true_length + (2 * num_spaces) #-> 17

Since you are using Python 3.x you could take advantage of the new type hints. According to PEP 484:

def urlify_string(string: str) -> str:
    """
    Replace each space '_' character element within a string with 
    the characters '%20' as individual character elements.
    """
    true_length = len(string.strip()) #-> 13
    num_spaces = count_spaces_in_string(string) #-> 2
    urlified_length = true_length + (2 * num_spaces) #-> 17

Since you are using Python 3.x you could take advantage of the new type hints. According to PEP 484:

def urlify_string(string: str) -> str:
    """
    Replace each space '_' character element within a string with 
    the escape characters '%20'.
    """
    true_length = len(string.strip()) #-> 13
    num_spaces = count_spaces_in_string(string) #-> 2
    urlified_length = true_length + (2 * num_spaces) #-> 17
added 3 characters in body
Source Link
Phrancis
  • 20.4k
  • 6
  • 68
  • 154
Loading
deleted 20 characters in body
Source Link
Phrancis
  • 20.4k
  • 6
  • 68
  • 154
Loading
Source Link
Phrancis
  • 20.4k
  • 6
  • 68
  • 154
Loading