Problème sur la table de hashage

Problème sur la table de hashage - Perl - Programmation

Marsh Posté le 01-12-2014 à 23:06:53    

Merci de bien vouloir vérifier que mon code est fonctionnel
 
 

Code :
  1. #Construire un programme proposant ces fonctionnalités :
  2. #• Au chargement, on a au moins 4 abonnés dont un à 0 DVD et un à undef.
  3. #• On boucle sur un menu proposant :
  4. #1. afficher la DVDthéque
  5. #2. ajouter un abonné
  6. #3. supprimer un abonné
  7. #4. emprunt d'un ou plusieurs DVD
  8. #5. retour d'un ou plusieurs DVD
  9. #6. quitter
  10. #On aidera l'utilisateur à tout moment du mieux qu'on peut, exemples (non exhaustifs) :
  11. #• 2 : on affiche la liste des abonnés pour lui montrer ceux qui existent déjà. On vérifie que le nouvel entrant n'existe pas sinon, message.
  12. #• 3 : on affiche la liste des abonnés avec des numéros pour qu'il puisse indiquer rapidement celui qu'il veut supprimer. On boucle sur une saisie blindée sur ces numéros-là.
  13. #• 4 : la liste des abonnés est affichée comme ci-dessus.
  14. #• 5 : idem ci-dessus et on vérifie qu'un abonné ne peut pas rendre plus de DVD qu'il n'en a.
  15. #!/usr/bin/perl
  16. use strict;
  17. use warning;
  18. my $i=0;
  19. my @DVD; 
  20. # La liste des emprunteurs est donnée par une table de hachage %abonnes
  21. # Clé : indentifiant = prénom pour simplifier
  22. # Valeur : nb de DVD empruntés
  23. # Création de la table :
  24. $abonnes{"Guillaume"} = 3;
  25. $abonnes{"Maxime"} = 15;
  26. $abonnes{"Anne"} = 0; # abonné qui a déjà emprunté mais aucun emprunt en cours
  27. $abonnes{"Michel"} = undef;
  28. while (1){
  29. print "################## Menu ##################\n";
  30. print "#                                        #\n";
  31. print "# 1 - Affichage de la DVDthéque          #\n";
  32. print "# 2 - Ajoute d'un abonné                 #\n";
  33. print "# 3 - Suppression d'un abonné            #\n";
  34. print "# 4 - Emprunt de DVD                     #\n";
  35. print "# 5 - Retour de DVD                      #\n";
  36. print "# 6 - Quitter                            #\n";
  37. print "#                                        #\n";
  38. print "##########################################\n";
  39. print "choix : ";
  40. my $choix=<STDIN>;
  41. if ( $choix eq '1' ){
  42.  print("\n\nAffichage de la DVDthèque" );
  43. while (($prenom,$nbDVD) = each %abonnes) {
  44. print "\n$prenom est abonné";
  45. # si le nb de DVD n'est pas undef
  46. if (defined($nbDVD)) {
  47. print("\n\tnb de DVD empruntés : $nbDVD" );
  48. } else {
  49. print("\n\tIl n'a jamais emprunté de DVD" );
  50. }
  51. }
  52. }
  53. elsif ( $choix eq '2' ){
  54.  print("\n\nAjout d'un nouvel abonné sans emprunt" );
  55. print("\nQui souhaitez-vous ajouter ?" );
  56. $newAbonne =<STDIN>;
  57. chomp($newAbonne); # suppression du saut de ligne
  58. $abonnes{"$newAbonne"} = undef; # abonné sans emprunt
  59. }
  60. elsif ( $choix eq '3' ){
  61. print("\n\nQuel User souhaitez vous supprimer?" );
  62. $user= <>;
  63. chomp($user);
  64. delete ($abonnes {$user}) ;
  65. }
  66. elsif ( $choix eq '4' ){
  67. print("\n\nCombien de DVD voulez vous emprunter?" );
  68. $maxDVD = -1; # le max de DVD emprunter
  69. while (($prenom,$nbDVD) = each %abonnes) {
  70. $DVD[$i]=$user
  71. $i++
  72. if ($nbDVD > $maxDVD) {
  73. $DVD = $nbDVD;
  74. $Emprunteur = $prenom;
  75. }
  76. }
  77. print("\nIl a emprunté $DVD DVD" );
  78. }
  79. elsif ( $choix eq '5' ){
  80. print"\n\nCombien de DVD voulez vous restituer?" );
  81. while (($prenom,$nbDVD) = each %abonnes) {
  82. $DVD[$i]=$user
  83. $i--
  84. if ($nbDVD > $maxDVD) {
  85. $DVD = $nbDVD;
  86. $restituer = $prenom;
  87. }
  88. }
  89. print ("\nIl a restitué $DVD DVD" );
  90. }
  91. elsif ( $choix eq '6' ){
  92.  exit 0;
  93. }
  94. else{
  95.  print "Votre choix n'est pas dans ceux proposes\n";
  96. }
  97. }

Reply

Marsh Posté le 01-12-2014 à 23:06:53   

Reply

Marsh Posté le 02-12-2014 à 03:44:00    

Avant de poster ce code, peut être que le minimum, c'est de le passer a l'interpréteur afin de voir s'il détecte des erreurs de syntaxe.
 
Je vous donne les 3 premières:
1) #!/usr/bin/perl doit figurer en première ligne (pour le shell unix), mettre la ligne ailleurs ne sert a rien
2) use warning; c'est warnings
3) $abonnes{"Guillaume"} = 3; mais vous n'avez pas fait de déclaration my %abonnes; auparavant
etc
et il y a des erreurs de parenthésage avec les } sur la fin qui est fausse
 
A+,


Message édité par gilou le 02-12-2014 à 03:44:19

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-12-2014 à 15:44:48    

Tant que j'y suis, la principale erreur de syntaxe qui rend la suite fausse, c'est:
print"\n\nCombien de DVD voulez vous restituer?" );
ce devrait être
print"\n\nCombien de DVD voulez vous restituer?";
sans parenthèse fermante.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-12-2014 à 16:02:59    

