Nuestros desarrolladores estrellas agotaron sus provisiones de café, en su búsqueda todo el tiempo por la solución, hasta que Saúl halló el resultado en Bitbucket y en este momento la comparte contigo.
Solución:
is_pangram = lambda s: not set('abcdefghijklmnopqrstuvwxyz') - set(s.lower())
>>> is_pangram('abc')
False
>>> is_pangram('the quick brown fox jumps over the lazy dog')
True
>>> is_pangram('Does the quick brown fox jump over the lazy dog?')
True
>>> is_pangram('Do big jackdaws love my sphinx of quartz?')
True
Prueba string
s
es un pangrama si empezamos con el abecedario, quitamos todas las letras que encontramos en el test string, y se eliminan todas las letras del alfabeto.
Explicación
El uso de ‘lambda’ es una forma de crear una función, por lo que es una línea equivalente a escribir un def
me gusta:
def is_pangram(s):
return not set('abcdefghijklmnopqrstuvwxyz') - set(s.lower())
set()
crea una estructura de datos que no puede tener duplicados, y aquí:
- El primer conjunto son las letras del alfabeto (inglés), en minúsculas
- El segundo conjunto son los personajes de la prueba. string, también en minúsculas. Y todos los duplicados también se han ido.
Restando cosas como set(..) - set(..)
devuelve el contenido del primer conjunto, menos el contenido del segundo conjunto. set('abcde') - set('ace') == set('bd')
.
En esta prueba de pangrama:
- tomamos los personajes en la prueba string lejos del alfabeto
- Si no queda nada, entonces la prueba string contenía todas las letras del alfabeto y debía ser un pangrama.
-
Si sobra algo, entonces la prueba. string no contenía todas las letras del alfabeto, por lo que no debe ser un pangrama.
-
cualquier espacio, caracteres de puntuación de la prueba string set nunca estuvieron en el alfabeto set, por lo que no importan.
set(..) - set(..)
devolverá un conjunto vacío o un conjunto con contenido. Si forzamos conjuntos en los valores Verdadero/Falso más simples en Python, entonces los contenedores con contenido son ‘Verdaderos’ y los contenedores vacíos son ‘Falsos’.
Así que estamos usando not
para comprobar “¿hay algo sobrante?” forzando el resultado a un valor Verdadero/Falso, dependiendo de si hay sobras o no.
not
también cambia Verdadero -> Falso y Falso -> Verdadero. Lo cual es útil aquí, porque (alfabeto agotado) -> un conjunto vacío que es False
, pero queremos is_pangram
regresar True
en ese caso. Y viceversa, (el alfabeto tiene algunos sobrantes) -> un conjunto de letras que es True
, pero queremos is_pangram
regresar False
para eso.
Luego devuelva ese resultado Verdadero/Falso.
is_pangram = lambda s: not set('abcdefghijklmnopqrstuvwxyz') - set(s.lower())
# Test string `s`
#is a pangram if
# the alphabet letters
# minus
# the test string letters
# has NO leftovers
Puedes usar algo tan simple como:
import string
is_pangram = lambda s: all(c in s.lower() for c in string.ascii_lowercase)
Los conjuntos son excelentes para las pruebas de membresía:
>>> import string
>>> candidate = 'ammdjri * itouwpo ql ? k @ finvmcxzkasjdhgfytuiopqowit'
>>> ascii_lower = set(string.ascii_lowercase)
Elimine los espacios en blanco y la puntuación del candidato y luego pruebe:
>>> candidate_lower = ascii_lower.intersection(candidate.lower())
>>> ascii_lower == candidate_lower
False
Descubre lo que falta:
>>> ascii_lower.symmetric_difference(candidate_lower)
set(['b', 'e'])
Inténtalo de nuevo pero agrega las letras que faltan:
>>> candidate = candidate + 'be'
>>> candidate_lower = ascii_lower.intersection(candidate.lower())
>>> ascii_lower == candidate_lower
True
>>>