cours/docstring challenge du 2023-08-13.md
oscar.plaisant@icloud.com a2ee0fa5ca from github to this gitea
2023-10-23 23:09:51 +02:00

14 KiB
Raw Blame History

alias
alias
compter les voyelles dans une chaîne de caractères

up:: discord docstring challenge de la semaine sibling:: docstring challenges - 13 août 2023.qmd date:: 2023-08-13 #informatique/python

Overview

🔶 Énoncé du challenge du dimanche 13 août 2023 :

Ce premier challenge sera très simple, cest un niveau débutant, mais si vous avez plus de lexpérience, vous pouvez essayer de trouver de belles astuces pour un code propre, rapide et concis.

👉 Créez une fonction nb_voyelles(phrase: str)->int qui retourne le résultat du nombre total de voyelles dans une phrase passée en paramètre.

🔹 Conditions

  • Les voyelles sont : aeiou, y nest pas pris en compte
  • Les voyelles accentuées ne sont pas prises en compte
  • La phrase passée en paramètre doit être écrite en minuscule
  • Une chaine vide, passée en paramètre, renvoie 0

🔹 Exemples

  • nb_voyelles("bonjour, comment allez-vous ?") retourne 9
  • nb_voyelles("je vais à paris") retourne 5
  • nb_voyelles("docstring") retourne 2
  • nb_voyelles("") retourne 0

Proposition de buck danny

def nb_voyelles(phrase: str)->int :
    return sum(phrase.count(el) for el in "aeiou")

result = nb_voyelles("je vais à paris")
print(result)

Notes

parenthèses facultatives

Les parenthèses ne sont pas obligatoires pour un calcul directe et simple. Si on passe par un variable par contre là, c'est obligatoire.

  1. When passing a generator expression as the only argument to a function, like fun((el for el in thing)), the extra pair of parentheses can be omitted. (modifié)

  2. [17:42] Since, well, it's not ambiguous what fun(el for el in thing) means, as long as it's the only argument. (modifié)

  3. [17:44] This behaviour dates back all the way to their introduction in 2.4: https://peps.python.org/pep-0289/#the-details

i.e. if a function call has a single positional argument, it can be a generator expression without extra parentheses, but in all other cases you have to parenthesize it.

def nb_voyelles(phrase: str)->int :
    return sum([ phrase.count(el) for el in "aeiou" ])

// sans parenthèses c'est ok aussi :
def nb_voyelles(phrase: str)->int :
    return sum( phrase.count(el) for el in "aeiou" )

Proposition des participants

@gabigab117

def nb_voyelles(phrase):
    VOWELS = ["a", "e", "i", "o", "u"]
    i = 0
    for letter in phrase:
        if letter in VOWELS:
            i += 1
    return i

@nbelaf

def nb_voyelles(string):
    return len([l for l in string if l.lower() in "aeiou"])

@OsKaR31415

# vim: set foldmethod=marker foldlevel=1:

# solution avec un prédicat de filtre{{{

def est_une_voyelle(lettre: str) -> bool:
    """Prédicat qui dit si `lettre` est une voyelle.# {{{
    Fonctionne avec les majuscules. "y" n'est pas considéré comme une voyelle.
    """# }}}
    assert len(lettre) == 1
    return lettre.lower() in "aeiou"

def nb_voyelles_filter(phrase: str) ->int:
    phrase = phrase.lower()
    voyelles = filter(est_une_voyelle, phrase)
    return len(list(voyelles))

# }}}

# solution one-liner{{{
# le principe est de créer une liste a partir de la phrase, en transformant
# chaque voyelle en True et chaque consonne en False.
# La somme de cette liste donne le nombre de voyelles car, dans une addition,
# True et False sont transformés en 1 et 0
nb_voyelles_golf=lambda p:sum(l in"aeiou"for l in p)# }}}


# solution "Programmation Orientée Objet Python" (POOP){{{

class Counter:
    """Object to count occurences of an `item` in any iterable."""
    def __init__(self, item: object):
        self.__item__ = item

    @property
    def item(self) -> object:
        return self.__item__

    def matches_item(self, other_item: object) -> bool:
        """Predicate to tell if `other_item` is equal to the item counted in# {{{
        the current object.
        It basically tells if `other_item` will be counted.
        """# }}}
        return self.item == other_item

    def __repr__(self) -> str:
        return f"Counter({repr(self.item)})"

    def __call__(self, item_list: iter) -> int:
        """Calling the on any iterable will return the number of occurences."""
        count = 0
        for item in item_list:
            if self.matches_item(item):
                count += 1
        return count


