How would I get a function to return True or False if the argument that is inputted is a symbol? (ex. %$#@)

Question:

As a beginner practice I have to create a function that returns True if ALL the letters in the string are uppercase. I am able to do that but it is returning False if only a string of symbols is inputted (ex. #$%) when it should be returning True.

Here is the code, it will return True if all letters are capital & include symbols but will not return True if only containing symbols.

def is_uppercase(inp):
    if inp.isupper() and inp != int:
        return True
    else:
        return False

The exact input that is failing is $%&.

Asked By: rootman0

||

Answers:

you would probably need to use the string.punctuation from the string library

import string

def isSymbol(word:str) -> bool:
    return all(c in string.punctuation or c.isupper() for c in word)

print(isSymbol('!@#$%^&*()_+'))
Answered By: some dude

Your problem is, .isupper() will return False for anything that is not an uppercase character, including symbols and digits. You will need to use the inverse (not) of .islower() instead. You should also iterate over the string and check each character individually:

def is_uppercase(inp):
    return not any(i.islower() for i in inp)

The (i.islower() for i in inp) part is a generator expression that iterates over the string and returns the .islower() value of the next character every time it’s called.

any() will compute every value of the generator expression until it finds True.

not will inverse the output.

Basically it will return False if it finds a non-uppercase character, and True if it can’t.

Answered By: Selcuk

Use isalpha() (doc)

def is_uppercase(inp):
    return inp.isupper() and inp.isalpha()

By the way, if you want to make a check to ensure inp is not a int, the inp != int will not work as you expected.

>>> 1 != int
True

The correct way to check it is:

>>> not isinstance(1, int)
False

The solution with type guard:

def is_uppercase(inp):
    if isinstance(inp, int):
        return False
    return inp.isupper() and inp.isalpha()
Answered By: James Chien

You could check whether uppering it changes it:

def is_uppercase(inp):
    return inp == inp.upper()

Or you could add an uppercase letter to satisfy isupper‘s "and there is at least one cased character" criterion:

def is_uppercase(inp):
    return (inp + 'A').isupper()

Benchmark results (due to Selcuk’s comment):

'$%&'
0.00206354699912481 Kelly1
0.0024452939978800714 Kelly2
0.007135316991480067 Selcuk

0.002112452988512814 Kelly1
0.002419316995656118 Kelly2
0.006345021014567465 Selcuk

0.0020082010014448315 Kelly1
0.002397250005742535 Kelly2
0.006479812000179663 Selcuk


'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
0.005014711001422256 Kelly1
0.005423808004707098 Kelly2
0.005639064009301364 Selcuk

0.00503394499537535 Kelly1
0.005443221016321331 Kelly2
0.005748191004386172 Selcuk

0.005227680987445638 Kelly1
0.0053241550049278885 Kelly2
0.00574598801904358 Selcuk

So even if mine have to process 300 characters while Selcuk’s only checks the first character, mine are still a bit faster.

Code (Try it online!):

from timeit import repeat

def Kelly1(inp):
    return inp == inp.upper()

def Kelly2(inp):
    return (inp + 'A').isupper()

def Selcuk(inp):
    return not any(i.islower() for i in inp)

for inp in '$%&', 'a'*300:
  print(repr(inp))
  for _ in range(3):
    for f in Kelly1, Kelly2, Selcuk:
      t = min(repeat(lambda: f(inp), number=10**4))
      print(t, f.__name__)
    print()
  print()
Answered By: Kelly Bundy

The answer from @Selcuk is concise and Pythonic. For comparison, here is the same thing done using a basic loop:

def is_uppercase(inp):
    for c in inp:
        if c.isalpha():
            return inp.isupper()
    return True
Answered By: user19077881
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.