Test sur un tableau...

Résolu/Fermé
Akre66 Messages postés 55 Date d'inscription mercredi 14 mai 2014 Statut Membre Dernière intervention 4 octobre 2016 - 29 oct. 2014 à 18:02
Akre66 Messages postés 55 Date d'inscription mercredi 14 mai 2014 Statut Membre Dernière intervention 4 octobre 2016 - 30 oct. 2014 à 16:37
Bonjour,


J'ecris un script depuis ce matin mais je bloque sur un point... J'ai beau tourner en rond je vois pas trop.

En gros, je dois recupérer des valeurs allant de 0 à 15k.
Ces valeurs je cherche à les regroupes sur des intervalles fixés ( [0;150[, [150;500[, [500;1000[, [1000;2000[, puis tous les 1000).
Après les avoir ranger, je dois dois soustraire la valeur à la borne infirieur.
tout ceci va me permettre de définir les valeurs selon deux variations.

Exemples:

175 va dans le groupe [150;500] et a un pas de 25.
2200 va dans [2000;3000] et un pas de 200...

Je sais pas si j'ai été assez clair, sinon je peux préciser.
merci


A voir également:

4 réponses

[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 29/10/2014 à 18:23
Salut Akre66,

Tu bloques sur un point, mais tu ne dis pas sur quel point tu bloques.

En gros, je dois recupérer des valeurs allant de 0 à 15k.
Ces valeurs je cherche à les regroupes sur des intervalles fixés ( [0;150[, [150;500[, [500;1000[, [1000;2000[, puis tous les 1000).


çà je comprends à peu près

Après les avoir ranger, je dois dois soustraire la valeur à la borne infirieur.
tout ceci va me permettre de définir les valeurs selon deux variations.


Cependant, si tu affectes 275 dans le groupe 150-500, tu fais 275-150 = 125 et tu en fais quoi de 275 et de 125 ? (et des autres valeurs initiales et calculées "rangées") ?

Exemples:

175 va dans le groupe [150;500] et a un pas de 25.
2200 va dans [2000;3000] et un pas de 200...


Je comprends que ce que tu appelles "le pas", c'est le résultat de la soustraction de la valeur avec la borne inférieure du groupe auquel elle appartient.

Tu veux seulement afficher comme dans ton exemple, ou stocker des choses dans des structures de données ?


Dal
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 29/10/2014 à 18:29
autre question, les valeurs que tu récupères sont-elles uniques, ou peuvent-elles être dupliquées (par exemple, il y a deux fois 2200 et tu as besoin de conserver cette information) ?
0
Akre66 Messages postés 55 Date d'inscription mercredi 14 mai 2014 Statut Membre Dernière intervention 4 octobre 2016
30 oct. 2014 à 09:55
Salut Dal,
Alors je vais essayer d'être plus clair.

En gros sur un fichier texte de ce type (bien plus grand):
								Cycle 1		
Nom Date Bu P. relative Bore G1 G2 N1 N2 R/D Cannaux
xxxxxxx 07/06/2013 66 86 1170 224 224 224 224 202 55
xxxxxxx 10/06/2013 198 98,5 1079 224 224 224 224 206 55
xxxxxxx 10/07/2013 1311 100,9 945 224 224 224 224 207 55
xxxxxxx 06/08/2013 2300 100,7 843 224 224 224 224 208 55
xxxxxxx 05/09/2013 3427 97,7 732 224 224 224 224 209 55
xxxxxxx 03/10/2013 4451 100,8 611 224 224 224 224 210 55
xxxxxxx 25/11/2013 6436 100,2 399 224 224xxxxxxx224 224 211 55
xxxxxxx 23/12/2013 7502 100,5 296 224 224 224 224 212 55
xxxxxxx 16/01/2014 8405 100,5 206 224 224 224 223,7 213 55
xxxxxxx 12/02/2014 9435 100,2 104 224 224 224 224 216 55
xxxxxxx 06/03/2014 10276 100,5 29 224 224 224 224 219 55
Cycle 2
Nom Date Bu P. relative Bore G1 G2 N1 N2 R/D Cannaux
xxxxxxx 06/05/2014 4,4 7,8 1808 224 224 224 224 212 55
xxxxxxx 11/05/2014 96 88,1 1293 224 224 224 224 200 55
xxxxxxx 13/05/2014 161 100,1 1238 224 224 224 224 205 55
xxxxxxx 19/05/2014 391 99,9 1186 224 224224 224 205 55



En gros, pour chaque cycle, je souhaite récupérer les valeurs de la troisième colonne. (FAIT)
Puis ces valeurs, je dois les décomposer en deux étapes.
La première admet uniquement les valeurs suivantes:
0,150,500,1000,2000,3000,...,16000.
Pour la deuxième on est libre.

Donc pour le cas de fichier, le dernier cycle, j'ai comme BU: 4.4, 96,161, 391.
4.4=0+4.4
96=0+96
161=150+11
391=150+241
Après pour ce cas j'aimerai avoir un tableau à deux dimension avec les valeurs de pas pour chaque pas.
Soit: (4.4;96) /(11;241)


Mon programme actuel est le suivant :
(il marche pas)

for($A=0;$A<$N+1;$A++){
	($cycle[$A]=$cycle[$A])=~s/\W//g;
	print "cycle $cycle[$A] \n";
	####CREATION DE LA LISTE RUB ###
	$ls="ls $home/cdf/rub/$Site/Tranche_$Tranche/$cycle[$A] > liste_rub";
	system ("$ls");
	open (FILE_IN_THE, "liste_rub") or die ("open: $!");##Meme manière pour le cycle, on écrit la liste des fichiers rubs sur un fichier
	@fichier=<FILE_IN_THE> ; ##On associe cette liste à un tableau
	$n=$#fichier;
	close(FILE_IN_THE);
	
	
	##Récupération des lignes de données###
	#Ce fichier a été cré via le programme Traitement avant
	open(DON, "$home/Donnees/$Site"."$Tranche");
	@fichier=<DON>; ##On associe tout ce fichier à un tableau
	close(DON);
	
	@donne=grep{$_=~/^$cycle[$A]/}@fichier; ##On récupere les lignes correpondant au cycle cherché
	
	#On initalise les valeurs
	@bu=0;
	@bu1=0;
	$evol=0;
	$tampon=0;

	
	##On prends les valeurs des BU qu'on rentre dans un tableau (bu)
	for($B=1;$B<$n+2;$B++){
		@ligne=split(" ",$donne[$B]);
		($ligne[2]=$ligne[2])=~s/\,/\./g; ##la troisieme case correspond au bu, donc on le récupére;
		##On encadre la valeur du bu de cette ligne puis on l'injecte dans le tableau correspondant		
		if($ligne[2]-$tampon<0){ ##Si cette relation n'est pas verifié, la valeur est fausse
			print "Error \n";	
		}
		else{
			$tampon=$ligne[2]; ###On change le tampon, la derniere valeur verifiée
			$bu[$B]=$ligne[2]; ##On infecte cette valeur dans notre tableau
			}
		}
		
		$evol=$#bu;
		print "Evol $evol \n";
		
		
		print "$bu1[1][1] \n";
		
		###Calcul et association des différents seuils à un tableau
		$Seuil[0]=150;
		$Seuil[1]=500; ###On donne les premiers
		$x=1;	
		for($y=2;$y<$evol-1;$y++){
			$Seuil[$y]=$x*1000; ###Les suivants suivent cette relation
			print "$Seuil[$y] \n";
			$x=$x+1;
			}
			
		for($y=0;$y<$evol-1;$y++){
			for($B=1;$B<$n+2;$B++){
				$bu1[$y]=grep{$bu[$B]>$Seuil[$y] && $bu[$B]<$Seuil[$y+1]}@bu
				}
			}
		
		
	}
0
Akre66 Messages postés 55 Date d'inscription mercredi 14 mai 2014 Statut Membre Dernière intervention 4 octobre 2016
30 oct. 2014 à 09:57
Pour ta question, c'est possible qu'il y ait deux valeurs, bien que pas attendu. Mais le pas (donc "0") doit etre pris en compte... J'ai pas encore penser à le verifier dans mon programme
0
Akre66 Messages postés 55 Date d'inscription mercredi 14 mai 2014 Statut Membre Dernière intervention 4 octobre 2016
30 oct. 2014 à 11:18
Je manipule le programme, donc j'ai corrigé pas mal de truc... J'arrive à bien récupérer le nombre de seuils nécessaire (donc de groupe), a bien les ranger.

Mais le soucis c'est que j'aimerai rentrer ces valeurs dans un tableau à 2 dimension. Une definerait l'intervalle, l'autre les valeurs contenu dans cette intervalle...
Et j'arrive pas...

J'essaye de le faire sous un tableau, parce qu'après je devrais le soustraire au seuil, et en plus rentrer ces valeurs dans un dossier spécial... Donc niveau organisation ça m'irait mieux mais je sais pas si c'est possible...

.
##On prends les valeurs des BU qu'on rentre dans un tableau (bu)
	for($B=1;$B<$n+2;$B++){
		@ligne=split(" ",$donne[$B]);
		($ligne[2]=$ligne[2])=~s/\,/\./g; ##la troisieme case correspond au bu, donc on le récupére;
		##On encadre la valeur du bu de cette ligne puis on l'injecte dans le tableau correspondant		
		if($ligne[2]-$tampon<0){ ##Si cette relation n'est pas verifié, la valeur est fausse
			print "Error \n";	
		}
		else{
			$tampon=$ligne[2]; ###On change le tampon, la derniere valeur verifiée
			$bu[$B]=$ligne[2]; ##On infecte cette valeur dans notre tableau
			}
		}
		
		$x=$#bu;
		if($bu[$x]<150){
			$evol=0;
			}
		elsif($bu[$x]<500){
			$evol=1;
			}
		elsif($bu[$x]<1000){
			$evol=2;
			}
		else{
			$evol=int($bu[$x]/1000)+1;
		}	
		print "Evol $evol \n";
		
		
		###Calcul et association des différents seuils à un tableau
		@Seuil=0;
		$Seuil[0]=150;
		$Seuil[1]=500; ###On donne les premiers
		$x=1;	
		for($y=2;$y<=$evol;$y++){
			$Seuil[$y]=$x*1000; ###Les suivants suivent cette relation
			$x=$x+1;
			}

		for($y=0;$y<$evol-1;$y++){
			for($B=1;$B<$n+2;$B++){
				@bu1[$y]=grep{$_>$Seuil[$y] && $_<$Seuil[$y+1]}@bu
				}
			}
		
		
	}
0
Akre66 Messages postés 55 Date d'inscription mercredi 14 mai 2014 Statut Membre Dernière intervention 4 octobre 2016
30 oct. 2014 à 15:10
Alors d'après quelques test et tout il semblerait que parfois (2 cycles sur 30) me font planter. La raison se trouve dans ma boucle condition if... En effet la boucle continue malgrè l'erreur, ce qui entraine que par la suite la valeur du max n'est pas la bonne, ce qui entraine que les intervalles non plus...
Enfin ça serait peut-être ça...Qu'en pensez vous ?

Et il existe une fonction "break" ou autre qui me permettrai de sauter un tour dans ma première boucle ?
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 30/10/2014 à 16:08
Salut Akre66,

Ce n'est pas super clair, mais si tu cherches un moyen de stocker dans un tableau, la valeur récupérée, sa limite inférieure et la différence entre les deux, tu peux faire avec un tableau de hash, comme dans cet exemple, qui fonctionne avec ton jeu de données :

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

# création d'un tableau des seuils
my @seuils;
push(@seuils, 0, 150, 500);
my $n = 1000;
do {
    push @seuils, $n;
    $n = $n + 1000;
} while ($n <= 15000);

# remplissage de @db avec des hash, en excluant les
# données de Cycle 2
my @db;
while (<main::DATA>)
{
    if (/\s+Cycle 2/) {
        last;
    } elsif (/^.*\s+\d\d\/\d\d\/\d\d\d\d\s+(\d+,*\d*)\s+/) {
        $n = 0;
        while ($1 > $seuils[$n]) {
            $n++;
        }
        --$n;
        push @db, {
            "val"   => $1,
            "seuil" => $seuils[$n],
            "pas"   => $1 - $seuils[$n]
        };
    }
}
print Dumper(@db);

exit;                                                                                                                       

__END__
1       
Nom Date    Bu  P. relative Bore    G1  G2  N1  N2  R/D Cannaux
xxxxxxx 07/06/2013  66  86  1170    224 224 224 224 202 55
xxxxxxx 10/06/2013  198 98,5    1079    224 224 224 224 206 55
xxxxxxx 10/07/2013  1311    100,9   945 224 224 224 224 207 55
xxxxxxx 06/08/2013  2300    100,7   843 224 224 224 224 208 55
xxxxxxx 05/09/2013  3427    97,7    732 224 224 224 224 209 55
xxxxxxx 03/10/2013  4451    100,8   611 224 224 224 224 210 55
xxxxxxx 25/11/2013  6436    100,2   399 224 224xxxxxxx224   224 211 55
xxxxxxx 23/12/2013  7502    100,5   296 224 224 224 224 212 55
xxxxxxx 16/01/2014  8405    100,5   206 224 224 224 223,7   213 55
xxxxxxx 12/02/2014  9435    100,2   104 224 224 224 224 216 55
xxxxxxx 06/03/2014  10276   100,5   29  224 224 224 224 219 55
    Cycle 2                                                          
Nom Date    Bu  P. relative Bore    G1  G2  N1  N2  R/D Cannaux
xxxxxxx 06/05/2014  4,4 7,8 1808    224 224 224 224 212 55
xxxxxxx 11/05/2014  96  88,1    1293    224 224 224 224 200 55
xxxxxxx 13/05/2014  161 100,1   1238    224 224 224 224 205 55
xxxxxxx 19/05/2014  391 99,9    1186    224 224224  224 205 55



Dal
0
Akre66 Messages postés 55 Date d'inscription mercredi 14 mai 2014 Statut Membre Dernière intervention 4 octobre 2016
30 oct. 2014 à 16:37
J'ai réussi à l'instant...l'erreur était bien du à la condition dans la deuxième boucle.
J'ai corrigé le tir, et ça marche du tonnere de Dieu (mohahaha).

Merci Dal, toujours présent pour répondre aux questions même si je suis pas clair.
Je vais regarder ta propostion de près même si ça devrait aller pour moi.
0