Exercism v3 launches on Sept 1st 2021. Learn more! 🚀🚀🚀
Avatar of nicolemon

nicolemon's solution

to Pangram in the Python Track

Published at Jul 13 2018 · 1 comment
Instructions
Test suite
Solution

Determine if a sentence is a pangram. A pangram (Greek: παν γράμμα, pan gramma, "every letter") is a sentence using every letter of the alphabet at least once. The best known English pangram is:

The quick brown fox jumps over the lazy dog.

The alphabet used consists of ASCII letters a to z, inclusive, and is case insensitive. Input will not contain non-ASCII symbols.

Exception messages

Sometimes it is necessary to raise an exception. When you do this, you should include a meaningful error message to indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. Not every exercise will require you to raise an exception, but for those that do, the tests will only pass if you include a message.

To raise a message with an exception, just write it as an argument to the exception type. For example, instead of raise Exception, you should write:

raise Exception("Meaningful message indicating the source of the error")

Running the tests

To run the tests, run pytest pangram_test.py

Alternatively, you can tell Python to run the pytest module: python -m pytest pangram_test.py

Common pytest options

  • -v : enable verbose output
  • -x : stop running tests on first failure
  • --ff : run failures from previous test before running other test cases

For other options, see python -m pytest -h

Submitting Exercises

Note that, when trying to submit an exercise, make sure the solution is in the $EXERCISM_WORKSPACE/python/pangram directory.

You can find your Exercism workspace by running exercism debug and looking for the line that starts with Workspace.

For more detailed information about running tests, code style and linting, please see Running the Tests.

Source

Wikipedia https://en.wikipedia.org/wiki/Pangram

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

pangram_test.py

import unittest

from pangram import is_pangram

# Tests adapted from `problem-specifications//canonical-data.json`


class PangramTest(unittest.TestCase):
    def test_empty_sentence(self):
        self.assertIs(is_pangram(""), False)

    def test_perfect_lower_case(self):
        self.assertIs(is_pangram("abcdefghijklmnopqrstuvwxyz"), True)

    def test_only_lower_case(self):
        self.assertIs(is_pangram("the quick brown fox jumps over the lazy dog"), True)

    def test_missing_the_letter_x(self):
        self.assertIs(
            is_pangram("a quick movement of the enemy will jeopardize five gunboats"),
            False,
        )

    def test_missing_the_letter_h(self):
        self.assertIs(is_pangram("five boxing wizards jump quickly at it"), False)

    def test_with_underscores(self):
        self.assertIs(is_pangram("the_quick_brown_fox_jumps_over_the_lazy_dog"), True)

    def test_with_numbers(self):
        self.assertIs(
            is_pangram("the 1 quick brown fox jumps over the 2 lazy dogs"), True
        )

    def test_missing_letters_replaced_by_numbers(self):
        self.assertIs(is_pangram("7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog"), False)

    def test_mixed_case_and_punctuation(self):
        self.assertIs(is_pangram('"Five quacking Zephyrs jolt my wax bed."'), True)

    def test_case_insensitive(self):
        self.assertIs(is_pangram("the quick brown fox jumps over with lazy FX"), False)

    # Additional tests for this track

    def test_sentence_without_lower_bound(self):
        self.assertIs(is_pangram("bcdefghijklmnopqrstuvwxyz"), False)

    def test_sentence_without_upper_bound(self):
        self.assertIs(is_pangram("abcdefghijklmnopqrstuvwxy"), False)


if __name__ == "__main__":
    unittest.main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import string

def is_pangram(sentence):
    """Determine if sentence is a pangram."""

    alphabet = [char for char in string.ascii_lowercase]

    for character in sentence.lower():
        if character in alphabet:
            alphabet.pop(alphabet.index(character))

    return len(alphabet) == 0


def main():
    pass


if __name__ == '__main__':
    main()

Community comments

Find this solution interesting? Ask the author a question to learn more.
Avatar of axiomiety

Have you considered using sets? The in operator for lists is linear, as is index (it needs to compare each value until found).

Probably not an issue with that kind of exercise but something to keep in mind.

You may also want to add a conditional on alphabet being non-empty (imagine if the sentence starts with all the letters of the alphabet - you don't need to check any further).

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?