Why is the output True even if the input is an isogram?

I am making a program which checks whether a particular string is an isogram or not.

ISOGRAM: A word which does not have any letter occurring more than once, irrespective of its casing.
Example: Dustbin (every word is occurring once)

(NOTE: The program can also work with random inputs like assdfd)

Click here for the code

For example, if the input is

print(is_isogram(‘moOse’))

the output should be False as the ‘o’ has occurred twice(the output has to do with the casing ). But the output is True.

Therefore, I want to know where am I going wrong. Every suggestion will be appreciated.
THANK YOU

This happens because the loop breaks after the first result.
The first character is “m” and the result for that is True.

Below is a way it can work, but only look at it if you don’t want to try it yourself first:

You can save the result in a variable and only break if it changes to false (which is the important part).

def is_isogram(string):
  strings = string.lower()
  ls = list(strings)
  result = True;
  for x in ls:
    if ls.count(x) == 1:
      result = True
    elif ls == '' or ls == ' ':
      result = True
    else:
      result = False
      break
  return result

print(is_isogram('moOse'))
# Returns False

print(is_isogram('mouse'))
# Returns True
1 Like

I have modified my piece of code by bringing a variable result and by using list comprehension for converting the string into a list.

def is_isogram(string):
    string = string.lower()
    result = True
    print(string)
    ls = [x for x in string if x.isalpha() != False ]
    print(ls)
    for x in ls:
        if ls.count(x) > 1:
            result = False
            break
        else:
            result = True
        if ls == [' ']:
            result =  True
    return result

Now, my question is that what is the reason of bringing a variable result. What was wrong in returning either of the boolean operators directly?

When you loop through the word, like “moOse”, it does it in order, first the “m”, then the first “o”, etc.

When you return or break inside of a loop (the for loop here), it exits the loop.
This means that after it returns the bool for the first character (“m”), the loop stops and the result is printed. The loop doesn’t continue for the rest of the characters in the word.

When you initialize the result variable it is True, meaning any word starts out as an isogram, and only when a letter is repeated (meaning it is not an isogram anymore), do you stop the loop and return the value.
If there are no letters repeated, the value true will be returned at the end because it wasn’t changed.

This also means you can shorten the if statements by just writing it like this:

def is_isogram(string):
  strings = string.lower()
  ls = list(strings)
  result = True

  for x in ls:
    if ls.count(x) > 1:
      result = False
      break
  return result

Because, like I said, you then assume the word is an isogram, until it is proven not to be one.

2 Likes

Is it necessary to create a list object? The str class has an attribute, count.

I’m still new to Python and I just edited the code this person has written, thanks for bringing that up.

By using that, the code can be written like this (I also got rid of the strings variable and removed the boolean variable because there are only 2 outcomes):

def is_isogram(string):
  string = string.lower()

  for x in string:
    if string.count(x) > 1:
      return False
  return True

If you are really new to Python, then the .count() method will not have been learned; however, you have bridged that gap. When we play it forward sometimes we get ahead of the program. It would be nice to see this played out as an algorithm rather than implementing the built-in ‘count’ method.