1

Q: A pangram is a sentence that contains all the letters of the English alphabet at least once, for example: The quick brown fox jumps over the lazy dog. Your task here is to write a function to check a sentence to see if it is a pangram or not.

What I have is:

def isPangram(s):
    alphabetList = 'abcdefghijklmnopqrstuvwxyz'
    alphabetCount = 0
    if len(s) < 26:
        return False
    else:
        s = re.sub('[^a-zA-Z]','',s).lower()
                for i in range(len(alphabetList)):
            if alphabetList[i] in s:
                alphabetCount = alphabetCount + 1
        if alphabetCount == 26:
            return True
        else:
            return False

However, when I try the example s=["The quick brown fox jumps over the lazy dog"], the result is False, which is wrong. It should be True b/c it has contained all 26 letters. Can anyone help me fix the code? Many thanks!!!

Ubik
  • 139
  • 1
  • 6
M Z
  • 11
  • 1
  • 2

5 Answers5

3

The problem is you're passing in a list of strings instead of a list. Simply pass in "The quick brown fox jumps over the lazy dog" without the brackets and your code will work.

Your code is also unnecessarily complex (and mis-indented to boot):

if alphabetCount == 26:
    return True
else:
    return False

is way too complicated - alphabetCount == 26 is already True or False! So you can simply write

return alphabetCount == 26

Additionally, you iterate over the input string with an index variable. This is completely unnecessary, just iterate over the input string, like this:

for c in alphabetList:
    if c in s:
        alphabetCount += + 1

On top - and that has caused the error now, since the code would have failed otherwise - the check for len(s) < 26 is completely superfluous, just remove it.

The alphabet is also already built-in to Python, it's called string.ascii_lowercase. So you don't need to write it yourself!

That being said, your algorithm is still really slow - you iterate over s 26 times! Why not simply write

import string
def isPangram(s):
    return set(s.lower()) >= set(string.ascii_lowercase)

phihag
  • 278,196
  • 72
  • 453
  • 469
  • Why are you using lambda to define a function just to assign it to a name? The whole and only point of lambda is that the function is anonymous and can be used in an expression; you're throwing away both benefits and getting all the disadvantages (e.g., the name in tracebacks will be `` instead of `isPangram`). PEP 8 explains in more depth why you shouldn't do this. – abarnert Sep 10 '14 at 17:06
  • But other than that, great explanation of what's wrong with the OP's code and all the ways it can be improved. – abarnert Sep 10 '14 at 17:06
  • @abarnert You're right, lambda was only there for golfing purposes. Fixed. – phihag Sep 10 '14 at 19:46
2

It's simpler to reduce the letters in the sentence to a set, then verify that the set is the set of all letters.

def isPangram(s):
    alphabet = set('abcdefghijklmnopqrstuvwxyz')
    s = re.sub('[^a-zA-Z]', '', s)
    sentence = set(s.lower())
    return sentence == alphabet

assert isPangram("The quick brown fox jumped over the lazy dog")
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 1
    No need to use a regular expression here - just convert the string to lower case then do a set intersection and see if the string intersection with alphabet is equivalent to alphabet. `( set(s.lower()) & alphabet_set) == alphabet_set` – Gavin H Sep 10 '14 at 16:00
  • 1
    True; I was originally using the user's code as much as possible, and didn't remove that. Equivalently, you can check that `alphabet - sentence` is empty. – chepner Sep 10 '14 at 16:01
1

I'd use sets:

def isPangram(s):
    alphabetset = set('abcdefghijklmnopqrstuvwxyz')
    set_string = set(s.lower())
    return set_string.issuperset(alphabetset)

Usage:

>>> isPangram('aabc')
False
>>> isPangram('aabcdefghijklmnopqrstuvwxyz')
True
>>> isPangram('aabcdefghijklmnopqrstuvwxyz J:L FSDJ f09823740235')
True
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
0

If s is array() s=["The quick brown fox jumps over the lazy dog"] you can only get a len()=1, then the if len(s) < 26: always return False

def isPangram(s):

    alphabetList = 'abcdefghijklmnopqrstuvwxyz'
    alphabetCount = 0
    if len(s) < 26:
        print "False 1"
    else:
        s = re.sub('[^a-zA-Z]','',s).lower() 
        for i in range(len(alphabetList)):
            if alphabetList[i] in s:
                alphabetCount = alphabetCount + 1
        if alphabetCount == 26:
            print "True"
        else:
            print "False"
a=isPangram("The quick brown fox jumps over the lazy dog")
  • What do you mean "If s is array()"? You're expecting it to be an `array.array('c')` or something? Even if it were, how would that be different from it being a list (as it appears to be) or anything else? – abarnert Sep 10 '14 at 22:41
  • Always I asumme this "s" is array or you can try to compare with type (s) – Fabio Duran Verdugo Sep 10 '15 at 19:08
0

Please remove else statement after the line:

if alphabetCount == 26:
    return True

as it is putting the code into else condition for the i=0 itself because it is taking only one alphabet count.

import re
def isPangram(s):
    alphabetList = 'abcdefghijklmnopqrstuvwxyz'
    alphabetCount = 0
    if len(s) < 26:
        print('lenth is short')
        return False
    else:
        s = re.sub('[^a-zA-Z]','',s).lower()
        print(s)
        for i in range(len(alphabetList)):
            if alphabetList[i] in s:
                print(alphabetList[i])
                print("The string is pangram2")
                alphabetCount = alphabetCount + 1
                print(alphabetCount)
                if alphabetCount >= 26:
                    print("The string is pangram")
                    return True

now the code is running properly

Tommaso Bertoni
  • 2,333
  • 1
  • 22
  • 22
Vinit Jain
  • 21
  • 1