String Validators

  • + 2 comments

    That is a significant improvement for most cases. But you can do better by having a list of checks to perform and removing checks from the list as soon they ever pass. That way you are only ever worrying about checks that still need to be done and not endlessly testing whether some checks have or have not passed yet.

    And you're still checking isdigit() for a character even if isalpha() returned true for that character, and so on.

    names = ['isalnum', 'isalpha', 'isdigit', 'islower', 'isupper']
    # The only tests we actually need to apply
    tests = {
        'isdigit' : str.isdigit,
        'islower' : str.islower,
        'isupper' : str.isupper
    }
    results = { k:False for k in names }
    
    s = input()
    for c in s:     #Iterate just once over the string
        for name, test in list(tests.items()):
            if test(c):
                results[name] = True
                del tests[name]     #No need to apply a successful test ever again
                continue    #Jump to next character - tests are mutually exclusive
        if not tests:   #All the tests succeeded, no need to continue
            break
    # Two tests can be determined from the result of other tests
    results['isalpha'] = results['islower'] or results['isupper']
    results['isalnum'] = results['isdigit'] or results['isalpha']
    # Now print the results in the order asked for
    for name in names:
            print(results[name])