Programmation Help vieux rouillé
Résolu
romaingeol
-
_vince Messages postés 37 Date d'inscription Statut Membre Dernière intervention -
_vince Messages postés 37 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
Bonjour,
Voila, j'ai un ensemble de fichier ascii (une centaine) contenant un nombre de lignes variables de valeurs rangées dans l'ordre décroissant:
exemple:
fichier1.out
339.87
333.85
332.12
328.35
323.57
320.36
308.99
303.39
297.65
289.89
288.54
276.96
265.50
227.05
Je voudrais calculer la valeur X(n+1) - X(n), avec n l'indice de ligne, sauf pour la dernière ligne ou l'opération doit être 360-(X(1)-X(finale)).
Je veux ensuite conserver uniquement la valeur max de cette série de calcul.
Enfin je voudrai obtenir un fichier de type:
Nom du fichier Valeur Max
fichier1.out 50
fichier2.out 100
.
.
.
.
etc.
Dans lequel sont rassemblées les valeurs max obtenues pour chaque fichier .out
Mon fortran et mon C sont beaucoup trop loin et je n'ai malheureusement pas beaucoup de temps.
Si quelqu'un peut m'aider....
Merci
Bonjour,
Voila, j'ai un ensemble de fichier ascii (une centaine) contenant un nombre de lignes variables de valeurs rangées dans l'ordre décroissant:
exemple:
fichier1.out
339.87
333.85
332.12
328.35
323.57
320.36
308.99
303.39
297.65
289.89
288.54
276.96
265.50
227.05
Je voudrais calculer la valeur X(n+1) - X(n), avec n l'indice de ligne, sauf pour la dernière ligne ou l'opération doit être 360-(X(1)-X(finale)).
Je veux ensuite conserver uniquement la valeur max de cette série de calcul.
Enfin je voudrai obtenir un fichier de type:
Nom du fichier Valeur Max
fichier1.out 50
fichier2.out 100
.
.
.
.
etc.
Dans lequel sont rassemblées les valeurs max obtenues pour chaque fichier .out
Mon fortran et mon C sont beaucoup trop loin et je n'ai malheureusement pas beaucoup de temps.
Si quelqu'un peut m'aider....
Merci
A voir également:
- Programmation Help vieux rouillé
- Ipad trop vieux pour application - Guide
- Application de programmation - Guide
- Windows 10 allégé pour vieux pc - Télécharger - Systèmes d'exploitation
- Programmation aria soho ✓ - Forum LG
- Comment faire la couleur rouille en acrylique - Forum Graphisme
6 réponses
Salut romaingeol
Ouhla, tu m'as obligé à ressortir et à dépoussiérer les vieux codes fortran pour voir comment on faisait ne serait-ce qu'une boucle, tentons quand même...
On va supposer que ton programme et tes fichiers sont dans le même répertoire, ce qui est pas très propre en fait donc si tu veux changer ça dis le moi (en supposant que le programme marche déjà...), c'est du Fortran90
Pas sûr que ça marche... je l'ai même pas testé.
Dis-moi quand même.
Ouhla, tu m'as obligé à ressortir et à dépoussiérer les vieux codes fortran pour voir comment on faisait ne serait-ce qu'une boucle, tentons quand même...
On va supposer que ton programme et tes fichiers sont dans le même répertoire, ce qui est pas très propre en fait donc si tu veux changer ça dis le moi (en supposant que le programme marche déjà...), c'est du Fortran90
PROGRAM CALCUL_ROMAINGEOL IMPLICIT NONE INTEGER :: UNITE_LECTURE INTEGER :: UNITE_ECRITURE INTEGER :: NOMBRE_FICHIERS CHARACTER*4 :: CHAR_FICH CHARACTER*15 :: NOM_FICHIER INTEGER :: I,J,N_LIGNES REAL*8 :: DUMMY,TESTVAL,TEST REAL*8, POINTER, DIMENSION(:) :: VALEURS UNITE_ECRITURE=67 UNITE_LECTURE=66 WRITE(*,*) 'Nombre de fichiers : ' READ(*,*) NOMBRE_FICHIERS OPEN(UNIT=UNITE_ECRITURE,FILE='Valeurs_Max.dat',& & STATUS='unknown',ACTION='write') DO I=1,NOMBRE_FICHIERS WRITE(CHAR_FICH,'(I4)') I NOM_FICHIER='fichier'//TRIM(CHAR_FICH)//'.out' OPEN(UNIT=UNITE_LECTURE,FILE=TRIM(NOM_FICHIER),& & STATUS='old',ACTION='read') !! PREMIER PASSAGE POUR COMPTER LE NOMBRE DE LIGNES DU FICHIER !! !! ET ENSUITE ALLOUER VALEURS !! N_LIGNES = 0 DO WHILE (0 < 1) READ(UNITE_LECTURE,*,ERR=125,END=123) DUMMY N_LIGNES = N_LIGNES+1 END DO 123 CONTINUE REWIND(UNITE_LECTURE) ALLOCATE(VALEURS(N_LIGNES)) DO J=1,N_LIGNES READ(UNITE_LECTURE,*,ERR=125,END=125) VALEURS(J) END DO TEST=360-(VALEURS(1)-VALEURS(N_LIGNES)) DO J=1,N_LIGNES-1 TESTVAL=VALEURS(J+1)-VALEURS(J) IF (TESTVAL > TEST) THEN TEST=TESTVAL END IF END DO DEALLOCATE(VALEURS) WRITE(UNITE_ECRITURE,*) TRIM(NOM_FICHIER)//' ', TEST CLOSE(UNITE_LECTURE) END DO CLOSE(UNITE_ECRITURE) RETURN 125 CONTINUE WRITE(*,*) 'Erreur' STOP
Pas sûr que ça marche... je l'ai même pas testé.
Dis-moi quand même.
Ok, Merci!
il y avait quelques anomalie dans les noms de variables mais le programme marche pour l'exemple que je t'ai donné.
Le problème c'est que les fichier .out ont des noms totalement aléatoires:
exemple 990710_101010.out
Seul la longueur des noms de fichiers est constante.
PROGRAM CALCUL_ROMAINGEOL
IMPLICIT NONE
INTEGER :: UNITE_LECTURE
INTEGER :: UNITE_ECRITURE
INTEGER :: NOMBRE_FICHIERS
CHARACTER*4 :: CHAR_FICH
CHARACTER*15 :: NOM_FICHIER_INPUT
CHARACTER*15 :: NOM_FICHIER_RESULTAT
INTEGER :: I,J,N_LIGNES
REAL*8 :: DUMMY,TESTVAL,TEST
REAL*8, POINTER, DIMENSION(:) :: VALEURS
UNITE_ECRITURE=67
UNITE_LECTURE=66
WRITE(*,*) 'Nombre de fichiers : '
READ(*,*) NOMBRE_FICHIERS
OPEN(UNIT=UNITE_ECRITURE,FILE='Valeurs_Max.dat', STATUS='unknown',ACTION='write')
DO I=1,NOMBRE_FICHIERS
WRITE(CHAR_FICH,'(I1)') I
NOM_FICHIER_INPUT='fichier'//TRIM(CHAR_FICH)//'.out'
WRITE(*,*) NOM_FICHIER_INPUT
OPEN(UNIT=UNITE_LECTURE,FILE=NOM_FICHIER_INPUT, STATUS='old',ACTION='read')
!! PREMIER PASSAGE POUR COMPTER LE NOMBRE DE LIGNES DU FICHIER !!
!! ET ENSUITE ALLOUER VALEURS !!
N_LIGNES = 0
DO WHILE (0 < 1)
READ(UNITE_LECTURE,*,ERR=125,END=123) DUMMY
N_LIGNES = N_LIGNES+1
END DO
123 CONTINUE
REWIND(UNITE_LECTURE)
ALLOCATE(VALEURS(N_LIGNES))
DO J=1,N_LIGNES
READ(UNITE_LECTURE,*,ERR=125,END=125) VALEURS(J)
END DO
TEST=360-(VALEURS(1)-VALEURS(N_LIGNES))
DO J=1,N_LIGNES-1
TESTVAL=VALEURS(J+1)-VALEURS(J)
IF (TESTVAL > TEST) THEN
TEST=TESTVAL
END IF
END DO
DEALLOCATE(VALEURS)
WRITE(UNITE_ECRITURE,*) TRIM(NOM_FICHIER_INPUT)//' ', TEST
CLOSE(UNITE_LECTURE)
END DO
CLOSE(UNITE_ECRITURE)
RETURN
125 CONTINUE
WRITE(*,*) 'Erreur'
STOP
END
il y avait quelques anomalie dans les noms de variables mais le programme marche pour l'exemple que je t'ai donné.
Le problème c'est que les fichier .out ont des noms totalement aléatoires:
exemple 990710_101010.out
Seul la longueur des noms de fichiers est constante.
PROGRAM CALCUL_ROMAINGEOL
IMPLICIT NONE
INTEGER :: UNITE_LECTURE
INTEGER :: UNITE_ECRITURE
INTEGER :: NOMBRE_FICHIERS
CHARACTER*4 :: CHAR_FICH
CHARACTER*15 :: NOM_FICHIER_INPUT
CHARACTER*15 :: NOM_FICHIER_RESULTAT
INTEGER :: I,J,N_LIGNES
REAL*8 :: DUMMY,TESTVAL,TEST
REAL*8, POINTER, DIMENSION(:) :: VALEURS
UNITE_ECRITURE=67
UNITE_LECTURE=66
WRITE(*,*) 'Nombre de fichiers : '
READ(*,*) NOMBRE_FICHIERS
OPEN(UNIT=UNITE_ECRITURE,FILE='Valeurs_Max.dat', STATUS='unknown',ACTION='write')
DO I=1,NOMBRE_FICHIERS
WRITE(CHAR_FICH,'(I1)') I
NOM_FICHIER_INPUT='fichier'//TRIM(CHAR_FICH)//'.out'
WRITE(*,*) NOM_FICHIER_INPUT
OPEN(UNIT=UNITE_LECTURE,FILE=NOM_FICHIER_INPUT, STATUS='old',ACTION='read')
!! PREMIER PASSAGE POUR COMPTER LE NOMBRE DE LIGNES DU FICHIER !!
!! ET ENSUITE ALLOUER VALEURS !!
N_LIGNES = 0
DO WHILE (0 < 1)
READ(UNITE_LECTURE,*,ERR=125,END=123) DUMMY
N_LIGNES = N_LIGNES+1
END DO
123 CONTINUE
REWIND(UNITE_LECTURE)
ALLOCATE(VALEURS(N_LIGNES))
DO J=1,N_LIGNES
READ(UNITE_LECTURE,*,ERR=125,END=125) VALEURS(J)
END DO
TEST=360-(VALEURS(1)-VALEURS(N_LIGNES))
DO J=1,N_LIGNES-1
TESTVAL=VALEURS(J+1)-VALEURS(J)
IF (TESTVAL > TEST) THEN
TEST=TESTVAL
END IF
END DO
DEALLOCATE(VALEURS)
WRITE(UNITE_ECRITURE,*) TRIM(NOM_FICHIER_INPUT)//' ', TEST
CLOSE(UNITE_LECTURE)
END DO
CLOSE(UNITE_ECRITURE)
RETURN
125 CONTINUE
WRITE(*,*) 'Erreur'
STOP
END
Salut romaingeol
En Fortran je vois pas comment on peut faire ce que tu veux, il y a peut-être un moyen d'ouvrir un par un tous les fichiers d'un répertoire mais je le connais pas.
La seule solution que je peux te donner (avec ce que je connais) c'est de créer au départ un fichier avec tous les noms de tes fichier.out
Dans ce cas ce serait mieux de réorganiser un peu le code.
Voilà ce que je te suggèrerais:
Appelons TRAVAIL le répertoire où sera ton code et tes fichiers de données.
Dans TRAVAIL tu mettras ton code.
Dans le répertoire TRAVAIL tu crées un sous-dossier que t'appelles par exemple DATA
et dans lequel tu mets tous tes fichier.out
D'après ton premier message t'es sous Windows (du moins pour ton message dans le forum)... Donc tu ouvres une fenêtre de commande (Windows+R -> cmd -> OK), tu te places dans TRAVAIL/DATA et tapes dir /A:A /B > ../data_files.dat (si t'es sous Unix ou Linux tu tapes ls > ../data_files.dat), ça te créera un fichier data_files.dat avec le nom de tous tes fichiers de données dans le répertoire TRAVAIL
Ensuite pour le code je ferais ça:
Pour les tableaux de caractères, je sais plus si c'est possible en Fortran et si c'est le cas je sais pas si ma syntaxe est bonne, tu me diras...
Après tu peux aussi créer un exécutable qui te fasse tout (lister les fichiers et exécuter le code Fortran). C'est tout con mais je sais même pas faire un truc aussi simple sous Windows. Donc au cas où t'aurais aussi un Unix ou Linux voilà ce que tu peux faire :
Tu crées un fichier merged_code dans le répertoire TRAVAIL dans lequel il y aura :
Tu oublies pas de faire un chmod +x merged_code et normalement en lançant merged_code ça devrait rouler (enfin je crois...).
En Fortran je vois pas comment on peut faire ce que tu veux, il y a peut-être un moyen d'ouvrir un par un tous les fichiers d'un répertoire mais je le connais pas.
La seule solution que je peux te donner (avec ce que je connais) c'est de créer au départ un fichier avec tous les noms de tes fichier.out
Dans ce cas ce serait mieux de réorganiser un peu le code.
Voilà ce que je te suggèrerais:
Appelons TRAVAIL le répertoire où sera ton code et tes fichiers de données.
Dans TRAVAIL tu mettras ton code.
Dans le répertoire TRAVAIL tu crées un sous-dossier que t'appelles par exemple DATA
et dans lequel tu mets tous tes fichier.out
D'après ton premier message t'es sous Windows (du moins pour ton message dans le forum)... Donc tu ouvres une fenêtre de commande (Windows+R -> cmd -> OK), tu te places dans TRAVAIL/DATA et tapes dir /A:A /B > ../data_files.dat (si t'es sous Unix ou Linux tu tapes ls > ../data_files.dat), ça te créera un fichier data_files.dat avec le nom de tous tes fichiers de données dans le répertoire TRAVAIL
Ensuite pour le code je ferais ça:
PROGRAM CALCUL_ROMAINGEOL IMPLICIT NONE INTEGER :: UNITE_LECTURE INTEGER :: UNITE_ECRITURE CHARACTER*17, POINTER, DIMENSION(:) :: NOM_FICHIER_INPUT CHARACTER*17 :: DUMMY_CHAR CHARACTER*22 :: FICHIER_TEMP INTEGER :: I,J,N_FICHIERS,N_LIGNES REAL*8 :: DUMMY,TESTVAL,TEST REAL*8, POINTER, DIMENSION(:) :: VALEURS UNITE_ECRITURE=67 UNITE_LECTURE=66 OPEN(UNIT=UNITE_LECTURE,FILE='data_files.dat', STATUS='old',ACTION='read') !! PREMIER PASSAGE POUR COMPTER LE NOMBRE DE LIGNES DU FICHIER !! !! ET ENSUITE ALLOUER NOM_FICHIER_INPUT !! N_FICHIERS = 0 DO WHILE (0 < 1) READ(UNITE_LECTURE,*,ERR=125,END=121) DUMMY_CHAR N_FICHIERS = N_FICHIERS+1 END DO 121 CONTINUE REWIND(UNITE_LECTURE) ALLOCATE(NOM_FICHIER_INPUT(N_FICHIERS)) DO I=1,N_FICHIERS READ(UNITE_LECTURE,*,ERR=125,END=125) NOM_FICHIER_INPUT(J) END DO CLOSE(UNITE_LECTURE) OPEN(UNIT=UNITE_ECRITURE,FILE='Valeurs_Max.dat', STATUS='unknown',ACTION='write') DO I=1,N_FICHIERS FICHIER_TEMP='DATA/'//NOM_FICHIER_INPUT(I) OPEN(UNIT=UNITE_LECTURE,FILE=TRIM(FICHIER_TEMP), STATUS='old',ACTION='read') !! PREMIER PASSAGE POUR COMPTER LE NOMBRE DE LIGNES DU FICHIER !! !! ET ENSUITE ALLOUER VALEURS !! N_LIGNES = 0 DO WHILE (0 < 1) READ(UNITE_LECTURE,*,ERR=125,END=123) DUMMY N_LIGNES = N_LIGNES+1 END DO 123 CONTINUE REWIND(UNITE_LECTURE) ALLOCATE(VALEURS(N_LIGNES)) DO J=1,N_LIGNES READ(UNITE_LECTURE,*,ERR=125,END=125) VALEURS(J) END DO TEST=360-(VALEURS(1)-VALEURS(N_LIGNES)) DO J=1,N_LIGNES-1 TESTVAL=VALEURS(J+1)-VALEURS(J) IF (TESTVAL > TEST) THEN TEST=TESTVAL END IF END DO DEALLOCATE(VALEURS) WRITE(UNITE_ECRITURE,*) TRIM(NOM_FICHIER_INPUT(I))//' ', TEST CLOSE(UNITE_LECTURE) END DO DEALLOCATE(NOM_FICHIER_INPUT) CLOSE(UNITE_ECRITURE) RETURN 125 CONTINUE WRITE(*,*) 'Erreur' STOP END
Pour les tableaux de caractères, je sais plus si c'est possible en Fortran et si c'est le cas je sais pas si ma syntaxe est bonne, tu me diras...
Après tu peux aussi créer un exécutable qui te fasse tout (lister les fichiers et exécuter le code Fortran). C'est tout con mais je sais même pas faire un truc aussi simple sous Windows. Donc au cas où t'aurais aussi un Unix ou Linux voilà ce que tu peux faire :
Tu crées un fichier merged_code dans le répertoire TRAVAIL dans lequel il y aura :
#!/bin/sh cd DATA ls > ../data_files.dat cd .. nom_de_l'exécutable_fortran
Tu oublies pas de faire un chmod +x merged_code et normalement en lançant merged_code ça devrait rouler (enfin je crois...).
Ah mais c'est tout facile!!! (merci Davide...)
C'est tout pareil sous Windows pour le dernier truc que je t'ai écrit (ou presque), tu tapes ça :
Et tu l'enregistres en merged_code.bat et ça suffit, il y a rien d'autre à faire.
Mais là en fait j'ai surtout l'impression d'écrire dans le vide... T'es toujours là romaingeol?
Allô! McFly? Y'a personne au bout du fil?
C'est tout pareil sous Windows pour le dernier truc que je t'ai écrit (ou presque), tu tapes ça :
cd DATA dir /A:A /B > ../data_files.dat cd .. nom_de_l'exécutable_fortran
Et tu l'enregistres en merged_code.bat et ça suffit, il y a rien d'autre à faire.
Mais là en fait j'ai surtout l'impression d'écrire dans le vide... T'es toujours là romaingeol?
Allô! McFly? Y'a personne au bout du fil?
Oui désolé, je suis là
Merci beaucoup, j'étais arrivé aux m^mes conclusions.
Le programme tourne et ça m'a permis de bien révisé mon fortran
encore merci
Merci beaucoup, j'étais arrivé aux m^mes conclusions.
Le programme tourne et ça m'a permis de bien révisé mon fortran
encore merci
Parce que romaingeol parlait de Fortran ou de C dans son premier message.
C'est vrai que je me suis pas posé la question de savoir si ça ce faisait facilement avec autre chose, je lui ai donné une méthode avec ce que je savais faire, c'est probablement pas la meilleure, mais elle avait l'air de marcher.
Mais toutes les solutions sont les bienvenues _vince!!! Si t'as un truc tu peux l'écrire, romaingeol choisira la solution qui lui convient le mieux.
Et de rien... content que ça marche romaingeol!!!
A plus et bonne journée à vous deux.
C'est vrai que je me suis pas posé la question de savoir si ça ce faisait facilement avec autre chose, je lui ai donné une méthode avec ce que je savais faire, c'est probablement pas la meilleure, mais elle avait l'air de marcher.
Mais toutes les solutions sont les bienvenues _vince!!! Si t'as un truc tu peux l'écrire, romaingeol choisira la solution qui lui convient le mieux.
Et de rien... content que ça marche romaingeol!!!
A plus et bonne journée à vous deux.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Finalement, j'ai trouve une solution qui vaut ce qui vaut. Je n'ai pas verifie les resultats.
En rajoutant une balise "fin" a la fin de chaque fichier, ca me donne un scripte du genre:
BEGIN {
# tous les fichiers en entree doivent avoir "fin" sur la derniere ligne
# 1 correspond a la premiere ligne, 2 a la deuxieme, 3 aux lignes suivantes
flag = 1;
# valeur interdite
DUMMY = -666;
# contient X(N-1)
derniere = DUMMY;
# contient X(N-2)
avantderniere = DUMMY;
# contient X(1)
premiere = DUMMY
LOGFILE = "file.out"
print "" > LOGFILE
}
3 == flag && $1 !~ /fin/ && derniere != DUMMY && avantderniere != DUMMY {
## de la ligne N = 3 jusque (N_MAX - 1),
## ret = X(N-1) - X(N-2)
ret = derniere - avantderniere;
if (ret_max < ret) {
ret_max = ret;
}
# on decale
avantderniere = derniere
derniere = $1;
}
2 == flag && $1 !~ /fin/ && derniere == DUMMY && avantderniere != DUMMY {
## deuxieme ligne du fichier, N = 2
## on ne calcule toujours rien
derniere = $1;
flag = 3;
## premiere valeur "par defaut" de ret_max
ret_max = derniere - avantderniere;
}
1 == flag && $1 !~ /fin/ && premiere == DUMMY && avantderniere == DUMMY && derniere == DUMMY {
## premiere ligne du fichier, N = 1
## on calcule rien
flag = 2;
avantderniere = $1;
premiere = $1;
}
/fin/ && derniere != DUMMY && premiere != DUMMY {
## derniere ligne du fichier (N_MAX)
flag = 1;
ret = 360 - (premiere - derniere);
if (ret_max < ret) {
ret_max = ret;
}
print FILENAME "\t" ret_max >> LOGFILE;
## par securite
derniere = DUMMY;
avantderniere = DUMMY;
premiere = DUMMY;
}
###########
Il faut ensuite executer le script comme ca:
awk -f test.awk file*.in
Il y a avait plus simple en mettant le script dans un shell pour compter le nombre de lignes du fichier pour le passer en variable au script awk. On doit pouvoir aussi faire plus simple en perl, en lisant chaque, puis en mettant les valeurs dans un tableau... mais j'arrete la pour les exercices intellectuels ;-)
En rajoutant une balise "fin" a la fin de chaque fichier, ca me donne un scripte du genre:
BEGIN {
# tous les fichiers en entree doivent avoir "fin" sur la derniere ligne
# 1 correspond a la premiere ligne, 2 a la deuxieme, 3 aux lignes suivantes
flag = 1;
# valeur interdite
DUMMY = -666;
# contient X(N-1)
derniere = DUMMY;
# contient X(N-2)
avantderniere = DUMMY;
# contient X(1)
premiere = DUMMY
LOGFILE = "file.out"
print "" > LOGFILE
}
3 == flag && $1 !~ /fin/ && derniere != DUMMY && avantderniere != DUMMY {
## de la ligne N = 3 jusque (N_MAX - 1),
## ret = X(N-1) - X(N-2)
ret = derniere - avantderniere;
if (ret_max < ret) {
ret_max = ret;
}
# on decale
avantderniere = derniere
derniere = $1;
}
2 == flag && $1 !~ /fin/ && derniere == DUMMY && avantderniere != DUMMY {
## deuxieme ligne du fichier, N = 2
## on ne calcule toujours rien
derniere = $1;
flag = 3;
## premiere valeur "par defaut" de ret_max
ret_max = derniere - avantderniere;
}
1 == flag && $1 !~ /fin/ && premiere == DUMMY && avantderniere == DUMMY && derniere == DUMMY {
## premiere ligne du fichier, N = 1
## on calcule rien
flag = 2;
avantderniere = $1;
premiere = $1;
}
/fin/ && derniere != DUMMY && premiere != DUMMY {
## derniere ligne du fichier (N_MAX)
flag = 1;
ret = 360 - (premiere - derniere);
if (ret_max < ret) {
ret_max = ret;
}
print FILENAME "\t" ret_max >> LOGFILE;
## par securite
derniere = DUMMY;
avantderniere = DUMMY;
premiere = DUMMY;
}
###########
Il faut ensuite executer le script comme ca:
awk -f test.awk file*.in
Il y a avait plus simple en mettant le script dans un shell pour compter le nombre de lignes du fichier pour le passer en variable au script awk. On doit pouvoir aussi faire plus simple en perl, en lisant chaque, puis en mettant les valeurs dans un tableau... mais j'arrete la pour les exercices intellectuels ;-)