Problème sur la table de hashage

Résolu/Fermé
laisso - Modifié par laisso le 30/11/2014 à 20:38
 laisso - 7 déc. 2014 à 22:55
Bonjour,

J'ai des difficultés pour exécuter les questions 4 5 et 6. Merci de bien vouloir m'aiguiller.


#Construire un programme proposant ces fonctionnalités :


#* Au chargement, on a au moins 4 abonnés dont un à 0 DVD et un à undef.

#* On boucle sur un menu proposant :




#1. afficher la DVDthéque
#2. ajouter un abonné
#3. supprimer un abonné
#4. emprunt d'un ou plusieurs DVD
#5. retour d'un ou plusieurs DVD
#6. quitter



#On aidera l'utilisateur à tout moment du mieux qu'on peut, exemples (non exhaustifs) :




#* 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.
#* 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à.
#* 4 : la liste des abonnés est affichée comme ci-dessus.
#* 5 : idem ci-dessus et on vérifie qu'un abonné ne peut pas rendre plus de DVD qu'il n'en a.


#!/usr/bin/perl

# 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;

# Affichage

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");
}
}

# 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

# Affichage

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");
}
}

# Révocation d'un abonné : delete

print("\n\nQuel User souhaitez vous supprimer?");
$user= <>;
chomp($user);
delete ($abonnes {$user}) ;

# Affichage

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");
}
}

# Emprunt d'un ou plusieurs DVD

print("\n\nCombien de DVD voulez vous emprunter?");
$maxDVD = -1; # le max de DVD empruntés
while (($prenom,$nbDVD) = each %abonnes) {
if ($nbDVD > $maxDVD) {
$DVD = $nbDVD;
$Emprunteur = $prenom;
}
}
print("\nIl a emprunté $DVD DVD");

# Recherche d'un abonné

print("\n\nQuel abonné cherchez-vous ? ");
$abbX = <STDIN>;
chomp($abbX); # suppression du saut de ligne
if (exists $abonnes{$abbX}) {
print("\n$abbX est abonné\nIl a emprunté $abonnes{$abbX} DVD");
} else {
print("\n$abbX n'est pas abonné\n");
}


# retour d'un ou plusieurs DVD

print'"\n\nCombien de DVD coulez vous restituer?");
while (($prenom,$nbDVD) = each %abonnes) {
if ($nbDVD > $maxDVD) {
$DVD = $nbDVD;
$restitué = $prenom;
}
}
print ("\nIl a restitué $DVD DVD");

# Quitter

print("\n\nAu revoir\n\n");

1 réponse

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 1/12/2014 à 14:52
Salut laisso,

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
Voici la version modifiée de mon code :


#!/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";
}
}
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
2 déc. 2014 à 10:53
Si tu tentes d'exécuter ton code, tu verras que, de nouveau, il ne compile pas.

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 :

    elsif ( $choix eq '4' ){
# Emprunt d'un ou plusieurs DVD
        print("\n\nCombien de DVD voulez vous emprunter?");
        my $maxDVD = -1; # le max de DVD emprunter
        while (my ($prenom,$nbDVD) = each %abonnes) {
            $DVD[$i]=$user;
            $i++;
            if ($nbDVD > $maxDVD) {
                $DVD = $nbDVD;
                $Emprunteur = $prenom;
            }
        }
        print("\nIl a emprunté $DVD DVD");
    }


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
my $emprunteur
, 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
"Guillaume"
dans
$emprunteur
, et une variable
my $n
contenant
2
, tu fais :

$abonnes{$emprunteur} = $abonnes{$emprunteur} + $n; 


Et le nombre d'ouvrages stocké dans le hash pour Guillaume passe de 3 à 5.


Dal
0
laisso > [Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024
2 déc. 2014 à 11:40
Voici le code modifié et corrigé: Par contre je n'ai fait qu'incrémenter le nombre de DVD pris.

#!/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";
}
}
0
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!




#!/usr/bin/perl
use strict;
use warnings;

my $i=0;
my @DVD;
my $emprunteur;
my $prenom;
my $n;
my %abonnes;
my $nbDVD;
my $newAbonne;
my $user;
my $maxDVD;
my $DVD;
my $restituer;

# 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"} = 0;

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 == 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 == 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 == 3 ){
# Révocation d'un abonné : delete
print("\n\nQuel User souhaitez vous supprimer?" );
$user= <>;
chomp($user);
delete ($abonnes {$user}) ;
}
elsif ( $choix == 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 == 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 == 6 ){
exit 0;
}
else{
print "Votre choix n'est pas dans ceux proposes\n";
}
}
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 4/12/2014 à 11:16
laisso,

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>
   print "Hello\n";
</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 :

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


Cela correspond à ceci :

    elsif ( $choix == 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" );
    }


et plus particulièrement à la ligne
$abonnes{$emprunteur} = $abonnes{$emprunteur} + $n;
dans laquelle tu additionnes
$n
alors que
$n
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 à
use warnings
).

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 :

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.


Cela correspond à ceci :

    elsif ( $choix == 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" );
    }


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 :

#!/usr/bin/perl

use strict;
use warnings;

my %abonnes;

$abonnes{"Guillaume"} = 3;
$abonnes{"Maxime"} = 15;
$abonnes{"Anne"} = 0; # abonné qui a déjà emprunté mais aucun emprunt en cours
$abonnes{"Michel"} = undef;

sub select_a_subscriber {
    my (%hash) = @_;
    my @arr;
    my $n;
    my $select = 0;
    foreach my $key (sort keys %hash) {
        push @arr, $key;
        print ++$n . ". $key\n";                                                                        
    }
    while (($select < 1) || ($select > $n)) {
        print "Sélection (1 à $n) ? \n";
        $select = <>;
        chomp($select);
    }
    return $arr[$select - 1];
}

my $ab = select_a_subscriber(%abonnes);
print "Abonné sélectionné : $ab\nNombre d'ouvrages empruntés : ";
defined $abonnes{$ab} ? print "$abonnes{$ab}\n" : print "jamais emprunté d'ouvrages\n";


cela donne, par exemple :

1. Anne
2. Guillaume
3. Maxime
4. Michel
Sélection (1 à 4) ?
3
Abonné sélectionné : Maxime
Nombre d'ouvrages empruntés : 15

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
0