Code :
  1. Code :
  2. #!/usr/bin/perl
  3. use strict;
  4. use warnings;
  5. my $i=0;
  6. my @DVD;
  7. my $emprunteur;
  8. my $prenom;
  9. my $restituer;
  10. my $n;
  11. my %abonne;
  12. my $nbDVD;
  13. my $newAbonne;
  14. my $user;
  15. my $maxDVD;
  16. my $DVD;
  17. # La liste des emprunteurs est donnée par une table de hachage %abonnes
  18. # Clé : indentifiant = prénom pour simplifier
  19. # Valeur : nb de DVD empruntés
  20. # Création de la table :
  21. $abonnes{"Guillaume"} = 3;
  22. $abonnes{"Maxime"} = 15;
  23. $abonnes{"Anne"} = 0; # abonné qui a déjà emprunté mais aucun emprunt en cours
  24. $abonnes{"Michel"} = undef;
  25. while (1){
  26. print "################## Menu ##################\n";
  27. print "# #\n";
  28. print "# 1 - Affichage de la DVDthéque #\n";
  29. print "# 2 - Ajoute d'un abonné #\n";
  30. print "# 3 - Suppression d'un abonné #\n";
  31. print "# 4 - Emprunt de DVD #\n";
  32. print "# 5 - Retour de DVD #\n";
  33. print "# 6 - Quitter #\n";
  34. print "# #\n";
  35. print "##########################################\n";
  36. print "choix : ";
  37. my $choix=<STDIN>;
  38. if ( $choix eq '1' ){
  39. print("\n\nAffichage de la DVDthèque" );
  40. while (($prenom,$nbDVD) = each %abonnes) {
  41.  print "\n$prenom est abonne";
  42.  # si le nb de DVD n'est pas undef
  43.  if (defined($nbDVD)) {
  44.    print("\n\tnb de DVD empruntes : $nbDVD" );
  45.  } else {
  46.    print("\n\tIl n'a jamais emprunte de DVD" );
  47.  }
  48. }
  49. }
  50. elsif ( $choix eq '2' ){
  51. # Ajout d'un nouvel abonné sans emprunt
  52. print("\n\nAjout d'un nouvel abonné sans emprunt" );
  53. print("\nQui souhaitez-vous ajouter ?" );
  54. $newAbonne =<STDIN>;
  55. chomp($newAbonne); # suppression du saut de ligne
  56. $abonnes{"$newAbonne"} = undef; # abonné sans emprunt
  57. }
  58. elsif ( $choix eq '3' ){
  59. # Révocation d'un abonné : delete
  60. print("\n\nQuel User souhaitez vous supprimer?" );
  61. $user= <>;
  62. chomp($user);
  63. delete ($abonnes {$user}) ;
  64. }
  65. elsif ( $choix eq '4' ){
  66. # Emprunt d'un ou plusieurs DVD
  67. print("\n\nCombien de DVD voulez vous emprunter?" );
  68. $maxDVD = -1; # le max de DVD emprunter
  69. while (($prenom,$nbDVD) = each %abonnes) {
  70.  $DVD[$i]=$user;
  71.  $i++;
  72.  if ($nbDVD > $maxDVD) {
  73.    $DVD = $nbDVD;
  74.    $Emprunteur = $prenom;
  75.    $abonnes{$emprunteur} = $abonnes{$emprunteur} + $n;
  76.  }
  77. }
  78. print("\nIl a emprunte $DVD DVD" );
  79. }
  80. elsif ( $choix eq '5' ){
  81. # retour d'un ou plusieurs DVD
  82. print"\n\nCombien de DVD voulez vous restituer?";
  83. while (($prenom,$nbDVD) = each %abonnes) {
  84.  $DVD[$i]=$user;
  85.  $i--;
  86.  if ($nbDVD > $maxDVD) {
  87.    $DVD = $nbDVD;
  88.    $restituer = $prenom;
  89.    $abonnes{$restituer} = $abonnes{$restituer} - $n;
  90.  }
  91. }
  92. print ("\nIl a restitue $DVD DVD" );
  93. }
  94. elsif ( $choix eq '6' ){
  95. exit 0;
  96. }
  97. else{
  98. print "Votre choix n'est pas dans ceux proposes\n";
  99. }
  100. }

Reply

Marsh Posté le 02-12-2014 à 17:59:47    

Ben manifestement, vous n'avez toujours pas corrigé toutes les erreurs de syntaxe, il en reste deux.
 
