How can I make if code check all cases?

Refresh

April 2019

Views

53 time

1
#Checking if a word is an isogram
from collections import Counter
def count_isogram(words, index):
    a=Counter(words[int(index)])
    d=words[int(index)]
    for (b,c) in a.items():
        if c >= 2:
            print(b,c)
            return(d+' is not an isogram')
        else:
            print(b,c)
            return(d+' is an isogram')

Hi, that is my code above. I'm trying to make a very basic isogram checker (an isogram is a word that doesn't have any repeated letters (dog, cat, bird, etc.). I've gotten the code mostly working but when I get to my if statement, it checks the first letter of each word to determine which return phrase to use. How do I make my code check each letter? For example the below image link demonstrates the problem (I don't have a high enough rep to post images yet):

Example:

enter image description here

You can see that the word in the first scenario: 'silly' (index of 1) is being run throuh the function but because there is only 1 S, it returns that the word is an isogram, when it is not. When running the word 'dude' (index of 1), because the first letter occurs in the word more than once it runs the correct return, however it is only because the first letter checked is the one that is repeated.

I've tried running c.all(), c.any(), and a few other operators but it does not work because c is an integer of only 1 value.

What can I change/add to make the code check all possible letters prior to running the return?

2 answers

1

Solution

The solution to your problem is to return the final result of your program, after you finish looping through each letter.

For each letter, check if it's count is above or equal to 2. If it is, return immediately with the appropriate message (return word + ' is not an isogram'). However, if you reach the end of the loop you know that the word is indeed an isogram, so you can return the other message (word + ' is an isogram')

from collections import Counter

def is_isogram(words, index):
    el = words[index]
    letter_occurences = Counter(el)
    for word, count in letter_occurences.items():
        print(word, count)
        if count >= 2:
            return word + ' is not an isogram'
    return word + ' is an isogram'

Algorithm Improvements

Since we know that an isogram is

any word that has no repeating letters

we can use a set to remove any possible duplicate letters from the string. We can then compare the length of the set to the original length of the string. If the lengths are equal, then no letters were removed and the word is an isogram. If they are not equal, we know that the word is not an isogram:

def is_isogram(words, index):
    word = words[index]
    if len(set(word)) == len(word):
        return word + ' is an isogram'
    return word + ' is not an isogram'

This is much faster than the original method (about nine times faster to be exact):

------------------------------------
| Original method | 6.47415304184  |
------------------------------------
| Above method    | 0.669512987137 |
------------------------------------
0

Both your if and else return, meaning you'll always return on the first iteration of the loop. Instead, the loop should only return if it finds the words isn't an isogram. Only if the loop terminates without getting to such a conclusion should you return that the word is an isogram:

for (b,c) in a.items():
    if c >= 2:
        return(d+' is not an isogram')

return(d+' is an isogram')