Explication algorithme avec des paramètres nommés

Fermé
Boto - Modifié le 9 juin 2023 à 15:12
mamiemando Messages postés 33433 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 décembre 2024 - 9 juin 2023 à 15:11

Bonjour, j'ai le programme suivant et je dois dire ce qu'il renvoie est ce que ce serait possible de m'expliquer le programme car je ne le comprends pas : 

def calculer(a, ** toti):
  for to ,ti in toti.items ():
    print(ti , ’: ’, to , end=’ | ’)
  print(a, end =’ | ’)

calculer(1)
calculer(2, supp1 =3, supp2 =4)


Windows / Chrome 113.0.0.0

5 réponses

georges97 Messages postés 12716 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 17 décembre 2024 2 434
8 juin 2023 à 19:20

Bonjour,

Vous devez avoir eu un message d'erreur qui vous aidera à identifier l'endroit où se produit une faute de syntaxe.

Remplacez tous les ' par " et normalement le script s'exécutera. L'important est d'identifier la nature de l'erreur, puis de la corriger, avant de répondre à la question qui vous est posée et qui concerne le résultat des fonctions.

0
PierrotLeFou
9 juin 2023 à 01:44

Le problème ne se trouve pas dans le fait qu'on utilise ' au lieu de "
Je pense que l'auteur a fait un copier-coller de ce code à partir d'une page web.
Ce sont de "faux" espaces qui sont le problème.
Il faudrait remplacer tous les espaces par des espaces. Idiot? Pas du tout!
Ou bien réécrire le code au complet.
Pour ce qui est de la question, ça dépend de la clarté du cours qui est suivi.
Il faut regarder du côté des paramètre de fonctions passés "par nom" et non positionnels, et le sens de '**' dans la définition des paramètres formels.

0
georges97 Messages postés 12716 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 17 décembre 2024 2 434
Modifié le 9 juin 2023 à 06:35

Bonjour pierrot,

Je vous laisse bien évidemment la main, cependant j'ai bien en exécutant le script tel quel le message d'erreur ;

SyntaxError: invalid character in identifier (<string>, line 3)
 

et après simple remplacement des apostrophes par des guillemets, sans toucher aux espaces, le résultat :

1 | 3 :  supp1 | 4 :  supp2 | 2 |
 

Test effectué sur le site online pytontutor.com

1
mamiemando Messages postés 33433 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 décembre 2024 7 809 > georges97 Messages postés 12716 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 17 décembre 2024
Modifié le 9 juin 2023 à 13:00

Bonjour,