D'autre part, dans votre code, remplacez tous les tests  
if ($choix eq '1')
par
if ($choix == 1)
ça marchera beaucoup mieux.
En effet, si l'utilisateur tape 1 puis retour chariot a la console, comme texte $choix vaudra "1\n" et le test $choix eq '1' va échouer.  
Tandis que comme valeur numérique, $choix vaudra 1 et le test $choix == 1 va marcher (et marchera encore s'il y a des blancs avant et après le 1).  
 
A+,


Message édité par gilou le 02-12-2014 à 18:09:13

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-12-2014 à 19:38:42    

Voici les modifications,
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. my $i=0;
  5. my @DVD;
  6. my $emprunteur;
  7. my $prenom;
  8. my $n;
  9. my %abonnes;
  10. my $nbDVD;
  11. my $newAbonne;
  12. my $user;
  13. my $maxDVD;
  14. my $DVD;
  15. # La liste des emprunteurs est donnée par une table de hachage %abonnes
  16. # Clé : indentifiant = prénom pour simplifier
  17. # Valeur : nb de DVD empruntés
  18. # Création de la table :
  19. $abonnes{"Guillaume"} = 3;
  20. $abonnes{"Maxime"} = 15;
  21. $abonnes{"Anne"} = 0; # abonné qui a déjà emprunté mais aucun emprunt en cours
  22. $abonnes{"Michel"} = undef;
  23. while (1){
  24. print "################## Menu ##################\n";
  25. print "# #\n";
  26. print "# 1 - Affichage de la DVDthéque #\n";
  27. print "# 2 - Ajoute d'un abonné #\n";
  28. print "# 3 - Suppression d'un abonné #\n";
  29. print "# 4 - Emprunt de DVD #\n";
  30. print "# 5 - Retour de DVD #\n";
  31. print "# 6 - Quitter #\n";
  32. print "# #\n";
  33. print "##########################################\n";
  34. print "choix : ";
  35. my $choix=<STDIN>;
  36. if ( $choix eq == 1 ){
  37. print("\n\nAffichage de la DVDthèque" );
  38. while (($prenom,$nbDVD) = each %abonnes) {
  39. print "\n$prenom est abonne";
  40. # si le nb de DVD n'est pas undef
  41. if (defined($nbDVD)) {
  42.    print("\n\tnb de DVD empruntes : $nbDVD" );
  43. } else {
  44.    print("\n\tIl n'a jamais emprunte de DVD" );
  45. }
  46. }
  47. }
  48. elsif ( $choix eq == 2 ){
  49. # Ajout d'un nouvel abonné sans emprunt
  50. print("\n\nAjout d'un nouvel abonné sans emprunt" );
  51. print("\nQui souhaitez-vous ajouter ?" );
  52. $newAbonne =<STDIN>;
  53. chomp($newAbonne); # suppression du saut de ligne
  54. $abonnes{"$newAbonne"} = undef; # abonné sans emprunt
  55. }
  56. elsif ( $choix eq == 3 ){
  57. # Révocation d'un abonné : delete
  58. print("\n\nQuel User souhaitez vous supprimer?" );
  59. $user= <>;
  60. chomp($user);
  61. delete ($abonnes {$user}) ;
  62. }
  63. elsif ( $choix eq == 4 ){
  64. # Emprunt d'un ou plusieurs DVD
  65. print("\n\nCombien de DVD voulez vous emprunter?" );
  66. $maxDVD = -1; # le max de DVD emprunter
  67. while (($prenom,$nbDVD) = each %abonnes) {
  68. $DVD[$i]=$user;
  69. $i++;
  70. if ($nbDVD > $maxDVD) {
  71.    $DVD = $nbDVD;
  72.    $Emprunteur = $prenom;
  73.    $abonnes{$emprunteur} = $abonnes{$emprunteur} + $n;
  74. }
  75. }
  76. print("\nIl a emprunte $DVD DVD" );
  77. }
  78. elsif ( $choix eq == 5 ){
  79. # retour d'un ou plusieurs DVD
  80. print"\n\nCombien de DVD voulez vous restituer?";
  81. while (($prenom,$nbDVD) = each %abonnes) {
  82. $DVD[$i]=$user;
  83. $i--;
  84. if ($nbDVD > $maxDVD) {
  85.    $DVD = $nbDVD;
  86.    $restituer = $prenom;
  87.    $abonnes{$restituer} = $abonnes{$restituer} - $n;
  88. }
  89. }
  90. print ("\nIl a restitue $DVD DVD" );
  91. }
  92. elsif ( $choix eq == 6 ){
  93. exit 0;
  94. }
  95. else{
  96. print "Votre choix n'est pas dans ceux proposes\n";
  97. }
  98. }

Reply

Marsh Posté le 02-12-2014 à 19:52:35    

Bon, c'est la dernière fois que je corrige une erreur que vous aurait indiqué l'interpréteur si vous l'aviez lancé sur le script.
La prochaine fois que j'ai un code qui ne se lance pas sans erreurs de syntaxes, je n'y touche plus.
 
syntax error at gdt.pl line 36, near "eq =="
en effet, c'est  $choix == 1  et non pas  $choix eq == 1
 
Les autres erreurs:
un $Emprunteur avec un E majuscule, et l'utilisation d'une variable $restituer sans l'avoir déclare auparavant.
 
A+,


Message édité par gilou le 02-12-2014 à 19:55:07

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-12-2014 à 20:00:57    

Bon, sinon, vôtre erreur de conception la plus flagrante:
$abonnes{"$newAbonne"} = undef; # abonné sans emprunt
C'est pas une bonne idée de mettre a undef et non pas a 0, car plus loin, pour l'emprunt d'un dvd, vous avez ce code:
while (($prenom,$nbDVD) = each %abonnes) {
      $DVD[$i]=$user;
      $i++;
      if ($nbDVD > $maxDVD) {
 
et la comparaison $nbDVD > $maxDVD ne va pas du tout aimer un $nbDVD a undef.
 
A+,


Message édité par gilou le 02-12-2014 à 20:01:12

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 03-12-2014 à 16:25:49    

Nan mais gilou, arrête de faire le boulot de ce fainéant. :o


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 04-12-2014 à 09:24:25    

Bonjour,
 
Pour le choix 5 j'ai ce message d'erreur que je ne comprends pas
 
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!

 
 
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. my $i=0;
  5. my @DVD;
  6. my $emprunteur;
  7. my $prenom;
  8. my $n;
  9. my %abonnes;
  10. my $nbDVD;
  11. my $newAbonne;
  12. my $user;
  13. my $maxDVD;
  14. my $DVD;
  15. my $restituer;
  16. # La liste des emprunteurs est donnée par une table de hachage %abonnes
  17. # Clé : indentifiant = prénom pour simplifier
  18. # Valeur : nb de DVD empruntés
  19. # Création de la table :
  20. $abonnes{"Guillaume"} = 3;
  21. $abonnes{"Maxime"} = 15;
  22. $abonnes{"Anne"} = 0; # abonné qui a déjà emprunté mais aucun emprunt en cours
  23. $abonnes{"Michel"} = 0;
  24. while (1){
  25. print "################## Menu ##################\n";
  26. print "# #\n";
  27. print "# 1 - Affichage de la DVDthéque #\n";
  28. print "# 2 - Ajoute d'un abonné #\n";
  29. print "# 3 - Suppression d'un abonné #\n";
  30. print "# 4 - Emprunt de DVD #\n";
  31. print "# 5 - Retour de DVD #\n";
  32. print "# 6 - Quitter #\n";
  33. print "# #\n";
  34. print "##########################################\n";
  35. print "choix : ";
  36. my $choix=<STDIN>;
  37. if ( $choix == 1 ){
  38. print("\n\nAffichage de la DVDthèque" );
  39. while (($prenom,$nbDVD) = each %abonnes) {
  40. print "\n$prenom est abonne";
  41. # si le nb de DVD n'est pas undef
  42. if (defined($nbDVD)) {
  43.    print("\n\tnb de DVD empruntes : $nbDVD" );
  44. } else {
  45.    print("\n\tIl n'a jamais emprunte de DVD" );
  46. }
  47. }
  48. }
  49. elsif ( $choix == 2 ){
  50. # Ajout d'un nouvel abonné sans emprunt
  51. print("\n\nAjout d'un nouvel abonné sans emprunt" );
  52. print("\nQui souhaitez-vous ajouter ?" );
  53. $newAbonne =<STDIN>;
  54. chomp($newAbonne); # suppression du saut de ligne
  55. $abonnes{"$newAbonne"} = undef; # abonné sans emprunt
  56. }
  57. elsif ( $choix == 3 ){
  58. # Révocation d'un abonné : delete
  59. print("\n\nQuel User souhaitez vous supprimer?" );
  60. $user= <>;
  61. chomp($user);
  62. delete ($abonnes {$user}) ;
  63. }
  64. elsif ( $choix == 4 ){
  65. # Emprunt d'un ou plusieurs DVD
  66. print("\n\nCombien de DVD voulez vous emprunter?" );
  67. $maxDVD = -1; # le max de DVD emprunter
  68. while (($prenom,$nbDVD) = each %abonnes) {
  69. $DVD[$i]=$user;
  70. $i++;
  71. if ($nbDVD > $maxDVD) {
  72.    $DVD = $nbDVD;
  73.    $emprunteur = $prenom;
  74.    $abonnes{$emprunteur} = $abonnes{$emprunteur} + $n;
  75. }
  76. }
  77. print("\nIl a emprunte $DVD DVD" );
  78. }
  79. elsif ( $choix == 5 ){
  80. # retour d'un ou plusieurs DVD
  81. print"\n\nCombien de DVD voulez vous restituer?";
  82. while (($prenom,$nbDVD) = each %abonnes) {
  83. $DVD[$i]=$user;
  84. $i--;
  85. if ($nbDVD > $maxDVD) {
  86.    $DVD = $nbDVD;
  87.    $restituer = $prenom;
  88.    $abonnes{$restituer} = $abonnes{$restituer} - $n;
  89. }
  90. }
  91. print ("\nIl a restitue $DVD DVD" );
  92. }
  93. elsif ( $choix == 6 ){
  94. exit 0;
  95. }
  96. else{
  97. print "Votre choix n'est pas dans ceux proposes\n";
  98. }
  99. }

Reply

Marsh Posté le 04-12-2014 à 09:24:25   

Reply

Marsh Posté le 04-12-2014 à 12:21:43    

Il suffit pourtant de lire les messages d'erreur: ils sont explicites.

Citation :

Pour le choix 5 j'ai ce message d'erreur que je ne comprends pas  
 
Use of uninitialized value $maxDVD in numeric gt (> ) at perl.pl line 90, <STDIN> line 1.

je vais voir ligne 90... c'est: if ($nbDVD > $maxDVD) {
uninitialized value $maxDVD, donc $maxDVD n'a pas été initialisé avant le choix 5, et si on regarde le seul endroit du code ou il est initialisé, ligne 72, c'est quand il passe par le choix 4. Donc si on fait le 5 avant de faire le 4...
 
Et c'est le même genre de problème ligne 79: $abonnes{$emprunteur} = $abonnes{$emprunteur} + $n;
$n n'a pas été initialisé, donc vouloir l'ajouter, hem...
 

Citation :

Modification of non-creatable array value attempted, subscript -2 at perl.pl line 88, <STDIN> line 1.

Je vais voir ligne 88 c'est: $DVD[$i]=$user;
non-creatable array donc il y a un problème avec un array, le seul array de la ligne, c'est $DVD[$i], donc je vais voir sa déclaration, et je vois que ce qui est déclaré ligne 15, c'est my $DVD; bref qu'on a déclaré un scalaire et non pas un array (qui aurait été déclaré lui comme my @DVD;), pas étonnant que l'interpréteur râle.
 
A+,

Message cité 1 fois
Message édité par gilou le 04-12-2014 à 12:26:42
Reply

Marsh Posté le 04-12-2014 à 18:47:24    

gilou a écrit :

Il suffit pourtant de lire les messages d'erreur: ils sont explicites.

Citation :

Pour le choix 5 j'ai ce message d'erreur que je ne comprends pas  
 
Use of uninitialized value $maxDVD in numeric gt (> ) at perl.pl line 90, <STDIN> line 1.

je vais voir ligne 90... c'est: if ($nbDVD > $maxDVD) {
uninitialized value $maxDVD, donc $maxDVD n'a pas été initialisé avant le choix 5, et si on regarde le seul endroit du code ou il est initialisé, ligne 72, c'est quand il passe par le choix 4. Donc si on fait le 5 avant de faire le 4...
 
Et c'est le même genre de problème ligne 79: $abonnes{$emprunteur} = $abonnes{$emprunteur} + $n;
$n n'a pas été initialisé, donc vouloir l'ajouter, hem...
 

Citation :

Modification of non-creatable array value attempted, subscript -2 at perl.pl line 88, <STDIN> line 1.

Je vais voir ligne 88 c'est: $DVD[$i]=$user;
non-creatable array donc il y a un problème avec un array, le seul array de la ligne, c'est $DVD[$i], donc je vais voir sa déclaration, et je vois que ce qui est déclaré ligne 15, c'est my $DVD; bref qu'on a déclaré un scalaire et non pas un array (qui aurait été déclaré lui comme my @DVD;), pas étonnant que l'interpréteur râle.
 
A+,


 
Le problème est résolu, j'ai seulement besoin d'optimiser ce code?
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. my $i=0;
  5. my @DVD;
  6. my $emprunteur;
  7. my $prenom;
  8. my $n=0;
  9. my %abonnes;
  10. my $nbDVD;
  11. my $newAbonne;
  12. my $user;
  13. my $maxDVD=-1;
  14. my $restituer;
  15. my $abonnes;
  16. my $DVD;
  17. # La liste des emprunteurs est donnée par une table de hachage %abonnes
  18. # Clé : indentifiant = prénom pour simplifier
  19. # Valeur : nb de DVD empruntés
  20. # Création de la table :
  21. $abonnes{"Guillaume"} = 3;
  22. $abonnes{"Maxime"} = 15;
  23. $abonnes{"Anne"} = 0; # abonné qui a déjà emprunté mais aucun emprunt en cours
  24. $abonnes{"Michel"} = undef;
  25. while (1){
  26. print "################## Menu ##################\n";
  27. print "# #\n";
  28. print "# 1 - Affichage de la DVDthéque #\n";
  29. print "# 2 - Ajoute d'un abonné #\n";
  30. print "# 3 - Suppression d'un abonné #\n";
  31. print "# 4 - Emprunt de DVD #\n";
  32. print "# 5 - Retour de DVD #\n";
  33. print "# 6 - Quitter #\n";
  34. print "# #\n";
  35. print "##########################################\n";
  36. print "choix : ";
  37. my $choix=<STDIN>;
  38. if ( $choix == 1 ){
  39. print("\n\nAffichage de la DVDthèque" );
  40. while (($prenom,$nbDVD) = each %abonnes) {
  41. print "\n$prenom est abonne";
  42. # si le nb de DVD n'est pas undef
  43. if (defined($nbDVD)) {
  44.    print("\n\tnb de DVD empruntes : $nbDVD" );
  45. } else {
  46.    print("\n\tIl n'a jamais emprunte de DVD" );
  47. }
  48. }
  49. }
  50. elsif ( $choix == 2 ){
  51. # Ajout d'un nouvel abonné sans emprunt
  52. print("\n\nAjout d'un nouvel abonné sans emprunt" );
  53. print("\nQui souhaitez-vous ajouter ?" );
  54. $newAbonne =<STDIN>;
  55. chomp($newAbonne); # suppression du saut de ligne
  56. $abonnes{"$newAbonne"} = undef; # abonné sans emprunt
  57. }
  58. elsif ( $choix == 3 ){
  59. # Révocation d'un abonné : delete
  60. print("\n\nQuel User souhaitez vous supprimer?" );
  61. $user= <>;
  62. chomp($user);
  63. delete ($abonnes {$user}) ;
  64. }
  65. elsif ( $choix == 4 ){
  66. # Emprunt d'un ou plusieurs DVD
  67. sub select_a_subscriber {
  68.     my (%hash) = @_;
  69.     my @arr;
  70.     my $n;
  71.     my $select = 0;
  72.     foreach my $key (sort keys %hash) {
  73.         push @arr, $key;
  74.         print ++$n . ". $key\n";                                                                       
  75.     }
  76.     while (($select < 1) || ($select > $n)) {
  77.         print "Sélection (1 à $n) ? \n";
  78.         $select = <>;
  79.         chomp($select);
  80.     }
  81.     return $arr[$select - 1];
  82. }
  83. my $ab = select_a_subscriber(%abonnes);
  84. print("\n\nCombien de DVD voulez vous emprunter?" );
  85. {
  86. if ($nbDVD > $maxDVD) {
  87.    $DVD = <>;
  88.    $DVD[$i]=$user;
  89.    $i++;
  90.    $emprunteur = $prenom;
  91.    $abonnes{$emprunteur} = $abonnes{$emprunteur} + $n;
  92. }
  93. }
  94. print("\nil a emprunte $DVD DVD" );
  95. }
  96. elsif ( $choix == 5 ){
  97. # retour d'un ou plusieurs DVD
  98. sub select_a_subscriber {
  99.     my (%hash) = @_;
  100.     my @arr;
  101.     my $n;
  102.     my $select = 0;
  103.     foreach my $key (sort keys %hash) {
  104.         push @arr, $key;
  105.         print ++$n . ". $key\n";                                                                       
  106.     }
  107.     while (($select < 1) || ($select > $n)) {
  108.         print "Sélection (1 à $n) ? \n";
  109.         $select = <>;
  110.         chomp($select);
  111.     }
  112.     return $arr[$select - 1];
  113. }
  114. my $ab = select_a_subscriber(%abonnes);
  115. print"\n\nCombien de DVD voulez vous restituer?";
  116. {
  117. if ($nbDVD > $maxDVD) {
  118.    $DVD = <>;
  119.    $DVD[$i]=$user;
  120.    $i--;
  121.    $DVD = $nbDVD;
  122.    $restituer = $prenom;
  123.    $abonnes{$restituer} = $abonnes{$restituer} - $n;
  124. }
  125. }
  126. print ("\nil a restitue $DVD DVD" );
  127. }
  128. elsif ( $choix == 6 ){
  129. exit 0;
  130. }
  131. else{
  132. print "Votre choix n'est pas dans ceux proposes\n";
  133. }
  134. }


Message édité par laisso le 04-12-2014 à 20:07:51
Reply

Marsh Posté le 05-12-2014 à 00:48:48    

Ben je ne sais pas, ton code d'ajout et de retrait de DVD est pas compréhensible et probablement faux.
 
Au vu de ton code, je suppose que c'est un truc dans ce genre que tu voulais faire:
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my %abonnes = ("Guillaume" => 3, "Maxime" => 15, "Anne" => 0, "Michel" => undef, );
  6.  
  7.  
  8. while (1) {
  9.  print "################## Menu ##################\n";
  10.  print "#                                        #\n";
  11.  print "# 1 - Affichage de la DVDthéque          #\n";
  12.  print "# 2 - Ajoute d'un abonné                 #\n";
  13.  print "# 3 - Suppression d'un abonné            #\n";
  14.  print "# 4 - Emprunt de DVD                     #\n";
  15.  print "# 5 - Retour de DVD                      #\n";
  16.  print "# 6 - Quitter                            #\n";
  17.  print "#                                        #\n";
  18.  print "##########################################\n";
  19.  print "choix : ";
  20.  $_ = <>;
  21.  s/^\s*|\s*$//g;
  22.  if (/^\d+$/) {
  23.    if (/1/) { affichage(); next; }
  24.    if (/2/) { add_abo(); next; }
  25.    if (/3/) { del_abo(); next; }
  26.    if (/4/) { emprunt_dvd(); next; }
  27.    if (/5/) { retour_dvd(); next; }
  28.    if (/6/) { last; }
  29.  }
  30.  print "entrée invalide\n";
  31. }
  32.  
  33.  
  34. sub affichage {
  35.  print "\n\n";
  36.  print "Affichage de la DVDthèque\n\n";
  37.  foreach my $prenom (sort (keys %abonnes)) {
  38.    print "$prenom est abonné";
  39.    defined($abonnes{$prenom})?
  40.      print "\tnb de DVD empruntés : $abonnes{$prenom}\n":
  41.      print "\tIl n'a jamais emprunté de DVD\n";
  42.  }
  43.  print "\n";
  44. }
  45.  
  46. # Ajout d'un nouvel abonné sans emprunt
  47. sub add_abo {
  48.    print "\n\n";
  49.    print "Ajout d'un nouvel abonné sans emprunt\n";
  50.    print "Qui souhaitez-vous ajouter ?";
  51.    $_ = <>;
  52.    s/^\s*|\s*$//g;
  53.    if (exists $abonnes{$_}) {
  54.      print "$_ est déjà abonné\n";
  55.    }
  56.    else {
  57.      $abonnes{$_} = undef;
  58.      print "$_ est ajouté\n";
  59.    }
  60.    print "\n";
  61. }
  62.  
  63. # Révocation d'un abonné : delete
  64. sub del_abo {
  65.  print "\n\n";
  66.  print "Quel User souhaitez vous supprimer? ";
  67.  $_ = <>;
  68.  s/^\s*|\s*$//g;
  69.  if (exists $abonnes{$_}) {
  70.    delete($abonnes{$_});
  71.    print "$_ est supprimé\n";
  72.  }
  73.  else {
  74.    print "$_ ne figure pas parmi les inscrits\n";
  75.  }
  76.  print "\n";
  77. }
  78.  
  79. sub choix_inscrit {
  80.  my @inscrits = sort (keys %abonnes);
  81.  while (1) {
  82.    my $i = 1;
  83.    foreach my $inscrit (@inscrits) {
  84.      print "$i - $inscrit\n";
  85.      ++$i;
  86.    }
  87.    print "Sélection (1 à ", scalar(@inscrits), " ) ? ";
  88.    $_ = <>;
  89.    s/^\s*|\s*$//g;
  90.    if (/^\d+$/) {
  91.      last if ($_ > 0 and $_ <= @inscrits);
  92.    }
  93.    print "entrée invalide\n";
  94.  }
  95.  return $inscrits[$_-1];
  96. }
  97.  
  98. sub emprunt_dvd {
  99.  my $maxabo = 50;  #max par abonné
  100.  print "\n\n";
  101.  my $abo = choix_inscrit();
  102.  my $nbDVD = 0;
  103.  $nbDVD = $abonnes{$abo} if defined $abonnes{$abo};
  104.  if ($nbDVD == $maxabo) {
  105.    print "Vous avez déjà atteint la limite\n";
  106.    return;
  107.  }
  108.  print "\n\n";
  109.  print "Combien de DVD voulez vous emprunter (1 à ", $maxabo - $nbDVD, " )? ";
  110.  $_ = <>;
  111.  s/^\s*|\s*$//g;
  112.  if (/^\d+$/) {
  113.    if ($_ > 0 and $_ <= ($maxabo - $nbDVD)) {
  114.      $abonnes{$abo} += $_;
  115.      print("$_ nouveaux DVDs empruntés, $abonnes{$abo} DVDs empruntés au total\n" );
  116.      return;
  117.    }
  118.  }
  119.  print "entrée invalide\n";
  120. }
  121.  
  122. sub retour_dvd {
  123.  print "\n\n";
  124.  my $abo = choix_inscrit();
  125.  unless (defined($abonnes{$abo}) and $abonnes{$abo} > 0) {
  126.    print "Vous n'avez pas de DVD emprunté\n";
  127.    return;
  128.  }
  129.  print "\n\n";
  130.  print "Combien de DVD voulez vous retourner (1 à ", $abonnes{$abo}, " ) ?";
  131.  $_ = <>;
  132.  s/^\s*|\s*$//g;
  133.  if (/^\d+$/) {
  134.    if ($_ > 0 and $_ <= $abonnes{$abo}) {
  135.      $abonnes{$abo} -= $_;
  136.      print("$_ DVDs rendus, $abonnes{$abo} DVDs empruntés au total\n" );
  137.      return;
  138.    }
  139.  }
  140.  print "entrée invalide\n";
  141. }


 
J'ai découpé ton code en subs plus petites et ne faisant qu'une seule chose, j'ai viré la tonne de variables globales inutiles.
Et ça a l'air de tourner, bien que j'aie pas testé à fond.
Ceci pour t'indiquer vers quelle direction orienter ton code.
 
Bon bien sur, un vrai exemple devrait être bien plus complet, ici, c'est hyper simplifié: en particulier travailler avec vraiment des DVDs et pas seulement un nombre de DVDs (et donc gérer les problèmes de DVD déjà empruntés, vérifier que les DVDs rendus sont ceux empruntés, sauver la DVDthèque et la relire, afficher la liste des DVDs, trouver qui a emprunté un titre, etc)
 
Et bien sur, si je devais coder cela, j'utiliserais un peu d'orienté objet (il y a cela dans Perl), mais si tu débutes en perl, cela ne t'est pas pour le moment utile.
 
Et j'aurais pu aussi utiliser les mots clés given/when (uniquement en perl moderne) pour le début:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use feature "switch";
  5.  
  6. my %abonnes = ("Guillaume" => 3, "Maxime" => 15, "Anne" => 0, "Michel" => undef, );
  7.  
  8.  
  9. while (1) {
  10.  print "################## Menu ##################\n";
  11.  print "#                                        #\n";
  12.  print "# 1 - Affichage de la DVDthéque          #\n";
  13.  print "# 2 - Ajoute d'un abonné                 #\n";
  14.  print "# 3 - Suppression d'un abonné            #\n";
  15.  print "# 4 - Emprunt de DVD                     #\n";
  16.  print "# 5 - Retour de DVD                      #\n";
  17.  print "# 6 - Quitter                            #\n";
  18.  print "#                                        #\n";
  19.  print "##########################################\n";
  20.  print "choix : ";
  21.  $_ = <>;
  22.  s/^\s*|\s*$//g;
  23.  given ($_){
  24.    when (/1/) { affichage()   }
  25.    when (/2/) { add_abo()     }
  26.    when (/3/) { del_abo()     }
  27.    when (/4/) { emprunt_dvd() }
  28.    when (/5/) { retour_dvd()  }
  29.    when (/6/) { last          }
  30.    default    { print "entrée invalide\n" }
  31.  }
  32. }


 
A+,

Message cité 1 fois
Message édité par gilou le 05-12-2014 à 01:09:31

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 05-12-2014 à 10:24:35    

gilou a écrit :

Ben je ne sais pas, ton code d'ajout et de retrait de DVD est pas compréhensible et probablement faux.
 
Au vu de ton code, je suppose que c'est un truc dans ce genre que tu voulais faire:
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my %abonnes = ("Guillaume" => 3, "Maxime" => 15, "Anne" => 0, "Michel" => undef, );
  6.  
  7.  
  8. while (1) {
  9.  print "################## Menu ##################\n";
  10.  print "#                                        #\n";
  11.  print "# 1 - Affichage de la DVDthéque          #\n";
  12.  print "# 2 - Ajoute d'un abonné                 #\n";
  13.  print "# 3 - Suppression d'un abonné            #\n";
  14.  print "# 4 - Emprunt de DVD                     #\n";
  15.  print "# 5 - Retour de DVD                      #\n";
  16.  print "# 6 - Quitter                            #\n";
  17.  print "#                                        #\n";
  18.  print "##########################################\n";
  19.  print "choix : ";
  20.  $_ = <>;
  21.  s/^\s*|\s*$//g;
  22.  if (/^\d+$/) {
  23.    if (/1/) { affichage(); next; }
  24.    if (/2/) { add_abo(); next; }
  25.    if (/3/) { del_abo(); next; }
  26.    if (/4/) { emprunt_dvd(); next; }
  27.    if (/5/) { retour_dvd(); next; }
  28.    if (/6/) { last; }
  29.  }
  30.  print "entrée invalide\n";
  31. }
  32.  
  33.  
  34. sub affichage {
  35.  print "\n\n";
  36.  print "Affichage de la DVDthèque\n\n";
  37.  foreach my $prenom (sort (keys %abonnes)) {
  38.    print "$prenom est abonné";
  39.    defined($abonnes{$prenom})?
  40.      print "\tnb de DVD empruntés : $abonnes{$prenom}\n":
  41.      print "\tIl n'a jamais emprunté de DVD\n";
  42.  }
  43.  print "\n";
  44. }
  45.  
  46. # Ajout d'un nouvel abonné sans emprunt
  47. sub add_abo {
  48.    print "\n\n";
  49.    print "Ajout d'un nouvel abonné sans emprunt\n";
  50.    print "Qui souhaitez-vous ajouter ?";
  51.    $_ = <>;
  52.    s/^\s*|\s*$//g;
  53.    if (exists $abonnes{$_}) {
  54.      print "$_ est déjà abonné\n";
  55.    }
  56.    else {
  57.      $abonnes{$_} = undef;
  58.      print "$_ est ajouté\n";
  59.    }
  60.    print "\n";
  61. }
  62.  
  63. # Révocation d'un abonné : delete
  64. sub del_abo {
  65.  print "\n\n";
  66.  print "Quel User souhaitez vous supprimer? ";
  67.  $_ = <>;
  68.  s/^\s*|\s*$//g;
  69.  if (exists $abonnes{$_}) {
  70.    delete($abonnes{$_});
  71.    print "$_ est supprimé\n";
  72.  }
  73.  else {
  74.    print "$_ ne figure pas parmi les inscrits\n";
  75.  }
  76.  print "\n";
  77. }
  78.  
  79. sub choix_inscrit {
  80.  my @inscrits = sort (keys %abonnes);
  81.  while (1) {
  82.    my $i = 1;
  83.    foreach my $inscrit (@inscrits) {
  84.      print "$i - $inscrit\n";
  85.      ++$i;
  86.    }
  87.    print "Sélection (1 à ", scalar(@inscrits), " ) ? ";
  88.    $_ = <>;
  89.    s/^\s*|\s*$//g;
  90.    if (/^\d+$/) {
  91.      last if ($_ > 0 and $_ <= @inscrits);
  92.    }
  93.    print "entrée invalide\n";
  94.  }
  95.  return $inscrits[$_-1];
  96. }
  97.  
  98. sub emprunt_dvd {
  99.  my $maxabo = 50;  #max par abonné
  100.  print "\n\n";
  101.  my $abo = choix_inscrit();
  102.  my $nbDVD = 0;
  103.  $nbDVD = $abonnes{$abo} if defined $abonnes{$abo};
  104.  if ($nbDVD == $maxabo) {
  105.    print "Vous avez déjà atteint la limite\n";
  106.    return;
  107.  }
  108.  print "\n\n";
  109.  print "Combien de DVD voulez vous emprunter (1 à ", $maxabo - $nbDVD, " )? ";
  110.  $_ = <>;
  111.  s/^\s*|\s*$//g;
  112.  if (/^\d+$/) {
  113.    if ($_ > 0 and $_ <= ($maxabo - $nbDVD)) {
  114.      $abonnes{$abo} += $_;
  115.      print("$_ nouveaux DVDs empruntés, $abonnes{$abo} DVDs empruntés au total\n" );
  116.      return;
  117.    }
  118.  }
  119.  print "entrée invalide\n";
  120. }
  121.  
  122. sub retour_dvd {
  123.  print "\n\n";
  124.  my $abo = choix_inscrit();
  125.  unless (defined($abonnes{$abo}) and $abonnes{$abo} > 0) {
  126.    print "Vous n'avez pas de DVD emprunté\n";
  127.    return;
  128.  }
  129.  print "\n\n";
  130.  print "Combien de DVD voulez vous retourner (1 à ", $abonnes{$abo}, " ) ?";
  131.  $_ = <>;
  132.  s/^\s*|\s*$//g;
  133.  if (/^\d+$/) {
  134.    if ($_ > 0 and $_ <= $abonnes{$abo}) {
  135.      $abonnes{$abo} -= $_;
  136.      print("$_ DVDs rendus, $abonnes{$abo} DVDs empruntés au total\n" );
  137.      return;
  138.    }
  139.  }
  140.  print "entrée invalide\n";
  141. }


 
J'ai découpé ton code en subs plus petites et ne faisant qu'une seule chose, j'ai viré la tonne de variables globales inutiles.
Et ça a l'air de tourner, bien que j'aie pas testé à fond.
Ceci pour t'indiquer vers quelle direction orienter ton code.
 
Bon bien sur, un vrai exemple devrait être bien plus complet, ici, c'est hyper simplifié: en particulier travailler avec vraiment des DVDs et pas seulement un nombre de DVDs (et donc gérer les problèmes de DVD déjà empruntés, vérifier que les DVDs rendus sont ceux empruntés, sauver la DVDthèque et la relire, afficher la liste des DVDs, trouver qui a emprunté un titre, etc)
 
Et bien sur, si je devais coder cela, j'utiliserais un peu d'orienté objet (il y a cela dans Perl), mais si tu débutes en perl, cela ne t'est pas pour le moment utile.
 
Et j'aurais pu aussi utiliser les mots clés given/when (uniquement en perl moderne) pour le début:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use feature "switch";
  5.  
  6. my %abonnes = ("Guillaume" => 3, "Maxime" => 15, "Anne" => 0, "Michel" => undef, );
  7.  
  8.  
  9. while (1) {
  10.  print "################## Menu ##################\n";
  11.  print "#                                        #\n";
  12.  print "# 1 - Affichage de la DVDthéque          #\n";
  13.  print "# 2 - Ajoute d'un abonné                 #\n";
  14.  print "# 3 - Suppression d'un abonné            #\n";
  15.  print "# 4 - Emprunt de DVD                     #\n";
  16.  print "# 5 - Retour de DVD                      #\n";
  17.  print "# 6 - Quitter                            #\n";
  18.  print "#                                        #\n";
  19.  print "##########################################\n";
  20.  print "choix : ";
  21.  $_ = <>;
  22.  s/^\s*|\s*$//g;
  23.  given ($_){
  24.    when (/1/) { affichage()   }
  25.    when (/2/) { add_abo()     }
  26.    when (/3/) { del_abo()     }
  27.    when (/4/) { emprunt_dvd() }
  28.    when (/5/) { retour_dvd()  }
  29.    when (/6/) { last          }
  30.    default    { print "entrée invalide\n" }
  31.  }
  32. }


 
A+,


 
Bonjour je vous remercie. Cepenadant, mon code avait beaucoup de variable et j'ai essayé de faire un code fonctionnel. Je vous remercie pour votre aide.

Reply

Marsh Posté le 05-12-2014 à 11:56:27    

A la base, je n'ai pas changé les fonctionnalités de votre code (donc si elles ne répondent pas à votre problème, c'est a vous de le modifier pour quelque chose de plus adapté. Typiquement, j'aurais choisi deux structures indépendantes, une pour les abonnés, et une pour la base des DVDs, si j'avais écrit le code), j'ai juste gardé la structure de votre solution et
- découpé le code en parties indépendantes, ce qui le rend plus lisible
- viré les globales et conservé la seule globale qui a un sens, la DVDthèque (noter aussi que si j'écrivais le code, mes subs n'auraient aucune  globale, je passerais la DVDtheque par référence en argument)
 
Si j'avais eu a résoudre le problème, j'aurais commencé par poser un modèle plu réaliste:
my %abonnes = ( "Guillaume" => {"emprunt" => [{"titre" => 25, "retour" => "2-12-2014"},  
          {"titre" => 27, "retour" => "18-12-2014"},],  
          "inscrit" => "1-1-2010"},
         "Maxime" => {"emprunt" => [{"titre" => 2, "retour" => "7-1-2015"},],  
        "inscrit" => "19-7-2012"},  
         "Anne" => {"emprunt" => [],  
      "inscrit" => "22-6-2013"},
         "Michel" => {"emprunt" => undef,  
       "inscrit" => "12-9-2012"}, );
et
my %DVD = ( 1 => {"titre" => "Money", "interprete" => "Pink Floyd", "Pistes" => 8},  
     2 => {"titre" => "Abbey Road", "interprete" => "Beatles", "Pistes" => 9},  
            ...
   );
 
Ensuite, il faut voir si ce genre de chose est bien pensé, ou si c'est la base de DVDs qui doit avoir un champ emprunteur et un champ retour  par DVDs plutôt qu'avoir cela au niveau des users (chaque système a ses avantages et ses inconvénients).
 
A+,


Message édité par gilou le 05-12-2014 à 12:00:59

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed