0

beginner here-- Given a string, my code must detect whether or not it is a pangram. Return True if it is, False if not.It should ignore numbers and punctuation.

When given "ABCD45EFGH,IJK,LMNOPQR56STUVW3XYZ" it returns none and when given "This isn't a pangram! is not a pangram." it returns True when the answer should be False.

This isn't a pangram! is not a pangram. What am I not seeing?

import string

def is_pangram(s):
    singlechar = set(s)
    list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    for index, item in enumerate(singlechar):
        if item in list:
            list.remove(item)
            if list:
                return True
                break 
    if not list:
        return False
kdendon
  • 1
  • 2
  • For a computer "A" is not the same as "a". Don't use list as a variable name it is a reserved keyword. Your check condition must happen after you have exhausted your list or all single char. – jlandercy Oct 25 '21 at 20:51
  • 2
    Your conditions are backwards. `if list` means you haven't used each letter, `if not list` means you have. – Tim Roberts Oct 25 '21 at 20:51
  • if you `import string` then also use it `lst = list(string.ascii_lowercase)` instead of `list = [...]` (don't use `list` as a variable name) – Matiiss Oct 25 '21 at 20:55

2 Answers2

1

Sets are a great way to check whether something belongs in two collections with their intersection or doesn't belong in one of the two with their difference.

In your case, if the intersection between the set of the letters in your phrase and the letters a-z is of length 26, it is a pangram.

from string import ascii_lowercase

def is_pangram(s):
    return len(set(s.lower()).intersection(ascii_lowercase)) == 26
Reti43
  • 9,656
  • 3
  • 28
  • 44
  • you could also use `return len(...) == len(ascii_lowercase)` (IMO it looks a bit better than some integer) – Matiiss Oct 25 '21 at 21:18
  • 1
    @Matiiss I did consider that, but considering what the definition of the pangram is, it was pointless. Now, if instead of `ascii_lowercase` you use some other collection dynamically, then `len(...) == len(whatever)` would make sense. – Reti43 Oct 25 '21 at 21:19
0

You could have just continued to use sets and their method .difference to find out if there were more characters in the set of all characters or there were no differences (before that you would need to strip the string from punctuation (and whitespace) and make it lowercase (done by .lower and .translate and .maketrans methods of strings)):

import string


def is_pangram(s):
    input_set = set(s.lower().translate(
        str.maketrans('', '', f'{string.punctuation} ')))
    check_set = set(string.ascii_lowercase)
    return not check_set.difference(input_set)


value1 = 'The quick brown fox jumps over a lazy dog!'
print(is_pangram(value1))
# True

value2 = 'This isn\'t a pangram! is not a pangram'
print(is_pangram(value2))
# False

If you want to still do it with a list:

def is_pangram(s):
    input_set = set(s.lower().translate(
        str.maketrans('', '', f'{string.punctuation} ')))
    lst = list(string.ascii_lowercase)
    for item in input_set:
        if item in lst:
            lst.remove(item)
            if not lst:
                return True
    return False
Matiiss
  • 5,970
  • 2
  • 12
  • 29