String Validators

  • + 0 comments

    Python version: 3.8+

    Solution 1:

    if __name__ == "__main__":
        s = input()
        for method in ("alnum", "alpha", "digit", "lower", "upper"):
            print(any(map(lambda char: getattr(char, f"is{method}")(), s)))
    

    This solution takes the input string, s, and checks if it satisfies any of the five str methods using a for loop and the built-in any function. The lambda function is used to dynamically access the is<method> methods of each character in s. This solution demonstrates the Don't Repeat Yourself (DRY) principle by not explicitly calling each of the is<method> methods separately.

    Solution 2:

    from re import search
    from typing import Callable
    
    
    def pattern_match(input_string: str) -> Callable[[str], bool]:
        """Return a pattern matching function."""
        def _pattern_match(pattern: str) -> bool:
            """Call re.search with the given pattern and cast to bool."""
            return bool(search(rf"[{pattern}]", input_string))
        return _pattern_match
    
    
    if __name__ == "__main__":
        print(
            *map(
                pattern_match(input()),
                (r"^\W_", r"a-zA-Z", r"\d", r"a-z", r"A-Z"),
            ),
            sep="\n",
        )
    

    This solution defines a pattern_match function that returns a closure that takes a pattern and returns a boolean indicating if the pattern matches the input string. The function uses re.search to check if a character in the input string matches the pattern. This solution demonstrates the advantage of using closures to encapsulate functionality and avoid code duplication.

    Solution 3:

    from re import search
    from typing import Callable
    
    
    def pattern_match(input_string: str) -> Callable[[str], bool]:
        """Return a pattern matching function."""
        def _pattern_match(pattern: str) -> bool:
            """Call re.search with the given pattern and cast to bool."""
            return bool(search(rf"[{pattern}]", input_string))
        return _pattern_match
    
    
    if __name__ == "__main__":
        digit, lower, upper = map(
            pattern_matcher := pattern_match(input()), (r"\d", r"a-z", r"A-Z")
        )
        print(
            (alpha := lower or upper) or digit or pattern_matcher(r"^\W_"),
            alpha,
            digit,
            lower,
            upper,
            sep="\n",
        )
    

    This solution is similar to Solution 2 but uses the short-circuiting behavior of the or operator to avoid redundant function calls. If one of the lower or upper conditions is True, the digit condition is not evaluated. Similarly, if the alpha condition is True, pattern_matcher is not called a fourth time.

    Code-golfed solution (101 characters):

    s=input()
    for m in"alnum alpha digit lower upper".split():print(any(getattr(c,f"is{m}")()for c in s))