Problème sur la table de hashage
Résolu/Fermé
A voir également:
- Erreur de hash
- Table ascii - Guide
- Table des matières word - Guide
- Table des annexes word ✓ - Forum Word
- WOrd 365 Liste des figures et annexes ✓ - Forum Word
- Table des matières et table des annexes - Forum Word
1 réponse
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
Modifié par [Dal] le 1/12/2014 à 14:52
Modifié par [Dal] le 1/12/2014 à 14:52
Salut laisso,
Ton code Perl ne compile pas, car :
- à cette ligne
... et plus bas...
- tu as un accent sur cette variable
En outre, tu ne fais pas ce que te demande de faire l'énoncé de l'exercice, qui te demande de créer un menu avec une boucle permettant d'afficher les différentes options du programme et de les exécuter en sélectionnant leur numéro.
Pareil pour la suppression : on te demande d'afficher la liste des différents abonnés avec des numéros pour que l'utilisateur puisse indiquer en tapant le numéro qui il veut supprimer, en bouclant tant qu'une saisie invalide est faite.
Par exemple :
Qui voulez-vous supprimer :
En fait, on te demande de faire une interface utilisateur (textuelle) pour que l'utilisateur sache ce qu'il peut faire avec le programme et lui faciliter la vie.
Tu devrais faire des fonctions pour chaque fonctionnalité de ton programme.
Pour tes questions "J'ai des difficultés pour exécuter les questions 4 5 et 6. Merci de bien vouloir m'aiguiller."
j'imagine que cela correspond aux items suivant du menu principal :
Si le programme se limite à comptabiliser le nombre d'ouvrages empruntés, j'imagine qu'il suffit :
- pour 4 : d'incrémenter la valeur correspondant à la personne dans le hash qui emprunte,
- pour 5 : de décrémenter
- pour 6 : tu termines ton programme : exit parait indiqué si tu es dans une boucle
Votre enseignant ne vous a pas enseigné à utiliser les directives strict et warnings ?
Dal
Ton code Perl ne compile pas, car :
- à cette ligne
print'"\n\nCombien de DVD coulez vous restituer?");, tu as une
'à la place d'une
(...
... et plus bas...
- tu as un accent sur cette variable
$restitué = $prenom;(que tu n'utilises d'ailleurs pas dans ton code)
En outre, tu ne fais pas ce que te demande de faire l'énoncé de l'exercice, qui te demande de créer un menu avec une boucle permettant d'afficher les différentes options du programme et de les exécuter en sélectionnant leur numéro.
Pareil pour la suppression : on te demande d'afficher la liste des différents abonnés avec des numéros pour que l'utilisateur puisse indiquer en tapant le numéro qui il veut supprimer, en bouclant tant qu'une saisie invalide est faite.
Par exemple :
Qui voulez-vous supprimer :
1. Guillaume
2. Maxime
3. Anne
4. Michel
0. Retour au menu principal
En fait, on te demande de faire une interface utilisateur (textuelle) pour que l'utilisateur sache ce qu'il peut faire avec le programme et lui faciliter la vie.
Tu devrais faire des fonctions pour chaque fonctionnalité de ton programme.
Pour tes questions "J'ai des difficultés pour exécuter les questions 4 5 et 6. Merci de bien vouloir m'aiguiller."
j'imagine que cela correspond aux items suivant du menu principal :
#4. emprunt d'un ou plusieurs DVD
#5. retour d'un ou plusieurs DVD
#6. quitter
Si le programme se limite à comptabiliser le nombre d'ouvrages empruntés, j'imagine qu'il suffit :
- pour 4 : d'incrémenter la valeur correspondant à la personne dans le hash qui emprunte,
- pour 5 : de décrémenter
- pour 6 : tu termines ton programme : exit parait indiqué si tu es dans une boucle
Votre enseignant ne vous a pas enseigné à utiliser les directives strict et warnings ?
Dal
1 déc. 2014 à 19:08
#!/usr/bin/perl
use strict;
use warning;
my $i=0;
my @DVD;
# La liste des emprunteurs est donnée par une table de hachage %abonnes
# Clé : indentifiant = prénom pour simplifier
# Valeur : nb de DVD empruntés
# Création de la table :
$abonnes{"Guillaume"} = 3;
$abonnes{"Maxime"} = 15;
$abonnes{"Anne"} = 0; # abonné qui a déjà emprunté mais aucun emprunt en cours
$abonnes{"Michel"} = undef;
while (1){
print "################## Menu ##################\n";
print "# #\n";
print "# 1 - Affichage de la DVDthéque #\n";
print "# 2 - Ajoute d'un abonné #\n";
print "# 3 - Suppression d'un abonné #\n";
print "# 4 - Emprunt de DVD #\n";
print "# 5 - Retour de DVD #\n";
print "# 6 - Quitter #\n";
print "# #\n";
print "##########################################\n";
print "choix : ";
my $choix=<STDIN>;
if ( $choix eq '1' ){
print("\n\nAffichage de la DVDthèque");
while (($prenom,$nbDVD) = each %abonnes) {
print "\n$prenom est abonné";
# si le nb de DVD n'est pas undef
if (defined($nbDVD)) {
print("\n\tnb de DVD empruntés : $nbDVD");
} else {
print("\n\tIl n'a jamais emprunté de DVD");
}
}
}
elsif ( $choix eq '2' ){
# Ajout d'un nouvel abonné sans emprunt
print("\n\nAjout d'un nouvel abonné sans emprunt");
print("\nQui souhaitez-vous ajouter ?");
$newAbonne =<STDIN>;
chomp($newAbonne); # suppression du saut de ligne
$abonnes{"$newAbonne"} = undef; # abonné sans emprunt
}
elsif ( $choix eq '3' ){
# Révocation d'un abonné : delete
print("\n\nQuel User souhaitez vous supprimer?");
$user= <>;
chomp($user);
delete ($abonnes {$user}) ;
}
elsif ( $choix eq '4' ){
# Emprunt d'un ou plusieurs DVD
print("\n\nCombien de DVD voulez vous emprunter?");
$maxDVD = -1; # le max de DVD emprunter
while (($prenom,$nbDVD) = each %abonnes) {
$DVD[$i]=$user
$i++
if ($nbDVD > $maxDVD) {
$DVD = $nbDVD;
$Emprunteur = $prenom;
}
}
print("\nIl a emprunté $DVD DVD");
}
elsif ( $choix eq '5' ){
# retour d'un ou plusieurs DVD
print"\n\nCombien de DVD voulez vous restituer?");
while (($prenom,$nbDVD) = each %abonnes) {
$DVD[$i]=$user
$i--
if ($nbDVD > $maxDVD) {
$DVD = $nbDVD;
$restituer = $prenom;
}
}
print ("\nIl a restitué $DVD DVD");
}
elsif ( $choix eq '6' ){
exit 0;
}
else{
print "Votre choix n'est pas dans ceux proposes\n";
}
}
2 déc. 2014 à 10:53
Les erreurs t'indiqueront que la package "warning" n'existe pas (car c'est "warnings" et non "warning"), que tu n'as pas déclaré un paquet de variables, que tu as oublié des points virgules en fin de ligne sur certaines lignes. Corrige tout cela tout seul stp, en t'aidant des messages d'erreur.
Je ne comprends pas que tu puisses faire près de 100 lignes de programme dans vérifier à chaque fois que tu en ajoutes une que ton programme compile et donne le résultat attendu.
Tu ne fais pas de fonctions, c'est dommage, car ton programme gagnerait en lisibilité et il serait plus efficace, car tu as besoin d'un code affichant la liste des personnes non seulement pour 1, mais aussi pour les autres où l'utilisateur doit choisir une personne existante, soit : 3, 4 et 5 (tu te rappelles.. tu dois faciliter la vie à l'utilisateur...).
Chaque option du menu est exécutée indépendamment l'une de l'autre.
Par exemple, lorsque tu fais :
Je ne comprends pas ton code. Tu déclares en début de code un tableau DVD, mais ne ne vois pas à quoi il te sert, si le hash fait déjà tout le travail. Tu pourrais l'utiliser pour indexer les noms sur des numéros affichés en face de chaque nom pouvant être choisi, mais tu ne fais pas cela non plus.
Hormis ce problème, une chose est sûre : le programme ne sais pas qui emprunte, car il ne demande pas cette information à l'utilisateur (en affichant la liste et en invitant l'utilisateur à indiquer qui est la personne concernée).
Une fois que tu sais qui est l'utilisateur qui emprunte (par exemple, tu as son nom dans une variable , tu utilise son nom en tant que clef pour incrémenter la valeur dans le hash après avoir demandé combien de livres il emprunte.
Par exemple, si c'est Guillaume, et qu'il veut emprunter 2 livres, si tu as dans , et une variable contenant , tu fais :
Et le nombre d'ouvrages stocké dans le hash pour Guillaume passe de 3 à 5.
Dal
2 déc. 2014 à 11:40
#!/usr/bin/perl
use strict;
use warnings;
my $i=0;
my @DVD;
my $emprunteur;
my $restituer;
my $abonnes;
my $prenom;
my $restituer;
my $n;
# La liste des emprunteurs est donnée par une table de hachage %abonnes
# Clé : indentifiant = prénom pour simplifier
# Valeur : nb de DVD empruntés
# Création de la table :
$abonnes{"Guillaume"} = 3;
$abonnes{"Maxime"} = 15;
$abonnes{"Anne"} = 0; # abonné qui a déjà emprunté mais aucun emprunt en cours
$abonnes{"Michel"} = undef;
while (1){
print "################## Menu ##################\n";
print "# #\n";
print "# 1 - Affichage de la DVDthéque #\n";
print "# 2 - Ajoute d'un abonné #\n";
print "# 3 - Suppression d'un abonné #\n";
print "# 4 - Emprunt de DVD #\n";
print "# 5 - Retour de DVD #\n";
print "# 6 - Quitter #\n";
print "# #\n";
print "##########################################\n";
print "choix : ";
my $choix=<STDIN>;
if ( $choix eq '1' ){
print("\n\nAffichage de la DVDthèque");
while (($prenom,$nbDVD) = each %abonnes) {
print "\n$prenom est abonne";
# si le nb de DVD n'est pas undef
if (defined($nbDVD)) {
print("\n\tnb de DVD empruntes : $nbDVD");
} else {
print("\n\tIl n'a jamais emprunte de DVD");
}
}
}
elsif ( $choix eq '2' ){
# Ajout d'un nouvel abonné sans emprunt
print("\n\nAjout d'un nouvel abonné sans emprunt");
print("\nQui souhaitez-vous ajouter ?");
$newAbonne =<STDIN>;
chomp($newAbonne); # suppression du saut de ligne
$abonnes{"$newAbonne"} = undef; # abonné sans emprunt
}
elsif ( $choix eq '3' ){
# Révocation d'un abonné : delete
print("\n\nQuel User souhaitez vous supprimer?");
$user= <>;
chomp($user);
delete ($abonnes {$user}) ;
}
elsif ( $choix eq '4' ){
# Emprunt d'un ou plusieurs DVD
print("\n\nCombien de DVD voulez vous emprunter?");
$maxDVD = -1; # le max de DVD emprunter
while (($prenom,$nbDVD) = each %abonnes) {
$DVD[$i]=$user;
$i++;
if ($nbDVD > $maxDVD) {
$DVD = $nbDVD;
$Emprunteur = $prenom;
$abonnes{$emprunteur} = $abonnes{$emprunteur} + $n;
}
}
print("\nIl a emprunte $DVD DVD");
}
elsif ( $choix eq '5' ){
# retour d'un ou plusieurs DVD
print"\n\nCombien de DVD voulez vous restituer?");
while (($prenom,$nbDVD) = each %abonnes) {
$DVD[$i]=$user;
$i--;
if ($nbDVD > $maxDVD) {
$DVD = $nbDVD;
$restituer = $prenom;
$abonnes{$restituer} = $abonnes{$restituer} - $n;
}
}
print ("\nIl a restitue $DVD DVD");
}
elsif ( $choix eq '6' ){
exit 0;
}
else{
print "Votre choix n'est pas dans ceux proposes\n";
}
}
4 déc. 2014 à 09:19
Use of uninitialized value $maxDVD in numeric gt (>) at perl.pl line 90, <STDIN> line 1.
Use of uninitialized value $n in subtraction (-) at perl.pl line 93, <STDIN> line 1.
Use of uninitialized value $maxDVD in numeric gt (>) at perl.pl line 90, <STDIN> line 1.
Modification of non-creatable array value attempted, subscript -2 at perl.pl line 88, <STDIN> line 1.
Pour le choix 4, J'ai ce message
Use of uninitialized value $n in addition (+) at perl.pl line 79, <STDIN> line 3.
Use of uninitialized value $n in addition (+) at perl.pl line 79, <STDIN> line 3.
Use of uninitialized value $n in addition (+) at perl.pl line 79, <STDIN> line 3.
Use of uninitialized value $n in addition (+) at perl.pl line 79, <STDIN> line 3
Merci de votre aide!
Modifié par [Dal] le 4/12/2014 à 11:16
1.
Je n'avais pas répondu à ton précédent message car tu repostais un code qui ne compilait pas, ne déclarant pas les variables, et qui ne tenait pas compte de mes observations.
Celui que tu postes compiles désormais, les erreurs étant seulement signalées à l'exécution, merci d'avoir fait cet effort :-)
Stp, lorsque tu postes du code, mets le entre balises code, comme ceci :
<code perl>
</code>
Cela va colorer la syntaxe de ton code, préserver l'indentation de ce que tu postes et numéroter les lignes. Cela est plus lisible sur le forum.
Ton code ne tient cependant toujours pas compte de toutes mes précédentes observations.
Sois attentif, stp, car je ne vais pas me répéter indéfiniment.
2.
Pour :
Cela correspond à ceci :
et plus particulièrement à la ligne dans laquelle tu additionnes alors que n'est initialisé à rien de particulier. Tu t'es contenté de le déclarer, mais Perl t'avertit que tu n'y a rien mis (grâce à ).
Cela rejoint une autre observation que j'ai déjà faite sur ce code :
Hormis ce problème, une chose est sûre : le programme ne sais pas qui emprunte, car il ne demande pas cette information à l'utilisateur (en affichant la liste et en invitant l'utilisateur à indiquer qui est la personne concernée).
Ton algorithme est faux, et comme déjà indiqué, je ne comprends pas du tout ton code, ou ce que tu essayes de faire.
A mon sens, ce que tu dois faire c'est :
- afficher la liste des abonnés
- demander à l'utilisateur du programme quel est l'abonné qui veut emprunter un livre
- demander à l'utilisateur du programme combien de livres l'abonné veut emprunter
- s'il y a un maximum de livres qu'un abonné donné peut emprunter, en tenir compte (ton énoncé n'indique pas cette information, cependant)
- si l'emprunt est permis, incrémenter la valeur correspondant au nombre de livres que cette personne a emprunté du nombre de livres nouvellement empruntés
3.
pour :
Cela correspond à ceci :
Les erreurs signalées à l'exécution sont dues au fait que la valeur de $i est décrémentée et tu te retrouves avec des indices négatifs, et que, par ailleurs, $maxDVD et $n ne sont pas initialisés.
là aussi, ton algorithme est faux, tout est à revoir, tu dois :
- afficher la liste des abonnés
- demander à l'utilisateur du programme quel est l'abonné qui veut restituer un livre
- demander à l'utilisateur du programme combien de livres l'abonné veut restituer
- éventuellement faire un contrôle de cohérence pour vérifier qu'il ne restitue pas plus de livres qu'il n'est sensé avoir déjà emprunté, s'il y a une erreur, traiter l'erreur (sois créatif) : renvoyer une erreur et arrêter le programme, ou renvoyer une erreur et demander une nouvelle saisie, ou renvoyer une erreur et revenir au menu principal, etc.
- si l'information est cohérente, traiter la restitution en décrémentant la valeur correspondant au nombre de livres que cette personne a emprunté du nombre de livres désormais restitués
Ta boucle n'a aucune raison d'être, et ton tableau ne sert à rien.
4.
Si tu veux vraiment utiliser un tableau et une boucle en complément de ton hash, d'une façon qui ait un sens par rapport à l'énoncé, tu peux le faire pour présenter la liste des abonnés précédée d'un numéro, permettant à l'utilisateur de taper un numéro pour choisir un abonné, au lieu d'avoir à taper son nom.
Voilà un exemple, avec une fonction réutilisable à cet effet :
cela donne, par exemple :
Les noms sont, en outre, classés par ordre alphabétique.
Cela te permet de combiner la souplesse du hash, avec l'indexation séquentielle permise par le array, et de répondre à la demande qui t'est faite (on affiche la liste des abonnés avec des numéros pour qu'il puisse indiquer rapidement).
Est-ce toi qui a pris l'initiative d'utiliser un hash pour stocker les données, ou est-ce une demande qui t'est faite et qui n'est pas apparente dans l'énoncé que tu donnes ?
Comme déjà dit précédemment, tu devrais faire des fonctions Perl pour exécuter les différentes parties de ton code, surtout les parties réutilisables, mais aussi les autres.
Un switch / case te permettrait de présenter la logique de la totalité de ton programme en un écran.
http://perldoc.perl.org/5.8.8/Switch.html
Cela présente aussi l'avantage de t'éviter de créer des variables globales, avec les risques que cela représente, pour des variables dont tu n'as un usage que dans une partie de ton code, désormais encapsulé dans une fonction. Cela réduit la portée de tes variables à la fonction qui les utilise, et évite de mauvaises surprises.
Et puis, de toutes façons, c'est une bonne pratique de séparer
Dal