diff --git a/exercises/practice/pangram/.approaches/config.json b/exercises/practice/pangram/.approaches/config.json index 550a3b5e11..19a3b9f973 100644 --- a/exercises/practice/pangram/.approaches/config.json +++ b/exercises/practice/pangram/.approaches/config.json @@ -1,6 +1,7 @@ { "introduction": { - "authors": ["bobahop"] + "authors": ["bobahop"], + "contributors": ["princemuel"] }, "approaches": [ { @@ -22,7 +23,8 @@ "slug": "set-len", "title": "set with len", "blurb": "Use set with len.", - "authors": ["bobahop"] + "authors": ["bobahop"], + "contributors": ["princemuel"] }, { "uuid": "0a6d1bbf-6d60-4489-b8d9-b8375894628b", diff --git a/exercises/practice/pangram/.approaches/introduction.md b/exercises/practice/pangram/.approaches/introduction.md index cf5538c015..247348feae 100644 --- a/exercises/practice/pangram/.approaches/introduction.md +++ b/exercises/practice/pangram/.approaches/introduction.md @@ -42,9 +42,7 @@ For more information, check the [`set` with `issubset()` approach][approach-set- ```python def is_pangram(sentence): - return len([ltr for ltr in set(sentence.lower()) if ltr.isalpha()]) \ - == 26 - + return len(set(ltr for ltr in sentence.lower() if ltr.isalpha())) == 26 ``` For more information, check the [`set` with `len()` approach][approach-set-len]. diff --git a/exercises/practice/pangram/.approaches/set-len/content.md b/exercises/practice/pangram/.approaches/set-len/content.md index b647a01d49..6c0347d5c0 100644 --- a/exercises/practice/pangram/.approaches/set-len/content.md +++ b/exercises/practice/pangram/.approaches/set-len/content.md @@ -2,20 +2,18 @@ ```python def is_pangram(sentence): - return len([ltr for ltr in set(sentence.lower()) if ltr.isalpha()]) \ - == 26 - + return len(set(ltr for ltr in sentence.lower() if ltr.isalpha())) == 26 ``` - This approach first makes a [set][set] from the [`lower`][lower]cased characters of the `sentence`. -- The characters in the `set`are then iterated in a [list comprehension][list-comprehension]. -- The characters are filtered by an `if` [`isalpha()`][isalpha] statement, so that only alphabetic characters make it into the list. -- The function returns whether the [`len()`][len] of the [`list`][list] is `26`. -If the number of unique letters in the `set` is equal to the `26` letters in the alphabet, then the function will return `True`. +- The characters are filtered using a [set comprehension][set-comprehension] with an `if` [`isalpha()`][isalpha] statement, so that only alphabetic characters make it into the set. +- The function returns whether the [`len()`][len] of the [`set`][set] is `26`. + If the number of unique [ASCII][ascii] (American Standard Code for Information Interchange) letters in the `set` is equal to the `26` letters in the [ASCII][ascii] alphabet, then the function will return `True`. +- This approach is efficient because it uses a set to eliminate duplicates and directly checks the length, which is a constant time operation. [lower]: https://docs.python.org/3/library/stdtypes.html?#str.lower [set]: https://docs.python.org/3/library/stdtypes.html?#set -[list-comprehension]: https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions +[set-comprehension]: https://realpython.com/python-set-comprehension/#introducing-set-comprehensions [isalpha]: https://docs.python.org/3/library/stdtypes.html?highlight=isalpha#str.isalpha [len]: https://docs.python.org/3/library/functions.html?#len -[list]: https://docs.python.org/3/library/stdtypes.html?#list +[ascii]: https://en.wikipedia.org/wiki/ASCII diff --git a/exercises/practice/pangram/.approaches/set-len/snippet.txt b/exercises/practice/pangram/.approaches/set-len/snippet.txt index 9a6a6d537b..16c2ce6806 100644 --- a/exercises/practice/pangram/.approaches/set-len/snippet.txt +++ b/exercises/practice/pangram/.approaches/set-len/snippet.txt @@ -1,3 +1,2 @@ def is_pangram(sentence): - return len([ltr for ltr in set(sentence.lower()) if ltr.isalpha()]) \ - == 26 + return len(set(ltr for ltr in sentence.lower() if ltr.isalpha())) == 26 diff --git a/exercises/practice/pangram/.articles/config.json b/exercises/practice/pangram/.articles/config.json index b7de79a678..ec053d3d0f 100644 --- a/exercises/practice/pangram/.articles/config.json +++ b/exercises/practice/pangram/.articles/config.json @@ -5,7 +5,8 @@ "slug": "performance", "title": "Performance deep dive", "blurb": "Deep dive to find out the most performant approach to determining a pangram.", - "authors": ["bobahop"] + "authors": ["bobahop"], + "contributors": ["princemuel"] } ] } diff --git a/exercises/practice/pangram/.articles/performance/code/Benchmark.py b/exercises/practice/pangram/.articles/performance/code/Benchmark.py index 1b42374447..6abefe1bee 100644 --- a/exercises/practice/pangram/.articles/performance/code/Benchmark.py +++ b/exercises/practice/pangram/.articles/performance/code/Benchmark.py @@ -28,7 +28,7 @@ def is_pangram(sentence): val = timeit.timeit("""is_pangram("Victor jagt zwölf_(12) Boxkämpfer quer über den großen Sylter Deich.")""", """ def is_pangram(sentence): - return len([ltr for ltr in set(sentence.lower()) if ltr.isalpha()]) == 26 + return len(set(ltr for ltr in sentence.lower() if ltr.isalpha())) == 26 """, number=loops) / loops diff --git a/exercises/practice/pangram/.articles/performance/content.md b/exercises/practice/pangram/.articles/performance/content.md index c5546e948b..32f7fe24d5 100644 --- a/exercises/practice/pangram/.articles/performance/content.md +++ b/exercises/practice/pangram/.articles/performance/content.md @@ -15,18 +15,18 @@ For our performance investigation, we'll also include a fourth approach that [us To benchmark the approaches, we wrote a [small benchmark application][benchmark-application] using the [`timeit`][timeit] library. ``` -all: 1.505466179997893e-05 -all: 1.6063886400021147e-05 // with sentence.casefold() -set: 1.950172399985604e-06 -len: 3.7158977999933994e-06 -bit: 8.75982620002469e-06 +all: 1.8692991019000146e-05 +all: 1.686682232399926e-05 // with sentence.casefold() +set: 2.5181135439997888e-06 +len: 5.848111433000668e-06 +bit: 1.2118699087000096e-05 ``` - The `set` `len()` approach is not as fast as the `set` `issubset()` approach. -- The `all()` approach is slower than either `set` approach. -Using `casefold` was slower than using `lower`. +- The `all()` approach is significantly slower than either `set` approach (approximately 6-8x slower). + Using `casefold()` versus `lower()` showed variable performance, with each being faster in different runs. - Although the bit field approach may be faster in other languages, it is significantly slower in Python. -It is faster than the `all()` approach, but much slower than either `set` approach. + It is faster than the `all()` approach, but much slower than either `set` approach. [benchmark-application]: https://github.com/exercism/python/blob/main/exercises/practice/pangram/.articles/performance/code/Benchmark.py [timeit]: https://docs.python.org/3/library/timeit.html diff --git a/exercises/practice/pangram/.articles/performance/snippet.md b/exercises/practice/pangram/.articles/performance/snippet.md index 0509fbee53..8542eba9fc 100644 --- a/exercises/practice/pangram/.articles/performance/snippet.md +++ b/exercises/practice/pangram/.articles/performance/snippet.md @@ -1,7 +1,7 @@ ``` -all: 1.505466179997893e-05 -all: 1.6063886400021147e-05 // with sentence.casefold() -set: 1.950172399985604e-06 -len: 3.7158977999933994e-06 -bit: 8.75982620002469e-06 +all: 1.8692991019000146e-05 +all: 1.686682232399926e-05 // with sentence.casefold() +set: 2.5181135439997888e-06 +len: 5.848111433000668e-06 +bit: 1.2118699087000096e-05 ```