class LetterCounter(Counter):
    """Count the number of occurences of a given letter in any string."""
    def __init__(self, letter: str):
        self.__assert_is_letter__(letter)
        super().__init__(letter)

    def __assert_is_letter__(self, letter: str):
        """Make sure the given parameter is really a letter and nothing else.# {{{
        Raises:
            ValueError: If the given parrameter is not a letter."""# }}}
        # the order of the predicates around the `or` is important, because it
        # makes sure that letter is a str before checking its length
        if (not isinstance(letter, str)) or len(letter) != 1:
            raise ValueError(f"'{letter}' is not a letter.")

    def __repr__(self) -> str:
        return f"LetterCounter('{self.item}')"

class ParallelLetterCounter:
    """Like `LetterCounter`, but is able to count occurences of multiple# {{{
    letters at the same time."""# }}}
    def __init__(self, letters_to_count: str):
        self.__letters_to_count__ = str(letters_to_count)

    @property
    def letters_to_count(self) -> str:
        return self.__letters_to_count__

    def __call__(self, text: str) -> int:
        text = str(text)
        count = 0
        for letter in self.letters_to_count:
            counter = LetterCounter(letter)
            count += counter(text)
        return count

class Sentence:
    def __init__(self, text: str, case_sensitive: bool =False):
        self.__text__ = str(text)
        self.__case_sensitive__ = case_sensitive

    @property
    def text(self):
        if self.case_sensitive:
            return self.__text__
        else:
            return self.__text__.lower()

    @property
    def case_sensitive(self) -> bool:
        return self.__case_sensitive__

    @case_sensitive.setter
    def case_sensitive(self, value: bool) -> None:
        self.__case_sensitive__ = bool(value)

    def __repr__(self) -> str:
        return f"Phrase('{self.text}')"

    def vowels_count(self) -> int:
        """Deprecated# {{{
        Returns the number of vowels in this sentence.
        You should use the `number_of_vowels` property instead.
        This does not take case into account, even if `case_sensitive` is set to False
        """# }}}
        vowel_counter = ParallelLetterCounter("aeiou")
        return vowel_counter(self.__text__)

    @property
    def number_of_vowels(self) -> int:
        """The number of vowels contained in this sentence.# {{{
        The letter "y" is not considered to be a vowel.
        If case sensitivity is enabled, it will only count lower case letters.
        """# }}}
        vowel_counter = ParallelLetterCounter("aeiou")
        return vowel_counter(self.text)

def nb_voyelles_oop(phrase: str) -> int:
    p = Sentence(str(phrase))
    return p.number_of_vowels
# }}}


# solution obfusquée{{{
# Pour la comprendre :
#  - les ___ sont des variables
#  - faire attention au champ des variables
#  - le lambda est utilisé pour définir des variables locales
#  - l et f sont une réimplémentation de len et filter
l=lambda _:1!=1 if not _ else l(_[1:])+~-2;f=lambda _,__:''if not len(__) else __[0]+f(_,__[1:])if _(__[0])else f(_,__[1:]);_=lambda _:0+(lambda __:lambda ___:lambda ____:lambda ______:___(____(______(lambda _:ord(_)in __,_))))([97,101,105,111,117])(l)(list)(f);nb_voyelles_obfuscated=_# }}}


# solution Counter{{{
# Les compteurs sont incroyables pour ce genre d'exercices
import collections

def nb_voyelles_counter(phrase: str) -> int:
    voyelles = collections.Counter("aeiou")
    voyelles.update(phrase)
    return voyelles.total()# }}}


# tester la vitesse de chaque implémentation{{{

from random import choices
LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.?"

def random_string() -> str:
    """Générer une chaîne de 800 caractères aléatoires parmi LETTERS."""
    return ''.join(choices(LETTERS, k=800))

if __name__ == "__main__":
    from time import time
    N = 10000  # nombre d'échantillons par fonction
    FUNCTIONS = [nb_voyelles_counter,
                 nb_voyelles_obfuscated,
                 nb_voyelles_oop,
                 nb_voyelles_golf,
                 nb_voyelles_filter]
    timing = {f: 0 for f in FUNCTIONS}
    for func in FUNCTIONS:
        for _ in range(N):
            phrase = random_string()
            dep = time()
            func(phrase)
            end = time()
            timing[func] += end-dep
    timing = {f.__name__: timing[f] / N for f in timing}
    print(str(timing).replace(", ", ",\n "))# }}}

@aanks

def nb_voyelles(phrase: str) -> int:
    return sum(phrase.lower().count(voyelle) for voyelle in "aeiou")

@Rocket

def nb_voyelles(phrase: str) -> int:
    return sum(True for char in phrase if char in "aeiou")

@Incapas

