muros
muros

Reputation: 337

Return True if alphanumeric (No methods or import allowed)

What would be a good way to make a function return True if, and only if, what is inputted is alphanumeric (contains only letters or numbers), without using methods or import?

So far in class, we only covered bools, while loops, and if-statements, and are only allowed to use what we have learned.

This is what I got

def alphanumeric(s):
    i = 0
    while i < len(s):
        if s[i] == 1 or s[i] == 2 or s[i] == 3.....:
            i = i + 1
            return True
        else:
            return False

Is there a more concise way to do this without using methods or import? What I have doesn't work, and returns False no matter what I input.

Resolved. Thank you to all that helped!

Upvotes: 1

Views: 1372

Answers (7)

Martijn Pieters
Martijn Pieters

Reputation: 1123022

You have misunderstood how == and or work. You need to test each and every character separately:

if s[i] == 1 or s[i] == 2 or s[i] == 3 ...:

or use an in test:

if s[i] in (1, 2, 3, 4, ...):

except that you are testing characters here, not integers, so either turn your character into an integer, or test against digits:

if int(s[i]) in (1, 2, 3, 4, ...):

or

if s[i] in '1234567890':

The latter works because strings are sequences too; testing if one character is in the string '1234567890' is a valid membership test too.

Since strings are sequences, you can also just loop over them directly:

for char in s:
    if char in '1234567890':

No need to use a while loop and counter there.

This still only tests for digits; to test for letters as well, you could do one of two things:

  • Use the string module, it has ascii_letters and digits attributes:

    import string
    
    for char in s:
        if char in string.ascii_letters + string.digits:
    
  • or test if the character is between two known characters:

    if 'a' <= char <= 'z' or 'A' <= char <= 'Z' or '0' <= char <= '9':
    

    and this works because strings are comparable and sortable; they are smaller or larger according to their position in the ASCII code table.

Your next problem is that you are returning True too early; you do this for the first match, but you need to test all characters. Only return True if you didn't find any misses:

for char in s:
    if char not in string.ascii_letters + string.digits:
        return False

return True

Now we test all characters, return False for the first character that is not alphanumeric, but only when the loop has completed, do we return True.

Upvotes: 3

James
James

Reputation: 2795

def isAlphaNumeric(myString):
    return not any((c for c in myString if not c in "abcdef...ABC...123"))

Upvotes: 0

Dan Copeland
Dan Copeland

Reputation: 571

A few suggestions:

First, you're attempting to return True when you see an alphanumeric character - you need to check all of the characters before returning True (though you can return False when you see a single non-alphanumeric character).

Second, if s is a string, s[i] is a character (i.e. '1', not 1).

Third, when you wrote

if s[i] == 1 or 2 or 3

you're evaluating (s[i] == 1), then 2 by itself as a boolean (which is always false), etc. To compare s[i] to each, you need

if s[i] == '1' or s[i] == '2' or s[i] == '3'

or, more concisely,

if s[i] in ['1', '2', '3', ...]

Upvotes: 0

jamylak
jamylak

Reputation: 133604

Assuming "no methods allowed" means no regex or anything like that, you may use this.

I'll leave it to you to write out string.digits and ascii_letters manually if you have to ;) (That was a joke, you can actually use @mipadi 's method if you aren't allowed to import string)

from string import digits, ascii_letters as alphabet
valid = digits + alphabet
def alphanumeric(s):
    return all(c in valid for c in s)


>>> alphanumeric('1a')
True
>>> alphanumeric('_')
False

Equivalent to:

def alphanumeric(s):
    for c in s:
        if c not in valid:
            return False
    else:
        return True

Upvotes: 1

elnabo
elnabo

Reputation: 264

First of all, I suppose that s is a String.

So you must do s[i] == '1' since s[i] is a substring and not an integer.

That is the reason your function always return False. Then you return true or false only after looking at the first char, you must test every char until one isn't alphanumeric or until the end.

def alphanumeric(s):
    i = 0
    flag = True
    char = 'a...zA...Z0..9'
    charLen = len(char)
    while (i < len(s) and flag) :
        subflag = False
        charIndex = 0
        while charIndex < charLen:
            subflag = subflag or (s[i] == char[charIndex])
            charIndex += 1 # Equivalent of charIndex = charIndex + 1
        flag = flag and subflag
        i = i +1
    return flag

Upvotes: 0

Bennett Brown
Bennett Brown

Reputation: 5383

You could use the in operator and iterate across the input string s:

for c in s:
    if c not in 'abcdefABC123':

Start with a flag being True and set it to False if any character violates the alphanumeric requirement.

Upvotes: 0

mipadi
mipadi

Reputation: 410812

You can use the Python comparison operators to test against characters, so you could do something like this:

def is_alphanumeric(s):
  for ch in s:
    if not ('a' <= ch <= 'z' or 'A' <= ch <= 'Z' or '0' <= ch <= '9'):
      return False
  return True

That will loop through each character in the string and see if it is between 'a' and 'z' or 'A' and 'Z' or '0' and '9'.

Upvotes: 2

Related Questions