Comment expliquer la fonction int () à un débutant

Je tutoie l'enfant d'un voisin et nous explorions la fonction int() avant de l'utiliser avec input () - qui renvoie une chaîne. Nous avons essayé ce qui suit:

int(5)
int(5.5)
int('5')
int('5.5')

Les trois premiers retourné 5 comme prévu; le dernier a jeté l'erreur

ValueError: littéral invalide pour int () avec la base 10: '5.5'

Compte tenu du comportement des trois premières lignes, comment expliquer l'erreur à un enfant de 14 ans (background = parle 4 langues mais les mathématiques ne l'sont pas chaud)?

Mise à jour C# présente le même comportement: Convert.ToInt32("5.5"); renvoie l'erreur

La chaîne D'entrée n'était pas dans un format correct.

36
demandé sur Peter Smith 2017-10-25 13:09:54

7 réponses

En un mot: parce que c'est ce que dit la spécification. C'est un peu un État d'esprit utile pour entrer dans de toute façon. ;-)

Maintenant, pourquoi la spécification le dit-elle? Il n'y a qu'un nombre fini de types qu'une fonction peut accepter comme entrée valide. La fonction int tente de couvrir deux types différents de cas d'utilisation:

  1. convertit une représentation de chaîne d'un entier en int
  2. jeter un float valeur de int, tronquant*

La troisième utilisation case, " convertit la représentation de chaîne d'un nombre à virgule flottante en int" n'est pas couvert par la spécification, car les concepteurs de langues ont décidé de ne pas le couvrir. Ce qui semble être une décision raisonnable à prendre, car ils devaient tracer la ligne quelque part sur les types que la fonction accepterait et n'accepterait pas. La représentation en chaîne d'un nombre à virgule flottante doit être analysée par float, pas par int.

* en fait: tout objet qui a une méthode __int__, mais permet de conserver il simple.


Comme contre-exemple, en PHP Vous pouvez essayer de lancer n'importe quelle chaîne dans un int, et il essaiera de vous donner la meilleure correspondance:

php > echo (int)'3.14';
3
php > echo (float)'3.14';
3.14
php > echo (int)'3 little pigs';
3
php > echo (int)'there are 3 little pigs';
0

Ce qui, honnêtement, est un comportement assez fou, surtout ce dernier. Python a un système de type strict(er); si vous essayez d'analyser une chaîne en tant que int, il doit s'agir d'une représentation parfaitement valide d'un nombre entier, pas simplement quelque chose qui contient quelque chose qui peut être interprété comme un nombre.

53
répondu deceze 2017-10-26 08:11:06

Le problème avec cette ligne est qu'il y a deux conversions impliquées:

"5.5" (string) -> 5.5 (float) -> 5 (int)

Les opérateurs de conversion en Python n'appliqueront qu'une conversion à la fois, jamais deux enchaînées, car cela pourrait devenir déroutant dans de nombreux cas.

La solution consiste à appliquer deux conversions imbriquées:

int(float("5.5"))
29
répondu rodrigo 2017-10-25 10:13:05

Vous pouvez vous référer à docs :

class int(x=0)
class int(x, base=10)

Renvoie un objet entier construit à partir d'un nombre ou d'une chaîne x, ou renvoie 0 si aucun argument n'est donné. Si x est un nombre, retournez x.__int__(). pour les nombres à virgule flottante, cela tronque vers zéro .

Si x n'est pas un nombre ou si base est donnée, alors x doit être une instance de chaîne, d'octets ou de bytearray représentant unentier littéral en radix base. éventuellement, le littéral peut être précédé de + ou - (sans espace entre les deux) et entouré par des espaces. Un littéral de base-n se compose de les chiffres 0 à n-1, avec a à z (ou A à Z) ayant des valeurs 10 à 35. La base par défaut est 10. Les valeurs autorisées sont 0 et 2-36. En Base 2, -8, et -16 littéraux peuvent être éventuellement préfixés avec 0b / 0B, 0o / 0O, ou 0x / 0X, comme avec les littéraux entiers dans le code. Base 0 signifie interpréter exactement comme un littéral de code, de sorte que la base réelle est 2, 8, 10 ou 16, et de sorte que int ('010', 0) n'est pas légal, tandis que int ('010') est également comme int ('010', 8).

Le type entier est décrit dans les Types numériques-int, float, complex.

(soulignement du mien)

Se référer à docs enseigne que dans la programmation rien n'est vraiment arbitraire, et les compilateurs/interprètes suivent simplement des règles.

4
répondu el.pescado 2017-10-25 10:22:23

Je pense que je dirais que int(5.5) et int('5.5') ne sont pas ce que vous êtes censé faire. la réponse de rodrigo donne une explication pourquoi on travaille toujours, mais en expliquant les choses à un enfant, j'essaierais de garder les choses aussi explicites que possible, et les conversions implicites n'aident pas à cela.

Alors, bien que trop explicite, pourquoi ne pas apprendre à aller comme ceci:

int(floor(float('5.5')))

, Au moins, tout est parfaitement clair et évident.

3
répondu Arne 2017-10-25 10:20:15

Je dirais que le problème derrière ceci estopérateur surchargeant , car il y a vraiment deux fonctions int() impliquées: l'une qui convertit une chaîne (si possible), l'autre tronque les flotteurs. Si l'enfant comprend les types, Je pense qu'il comprendra également ce qu'est la surcharge.

2
répondu Peter Leupold 2017-10-25 10:35:59

Essayez d'expliquer les chaînes contenant des chiffres comme si elles étaient écrites sous forme de mots.

int(5)
int(5.5)

Fonctionne puisque la fonction int() de Python le "voit" comme des nombres et prend la partie entière, comme un autre enfant, qui ne sait rien sur les virgule flottante / décimales - > les deux seraient interprétés comme 5, le reste est ignoré.

Maintenant: utiliser des chaînes

int('5')
int('5.5')

Pourrait être interprété comme "cinq" que la fonction int() de Python sait traduire en 5, mais un verbal "fivepointfive" n'est pas ce que notre enfant a jamais entendu, ne sachant rien sur le point flottant. (la fonction int () étant l'enfant ici)

Une belle question et un défi d'essayer de l'expliquer de cette façon.

1
répondu EvilSmurf 2017-10-25 10:24:59

Votre fonction (imaginaire) prend une photo d'un chat en paramètre et vous avez essayé de lui transmettre un chat réel. Il y a une conversion qui doit d'abord se produire de cat à picture of cat avant que la fonction ne sache quoi en faire.

1
répondu JeffC 2017-10-26 04:04:50