def nb_voyelles(phrase: str) -> int:

    """Fonction permettant de compter le nombre de voyelles au sein d'une chaîne de caractères.

    Args:
        phrase (str):

        La chaîne de caractère peut contenir des majuscules et/ou des minuscules.
        Avec la fonction "lower" utilisée dans la structure conditionnelle, les majuscules ne seront pas comptées.
        En conséquence, une chaîne de caractères ne comportant que des majuscules sera considérée comme étant vide.

    Returns:
        int:

        Le chiffre 0 est retourné si une chaîne de caractères vide est passée comme argument lors de l'appel de la fonction.
        Le nombre de voyelles contenu dans l'argument est retourné si ce dernier comporte au moins un caractère.

    """
    a = "a"
    e = "e"
    i = "i"
    o = "o"
    u = "u"

    nb = (phrase.count(a) + phrase.count(e) + phrase.count(i) + phrase.count(o) + phrase.count(u))

    if phrase.lower() == "":
        return 0
    else:
        return nb

@Jojokes

def nb_voyelles(txt):
    return sum(1 for x in txt if x in 'aeiou')

@dwho

def nb_voyelles(phrase):
    phrase.lower()
    if len(phrase) == 0:
        return 0
    else:
        return phrase.count('a') + phrase.count('e') + phrase.count('i') + phrase.count('o') + phrase.count('u')

print(nb_voyelles(""))

@yannick_fswd

def nb_voyelles(phrase: str) -> int:
    return len([letter for letter in phrase if letter in "aeiou"])

@Vincent

import re

def nb_voyelles(phrase: str) -> int:
    '''
    Return the number of vowels in a string
    :param phrase: string
    :return: number of vowels
    '''
    #If the string is empty, we return 0
    if phrase:
        return len(re.findall("[aeiou]", phrase.lower()))
    else:
        return 0

@tuxmania

VOYELLES = ["a", "e", "i", "o", "u"]

def nb_voyelles(phrase: str) -> int:
    voyelles = 0
    for letter in phrase:
        if letter.isupper():
            raise ValueError("La phrase ne peut contenir de lettres majuscules!")
        if letter in VOYELLES:
            voyelles += 1

    return voyelles


if __name__ == "__main__":
    phrase_saisie = input("Entrez une phrase (en minuscule) svp: ")
    total_voyelles = nb_voyelles(phrase=phrase_saisie)
    print(f"Nombre total de voyelles: {total_voyelles}")

@Loudo_t

def vowel_counter(sentence: str) -> int:
    """Count the number of vowel in a string.

    Args:
        sentence (str): A string

    Returns:
        int: number of vowel
    """
    vowel_list = ["a", "e", "i", "o", "u"]
    nb_vowel = 0

    for letter in sentence:
        if letter in vowel_list:
            nb_vowel += 1

    return nb_vowel

@Hugo

def nb_voyelles(mot: str):
    # Prise en compte des voyelles existantes dans une liste
    voyelles = ['a','e','o','u','i','y']
    # Compteur de voyelles initialisé à 0 par défaut
    counter = 0
    # On compte le nombre de fois où chaque voyelle apparaît dans le mot grâce à la méthode count
    for v in voyelles:
        counter += mot.count(v)
    return counter

if __name__ == "__main__":
    print(nb_voyelles("bonjour, comment allez-vous ?"))
    print(nb_voyelles("je vais à paris"))
    print(nb_voyelles("docstring"))
    print(nb_voyelles(""))

@Romu80

def nb_voyelles(phrase: str) -> int:
    return 0 if not phrase else sum([phrase.count(v) for v in ["a", "e", "i", "o", "u"]])

@Djohner

def nb_voyelles(phrase):
  return sum([phrase.count(i) for i in "aeiou"])

@Oxilams

import time

phrase = input("entrez une phrase ou un mot, n'importe la/lequel/elle:  ")

minuscule = phrase.lower

print("Laissez moi vous dire combien il y a de voyelles dans votre phrase/mot")

compteur = 0
listedesvoyelles = ["i","e","a","u","o"]

for caractères in phrase:
    if caractères in listedesvoyelles:
        compteur = compteur+1
        time.sleep(2)

print ("Le nombre de voyelles dans votre phrase/mot est de :", compteur )

@Guaros

def nb_voyelles(phrase:str)->int:
  return sum(phrase.lower().count(char) for char in "aeiou")

@Philippe

def nb_voyelles(phrase: str) -> int:
    return sum([phrase.count(caractere) for caractere in "aeiou"])

@n0xas

def nb_voyelles(phrase: str) -> int:
    nb = 0
    lst = [nb + 1 for v in phrase if v in "aeiou"]
    return sum(lst)

a = nb_voyelles("je vais à paris")
print(a)

@GuillaumeC

def nb_voyelles(phrase: str) -> int:
       return print(sum(1 for letter in list(phrase) if letter == 'a' or letter == 'e' or letter == 'i' or letter == 'o' or letter == 'u'))

Content

type: folder_brief_live
title: Référence

title:  lien
icon: link