En fait il y a une incompréhension : en python tu peux utiliser au choix des guillemets (") ou des apostrophes droites ('), mais dans l'extrait de code du message initial, ce sont des apostrophes penchées en avant (’). Si tu testes ce code tu verras qu'il marche :

def calculer(a, **toti):
    for to, ti in toti.items ():
        print(ti, ': ', to, end=' | ')
    print(a, end =' | ')

calculer(1)
calculer(2, supp1=3, supp2=4)

Bonne chance

0
georges97 Messages postés 12716 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 17 décembre 2024 2 434 > mamiemando Messages postés 33433 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 décembre 2024
9 juin 2023 à 13:37

Bonjour mamiemando,

Le diable est dans les détails. Merci pour les explications du post n°6. On peut souhaiter que le "demandeur", à défaut de revenir remercier, ait bénéficié de l'aide.

0

Après vérification, il semble que d'autres caractères que les espaces ne soient pas corrects.
Donc, il vaut mieux écrire tout le code à nouveau.
Voici ce que mon dump me donne:
 

*** Fichier 'az.py'
Longueur: 181 octets
 0  def calculer(a,    64 65 66 20 63 61 6C 63 75 6C 65 72 28 61 2C 20
10  ** toti):??  for   2A 2A 20 74 6F 74 69 29 3A 0D 0A 20 20 66 6F 72
20   to ,ti in toti.   20 74 6F 20 2C 74 69 20 69 6E 20 74 6F 74 69 2E
30  items ():??    p   69 74 65 6D 73 20 28 29 3A 0D 0A 20 20 20 20 70
40  rint(ti , ???: ?   72 69 6E 74 28 74 69 20 2C 20 E2 80 99 3A 20 E2
50  ??, to , end=???   80 99 2C 20 74 6F 20 2C 20 65 6E 64 3D E2 80 99
60   | ???)??  print   20 7C 20 E2 80 99 29 0D 0A 20 20 70 72 69 6E 74
70  (a, end =??? | ?   28 61 2C 20 65 6E 64 20 3D E2 80 99 20 7C 20 E2
80  ??)????calculer(   80 99 29 0D 0A 0D 0A 63 61 6C 63 75 6C 65 72 28
90  1)??calculer(2,    31 29 0D 0A 63 61 6C 63 75 6C 65 72 28 32 2C 20
A0  supp1 =3, supp2    73 75 70 70 31 20 3D 33 2C 20 73 75 70 70 32 20
B0  =4)??              3D 34 29 0D 0A
0
mamiemando Messages postés 33433 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 décembre 2024 7 809
Modifié le 9 juin 2023 à 15:10

Bonjour,

print(..., end=...)

Pour commencer, expliquons la syntaxe de print. Cette fonction admet un paramètre optionnel nommé end qui spécifie quelle chaîne de caractère doit être écrit après avoir écrit tous les arguments.

Exemples :

print("111", end="a")  # Écrit "111a"
print("111", end="bb")  # Écrit "111bb"

Par défaut, cette chaîne vaut "\n" et c'est pourquoi quand tu fais un print sans préciser ce paramètre, python passe à la ligne.

print("111")  # Écrit "111\n"
print("111", end="\n")  # Écrit aussi "111\n"

f(..., **kwargs)

Avant d'entrer dans le détail, corrigeons les erreurs d'indentation et d'apostrophes du code initialement proposé, et renommons certaines variables pour me conformer aux conventions usuelles en python.

def calculer(a, **kwargs):
    for (key, value) in kwargs.items():
        print(key , ': ', value , end=' | ')
    print(a, end =' | ')

calculer(1)
calculer(2, supp1=3, supp2=4)

Lorsque tu déclares une fonction avec un paramètre ** (par convention, on le nomme kwargs) cela signifie que la fonction qui l'implique (ici calculer) accumule l'ensemble de ses paramètres dans un dictionnaire. Ce dictionnaire contient autant de paire (clé, valeur) qu'il y a de paramètres nommés (e.g. supp1=3 et supp2=4 mais pas 2) passés à la fonction lors de son appel. Pour s'en convaincre on peut afficher le contenu de kwargs :

def calculer(a, **kwargs):
    print(kwargs)
    #for (key, value) in kwargs.items():
    #    print(key , ': ', value , end=' | ')
    #print(a, end =' | ')

calculer(1)  # Écrit {}
calculer(2, supp1=3, supp2=4)  # Écrit {'supp1': 3, 'supp2': 4}

Ainsi, itérer sur les éléments de kwargs (dans la boucle for) va consécutivement pour le deuxième appel de calculer itérer sur les paires ('supp1', 3) et ('supp2', 4).

Revenons maintenant au code précédent :

def calculer(a, **kwargs):
    for (key, value) in kwargs.items():
        print(value , ': ', key , end=' | ')
    print(a, end =' | ')

calculer(1)
calculer(2, supp1=3, supp2=4)
  • Considérons le premier appel : le dictionnaire kwargs est vide, donc on n'entre pas dans la boucle for. En pratique, seul le dernier print est exécuté ce qui écrit :
    • "1 | ".
  • Considérons le second appel :
    • le dictionnaire kwargs contient {'supp1': 3, 'supp2': 4} et donc la boucle est exécutée pour ces deux paires ce qui écrit :
      • "3: supp1 | "
      • puis "4: supp2 | "
    • puis on exécute le print final ce qui écrit :
      • "2 | "
  • Comme aucun de ces prints ne passe à la ligne, toutes ces chaînes sont écrites à la suite des autres. On obtient donc :
1 | 3 :  supp1 | 4 :  supp2 | 2 |

Bonne chance

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question

Je voudrais préciser encore que le dictionnaire est formé des paramètre nommés seulement.
Dans le test suivant, seuls les deux premiers appels passeront:

(il faut autant de paramètres positionels dans l'appel que dans la définition)
 
def test(**d):
    print(d)
test(a=1, b=2, c=3)
test()
test(1, a=2)
test(1, 2, 3)

0
mamiemando Messages postés 33433 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 décembre 2024 7 809
9 juin 2023 à 15:11

Hello PIerrot, tu as raison de le préciser, j'ai corrigé mon message #6 en conséquence.

0