IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Perl script aléatoire d'un hash: tirage sans remise


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 70
    Points : 49
    Points
    49
    Par défaut Perl script aléatoire d'un hash: tirage sans remise
    Bonjour,

    J'ai testé plusieurs façon mais impossible pour moi de faire ce que je veux
    J'ai une liste de 15 éléments et à la fin du script il m'en donne un aléatoirement.
    Jusqu'ici tout va bien.

    Mais je veux qu'à la seconde exécution il m'en sorte un autre non plus sur les 15, mais sur les 15 moins celui qu'il ma trouvé et ainsi de suite
    Pour ainsi avoir vraiment un aléatoire.

    Et une fois arrivé au bout il doit me prévenir qu'il n'est plus possible de le faire

    Voici mon fichier source:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    TST0000080454.mpg
    TST0000052063.mpg
    TST0000080489.mpg
    TST0000080510.mpg
    TST0000052660.mpg
    TST0000000386.mpg
    TST0000080006.mpg
    TST0000027278.mpg
    TST0000059243.mpg
    TST0000051841.mpg
    TST0000052030.mpg
    TST0000002015.mpg
    TST0000052450.mpg
    TST0000080074.mpg
    TST0000069883.mpg
    Et voici mon script

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    #!/usr/bin/perl -w
    # Purpose: Random Script
    use strict;
    use warnings;
     
    use File::Copy;
    use File::Find;
     
    # ************************************************************
    # Calcul du temps - #60*60*24*0 = Aujourd'hui
    # Aujourd'hui
    my $temps = time - 60*60*24*0;
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($temps);
    if($sec < 10) {$sec = "0" . $sec;}
    if($min < 10) {$min = "0" . $min;}
    if($hour < 10) {$hour = "0" . $hour;}
    if($mday < 10) {$mday = "0" . $mday;}
    $year+=1900; $mon++; if($mon < 10) {$mon = "0" . $mon;}
    my $today = $mday.'-'.$mon.'-'.$year;
    my $jobs_date = $year.$mon.$mday;
    my $DATE_FR_SLASH = $mday."/".($mon)."/".($year)."|".$hour.":".$min.":".$sec;
     
    print $DATE_FR_SLASH."\n";
     
    #************************************************************
    # GlobalVariables
     
    my $mystere;
    my $ligne;
    my $nbligne;
    my $film;
    my %hash;
    my @tab;
    my $MYSTERE_DIR="/archi/tmp/";
    my $LOG_DIR="/archi/tmp/";
    my $LOG_FILE="fm_ingest.log";
    my $FILM_MYSTERE="fm_liste_aleatoires.csv";
     
    #************************************************************
    # Script Starting...
     
    open (TOP,"<$MYSTERE_DIR$FILM_MYSTERE") or die "Message : TOP $!\n";
    while($ligne=<TOP>)
    {
    	chomp $ligne; # Suppréssion des rétours chariots
    	$_=$ligne; # Initialisation de la variable par défaut
    	if(/TST/) # Si le fichier est TST
    		{
    			@tab=split(/;/,$ligne); # On split les données dans un tableau
    			$film=$tab[0]; # On récupère le nom du fichier
    			$nbligne=keys(%hash)+1; # On compte le nombre d'élément
    				if(! $hash{$film}) # Si n'existe pas dans le hash
    					{
    						$hash{$film}=1; # On ajoute dans le hash
    					}
    						else # Sinon on affiche la présence d'un doublon
    							{
    								print "Doublon: ".$film."\n";
    							}
    		}
    }
    close (TOP) or die "Message : $!\n";
     
    @tab=keys %hash; # Affecte l'ensemble des clés à un tableau
    $mystere=$tab[int rand(@tab)]; # Random de la clé pour avoir le contenu
     
    open (FILE,">>$LOG_DIR$LOG_FILE") or warn "Message : $!\n";
    print FILE "Ingest Date: ".$DATE_FR_SLASH." | ".$mystere." | "."\n";
    print "Ingest Date: ".$DATE_FR_SLASH." | ".$mystere." | "."\n";
    close (FILE) or warn "Message : $!\n";
     
    #************************************************************
    # Ending...
    __END__

  2. #2
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Pour être sincère, je n'ai rien compris. Que souhaites-tu faire ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 11
    Points : 20
    Points
    20
    Par défaut
    je crois que le problème est un tirage aléatoire sans remise. Il s'agit de tirer un titre de film au sort, le mettre de côté et le sortir de la lsite avant un nouveau tirage aléatoire.


    Sympa le nom de la variable $DORCEL_dir. Il s'agit de reportages animaliers?

  4. #4
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Citation Envoyé par cobaltsixty Voir le message
    Sympa le nom de la variable $DORCEL_dir. Il s'agit de reportages animaliers?

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 70
    Points : 49
    Points
    49
    Par défaut
    Bonjour,

    Non ce n'est pas de l'animalier, c'est pour les grands adultes
    Hey oui c'est le côté sympas de mon boulot

    Donc le principe c'est bien ça,
    J'ai une liste de 15 films
    A chaque exécution il doit faire un tirage sans remise.

    1ère exécution: il me sort un film sur les 15 de la liste
    2ème exécution: il me sort un film sur les 14 de la liste restante
    3ème exécution: il me sort un film sur les 13 de la liste restante
    etc...
    et quand il a joué les 15, de me dire que c'est terminé, qu'il est temps de renouveler la liste.

    J'ai essayé avec un fichier intermédiaire avec un second hash mais cela ne fonctionne pas.

    Quelqu'un a-t-il une idée de comment procéder?

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Si tu veux vraiment faire une tirage aléatoire sans remise qui fonctionne entre deux exécution du script (et non pas dans la même exécution du script), tu as besoin d'une mémorisation externe (sur disque dur par exemple) : ton script devra sauver l'état de la liste avant de sortir (par exemple, dans le bloc END) et la récupérer (si elle existe) en début d'appel (dans le bloc INIT par exemple).
    Voit avec le module Storable.
    Personnellement, j'utilise le module Data:umper et "do" (voir perldoc -f do).
    Code perldoc : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    You might like to use "do" to read in a program configuration
    file.  Manual error checking can be done this way:
     
      # read in config files: system first, then user
      for $file ("/share/prog/defaults.rc",
                 "$ENV{HOME}/.someprogrc")
        {
          unless ($return = do $file) {
            warn "couldn't parse $file: $@" if $@;
            warn "couldn't do $file: $!"    unless defined $return;
            warn "couldn't run $file"       unless $return;
          }
        }

  7. #7
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 70
    Points : 49
    Points
    49
    Par défaut
    Merci Philou,
    Je vais étudier ça mais je vais mettre 15 ans

    J'ai déjà du mal avec les hash, while, if & foreach pour faire ce que je veux, que passer par des modules annexes va me rendre la tâche encore plus difficile.

    Là je souhaite plutôt le faire avec les outils basiques + un fichier annexe pour forcément stocker le tirage sorti pour le traiter à la prochaine exécution.

    Selon toi est-ce faisable ou vais-je devoir faire cela avec un module?

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Août 2008
    Messages : 505
    Points : 712
    Points
    712
    Par défaut
    Je n'ai pas été très attentif dans la lecture du code. Il semble assez sensé dans l'esprit même si pas mal de détails n'ont pas de sens par rapport au problème que tu poses.
    Il y a cependant une très vilaine ligne qu'il faut éliminer.
    Mais effectivement, ça n'a aucune chance de marcher dès la deuxième itération, parce que tu continues à lire le même répertoire avec le même fichier. Tu as pas mal de solutions, à mon avis.
    1. Faire un fichier avec les noms de fichiers, que tu décrémentes avec les tirages
    2. Renommer les fichiers déjà tirés (par exemple en TPT au lieu de TST)
    3. Ou bien, se mettre dans un autre répertoire, avec tout les fichiers liés dedans, et supprimer le lien à chaque tirage

  9. #9
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 70
    Points : 49
    Points
    49
    Par défaut
    Merci Thierry,
    Je vais travailler sur la première option

    Pourquoi dis-tu que c'est une très mauvaise ligne?
    Elle m'a justement été conseillé par un ami qui développe en PHP/Perl

    Je reviens vers vous avec mon ébauche ou j'espère une solution.

  10. #10
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 70
    Points : 49
    Points
    49
    Par défaut
    Bonsoir,

    C'est bon j'ai réussi
    J'ai stocké le tirage dans un fichier annexe,
    La logique qui me manquait était de traiter ce fichier en supprimant le tirage s'il existait dans le hash de départ

    Cela donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    open (TIRAGE,"<$MYSTERE_DIR"."tirage.log") or warn "Message : TIRAGE $!\n";
    while($ligne=<TIRAGE>)
    {
    	chomp $ligne; # Suppréssion des rétours chariots
    	$_=$ligne; # Initialisation de la variable par défaut
    	@tab=split(/;/,$ligne);	# On split les données dans un tableau
    	if($hash{$tab[0]}) # Si le tirage existe
    	{
    		delete($hash{$tab[0]}); # On le supprime du hash
    	}
    }
    close (TIRAGE) or warn "Message : TIRAGE $!\n";

  11. #11
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Si %hash contient la donnée que tu souhaites persistante, l'usage de Data::Dumper est simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    use Data::Dumper;
     
    my $tirage_file = "tirage.pl";
    our %hash;
     
    INIT {
      if (-f $tirage_file) {
        unless (my $return = do $tirage_file) {
          warn "couldn't parse $file: $@" if $@;
          warn "couldn't do $file: $!"    unless defined $return;
          warn "couldn't run $file"       unless $return;
        }
      }
      else {
        # INITIALISER %hash ICI
      }
    }
     
    # FAIRE LE TRAITEMENT DU TIRAGE
     
    END {
      open my $TIRAGE, ">", $tirage_file or die "Can't open $tirage_file for writing: $!\n";
      print { $TIRAGE } Data::Dumper->Dump([\%hash], [qw(*hash)]);
    }
    Avec Storable, c'est encore plus simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    use Storable;
     
    my $tirage_file = "tirage.pl";
    our %hash;
     
    INIT {
      if (-f $tirage_file) {
       $hashref = retrieve($tirage_file);
      else {
        # INITIALISER %hash ICI
      }
    }
     
    # FAIRE LE TRAITEMENT DU TIRAGE
     
    END {
     store \%hash, $tirage_file;
    }
    Je n'ai pas testé les deux scripts, qui peuvent contenir des erreurs (y compris de syntaxe).

  12. #12
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 70
    Points : 49
    Points
    49
    Par défaut
    Ok merci Philou
    Je vais tester ça

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Sources/Macros] Tirage aléatoire sans remise : macro tasr
    Par fafabzh6 dans le forum Contribuez
    Réponses: 2
    Dernier message: 10/04/2014, 20h43
  2. Boucle tirage aléatoire sans remise
    Par Jennn dans le forum Macro
    Réponses: 17
    Dernier message: 12/07/2012, 09h17
  3. faire un tirage sans remise
    Par mgrizzly dans le forum Macros et VBA Excel
    Réponses: 26
    Dernier message: 19/05/2009, 11h38
  4. tirage sans remise
    Par ouioui_cmoi dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 12/03/2008, 11h44
  5. Tirage sans remise
    Par pedrosanchau dans le forum MATLAB
    Réponses: 9
    Dernier message: 04/02/2008, 16h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo