Ceci dit, c'est aussi au programmeur de savoir qu'il passe à la fonction des types comparables entre eux : c'est simplement une question de bon sens.
Si la fonction est assez polymorphe pour ne pas imposer de type (et ne pas non plus imposer de valeur, donc elle évite de faire un maxi = 0 ou maxi = int() ), mais qu'elle ne nécessite que d'avoir des types comparables entre eux (ce qui est un pré-requis unique largement acceptable pour une fonction "max"), il suffit de préciser ce pré-requis dans la doc de la fonction.
Mais je trouve que l'on va un peu trop loin dans l'analyse du problème :
Pour moi, le problème du maxi=0et du maxi=int() n'est pas tant qu'elle impose des entiers (ou des nombres), mais plus qu'elle impose, comme effet de bord, que le maximum de la liste ait une valeur positive. Avant de poser un problème de polymorphisme, elle pose déjà un problème de fonctionalité : si on lui passe une liste d'entiers négatifs, bien qu'il s'agisse quand même d'entiers, elle retourne une valeur qui n'est pas contenue dans la liste. C'est un comportement inattendu.
C'est la raison pour laquelle, dans la version où je ré-écris la boucle, j'initialise explicitement maxi avec le premier élément de la liste. Ça évite non seulement ce genre d'effet de bord gênant, mais en plus ça rend la fonction utilisable avec n'importe quelle liste d'objets comparables entre eux.
Un autre moyen (pour être sûr d'éviter ce problème de fonctionalité), serait d'initialiser maxi à None :
def elemax(liste, debut=0, fin=None):
maxi = None
for elt in liste[debut:fin]:
if maxi is None or elt > maxi:
maxi = elt
return maxi
Dans ce cas, si la liste est vide, la fonction retourne None au lieu de lever bruyamment une exception : c'est un comportement acceptable que l'on retrouve dans plusieurs fonctions de Python (re.match, list.index(...), par exemple).
C'est plus concis et peut-être plus pythonnesque d'initialiser <maxi> à la première valeur de la liste. maxi=liste[debut]
Cela evite de tester la valeur de maxi par rapport à None à chaque itération. Et on peut directement commencer l'itération à debut+1.
Citation : NoHaR
Avant de poser un problème de polymorphisme, elle pose déjà un problème de fonctionalité
Oui, mais tu utilise de ces termes aussi...
Sinon... je suis d'accord.
Avant de poser un problème de polymorphisme, elle pose déjà un problème de fonctionalité
Oui, mais tu utilise de ces termes aussi...
Ben quoi, j'appelle un chat un chat.
Ce qui serait embêtant, c'est si je lâchais la phrase toute seule sans une explication de ce que j'entends par « problème de polymorphisme », dans ce cas ça serait de l'étalage gratuit de vocabulaire.
Je voulais surtout insister sur le fait qu'avant de penser polymorphisme (« Ma fonction doit être utilisable avec tous les types possibles et imaginables moyennant un minimum de contraintes »), il faut penser fonctionnalité (« Ma fonction ne doit pas faire moins que ce que l'on attend d'elle »).
Bon, après, y'a le cas où le polymorphisme est une fonctionnalité requise, mais là, je me sens pas assez intime des mouches pour les enc***** aujourd'hui.
Je pense que lever une exception est préférable à renvoyer silencieusement une valeur non attendue comme None : au final, le programme va probablement planter quand même, mais ce sera plus loin, sans moyen de savoir où est le problème. Il vaut mieux s'arrêter tout de suite.
Hum oui, mais dans re.match et list.index par exemple, c'est un comportement compréhensible : l'appel à la fonction a un sens, mais elle ne trouve pas de valeur qui vérifie les critères. Là, demander le maximum d'une liste vide n'a pas de sens, c'est pas simplement qu'on ne le trouve pas.
Dans une fonction qui doit retourner l'élément max ou min du sequence, il serait génant qu'elle retourne un élément qui n'est pas dans cette sequence... D'ailleurs les fonctions de comparaison de min() et max() déclanche une exception TypeError en cas de comparaison impossible ou une ValueError si la sequence est vide.
De toute façon, d'une manière générale, il ne faut jamais hésiter à lever une exception en cas de comportement inattendu. C'est pourquoi mon premier exemple "complet" gère le cas vide avec une exception. Les précédents le font aussi, mais de manière implicite.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.