Problème sur la table de hashage - Perl - Programmation
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+,
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+,
Marsh Posté le 02-12-2014 à 16:02:59
Code :
|
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+,
Marsh Posté le 02-12-2014 à 19:38:42
Voici les modifications,
Code :
|
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+,
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+,
Marsh Posté le 03-12-2014 à 16:25:49
Nan mais gilou, arrête de faire le boulot de ce fainéant.
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 :
|
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 |
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+,
Marsh Posté le 04-12-2014 à 18:47:24
gilou a écrit : Il suffit pourtant de lire les messages d'erreur: ils sont explicites.
je vais voir ligne 90... c'est: if ($nbDVD > $maxDVD) {
Je vais voir ligne 88 c'est: $DVD[$i]=$user; |
Le problème est résolu, j'ai seulement besoin d'optimiser ce code?
Code :
|
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 :
|
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 :
|
A+,
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.
|
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.
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+,
Marsh Posté le 01-12-2014 à 23:06:53
Merci de bien vouloir vérifier que mon code est fonctionnel