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

Python Discussion :

Modif valeurs dans certaines lignes


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Points : 5
    Points
    5
    Par défaut Modif valeurs dans certaines lignes
    Suite à mon post précédent qui fonctionne, j'ouvre un post pour un autre pour un autre problème.
    J'ai reçu la façon de recalculer les valeurs des Bend qui se trouve un fichier du style
    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
    /SPOOL
    SPOOL-ID            1
    SPOOL-PREFIX        QI-50080
    START               0.0      0.0      0.0      0.0      0.0
    FINISH              0.0      0.0    217.3      0.0      0.0
    ND                       25                                                     
    OD                       0.000
    WALL-THICKNESS           0.000
    START               0.0      0.0      0.0      0.0      0.0
    BEND1             360.0      0.0      0.0    120.0     45.0
    BEND2             656.2   -296.1      0.0    120.0     45.0
    BEND3            1129.7   -296.1      0.0    120.0     90.0
    FINISH           1129.7   -741.1      0.0      0.0      0.0
    ND                       40                                                     
    OD                       0.000
    WALL-THICKNESS           0.000
    /END-SPOOL
    C'est cette partie qu'il rechercher et modifier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    START               0.0      0.0      0.0      0.0      0.0
    BEND1             360.0      0.0      0.0    120.0     45.0
    BEND2             656.2   -296.1      0.0    120.0     45.0
    BEND3            1129.7   -296.1      0.0    120.0     90.0
    Je prend BEND1 et sa première valeur qui est 360.
    La valeur qui remplacera 360 est 360 - 0 (qui est la valeur de la ligne précédente) = 360.

    Je prends BEND2 et sa première valeur qui est 656,2.
    La valeur qui remplacera 656,2 est 656,2 - 360 = 296,2

    Et ainsi de suite. Sur les trois lignes BEND et sur les 3 première colonnes.
    Mais il se peut que l'on trouve que 1 ou 2 BEND.

    Ca se complique sérieux.
    Merci

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Points : 290
    Points
    290
    Par défaut
    bonjour,
    ça se fait bien avec une petite expression régulière et des boucles.
    Je me suis amusé à le coder:
    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
     
    import re
    file = open("file.txt")
    listInfo = []
     
    #l'expression reguliere
    exp = re.compile(r'^(\S*)\s*(\S*)\s*(\S*)\s*(\S*).*$')
     
    #parse le fichier et recupere les infos dans une liste 
    for line in file:
    	p = exp.search(line)
    	info = p.groups()
    	if info[0] == "START" or info[0][:4] == "BEND":
    		listInfo.append(list(info))
     
    #supprime le 1er START qui n'a pas l'air de te servir
    listInfo = listInfo[1:]
    #Creation de la liste ou seront stoquer les modification
    listModif = [[0]*4 for i in range(len(listInfo))]
     
    #copie la 1ere ligne (START), qui n'a pas de modification
    listModif[0] = listInfo[0]
    #boucle les lignes
    for i, info in enumerate(listInfo[1:]):
    	#recopie les noms (START, BEND1...)
    	listModif[i+1][0] = info[0]
    	#boucle les chiffres
    	for j in range(1,4):
    		#le chiffre precedant
    		nbrPrec = listInfo[i][j]
    		#le chiffre en cours
    		nbr = info[j]
    		#ajoute et stoque les 2 chiffres
    		listModif[i+1][j] = nbr + " - " + nbrPrec
     
     
    #et voila le tour est joue
    for a in listModif:
    	print a

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Points : 5
    Points
    5
    Par défaut
    Merci nyko77
    Mais je ne veux pas le calcul, juste le résultat. J'ai donc fait la modif.
    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
     
    listInfo = []
     
    #l'expression reguliere
    exp = re.compile(r'^(\S*)\s*(\S*)\s*(\S*)\s*(\S*).*$')
     
    #parse le fichier et recupere les infos dans une liste 
    for line in file:
    	p = exp.search(line)
    	info = p.groups()
    	if info[0] == "START" or info[0][:4] == "BEND" or info[0][:6] == "FINISH" :
    		listInfo.append(list(info))
     
    #supprime le 1er START qui n'a pas l'air de te servir
    listInfo = listInfo[1:]
    #Creation de la liste ou seront stoquer les modification
    listModif = [[0]*4 for i in range(len(listInfo))]
     
    #copie la 1ere ligne (START), qui n'a pas de modification
    listModif[0] = listInfo[0]
    #boucle les lignes
    for i, info in enumerate(listInfo[1:]):
    	#recopie les noms (START, BEND1...)
    	listModif[i+1][0] = info[0]
    	#boucle les chiffres
    	for j in range(1,4):
    		#le chiffre precedant
    		nbrPrec = listInfo[i][j]
    		#le chiffre en cours
    		nbr = info[j]
    		#ajoute et stoque les 2 chiffres
    		tot = float(nbr) - float(nbrPrec)
    		listModif[i+1][j] = tot
    		#listModif[i+1][j] = nbr + " - " + nbrPrec
     
     
    #et voila le tour est joue
    for a in listModif:
    	print a
    Et maintenant il faut remplacer ces valeurs à la bonne place dans le fichier

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Points : 290
    Points
    290
    Par défaut
    Et maintenant il faut remplacer ces valeurs à la bonne place dans le fichier
    A ok, j'avais mal lu ton poste, je pensais que tu voulais uniquement récupérer les lignes modifiées.
    Du coup c'est plus simple, il suffit de recopié les lignes dans un nouveau fichier et les modifier si besoin.
    J'ai changer le re.compile par re.split (son existence m'était sortie de l'espris).
    Avec ce code les chiffres ne sont plus alignés, mais je ne pense pas que cela pose un problème, ça doit pouvoir se gérer le cas échéant.

    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
     
    import re
     
    file = open("file.txt")
    fileModif = open("fileModif.txt", "w")
     
    #boucle les lignes
    for line in file:
    	#split la ligne en enlevant les espaces
    	info = re.split("\s*", line)
    	#si le nom est START, stoque les valeurs pour pouvoir les soustraire
    	if info[0] == "START":
    		infoPrec = info
    	#si le nopm commence par BEND, modifie la ligne
    	elif info[0][:4] == "BEND":
    		#boucle les 3 chiffres
    		for i in range(1,4):
    			#la nouvelle valeur
    			newVal = str(float(info[i]) - float(infoPrec[i]))
    			#remplace l'ancienne valeur par la nouvelle
    			line = line.replace(info[i], newVal, 1)
    		#stoque les valeurs pour le prochain BEND
    		infoPrec = info
     
    	#ecrit la ligne dans le fichier
    	fileModif.write(line)	
     
    file.close()
    fileModif.close()

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Points : 5
    Points
    5
    Par défaut
    Super.
    J'avais commencer quelques choses avec un nouveau fichier aussi en insérant des \t dans le résultat du calcul.
    Petite question : C'est toutes les lignes qui sont recopiées ou juste celles modifiées ? Je pense que oui vu que write est dans le for ??
    Il faut toutes les lignes y compris celles modifiées..

    Je vais tester ça.

    Merci à toi maître

  6. #6
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Désolé, je n’ai pas pu revenir sur cette file avant.

    Voici ma proposition.

    J’ai fait en sorte qu’il n’y ait pas trop de recherche par expression régulière. Dans un premier code, j’avais 4 expressions régulières, mais les nombres dans les lignes START, BEND et FINISH peuvent être attrapés par line[14:].split().



    L’itération
    for id,prefix,portion in (m.groups() for m in patSpool.finditer(ch)):
    découpe des portions de fichier situées entre les lignes SPOOL-PREFIX et /END-SPOOL (non comprises),
    tout en récupérant les valeurs des lignes SPOOL-ID et SPOOL-PREFIX.



    Pour chaque portion,

    - L’itération
    for line in ( m.group() for m in patLigne.finditer(portion)):
    ne débite que des lignes qui nous intéressent, c’est à dire celles dont l’en-tête est listé dans le tuple agarder.

    - Un nom de fichier est créé. J’ai choisi un nom id + '^' + prefix avec le caractère ’^’ mais on peut faire ce qu’on veut avec id et prefix.

    - La portion est mise dans une chaîne chout, dans laquelle les lignes BEND ont été transformées.

    - chout est enregistrée dans un fichier propre à la portion


    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
    with open('piktux.txt', 'r') as f:
        ch = f.read()
     
    import re
     
    patSpool = re.compile('/SPOOL\r?\nSPOOL-ID\s+(\d+)\r?\nSPOOL-PREFIX\s+(.+?)\r?\n'
                          '(.+?)/END-SPOOL',re.DOTALL)
     
    agarder = ('^ND {23}', '^OD {23}', '^WALL-THICKNESS {11}',
               '^START {9}','^BEND[\d ]{10}','^FINISH {8}')
    # dans agarder: en-têtes précis des lignes à garder
    patLigne = re.compile( '(' + '|'.join( ag+'.+\n' for ag in agarder ) + ')',re.MULTILINE )
     
    for id,prefix,portion in (m.groups() for m in patSpool.finditer(ch)):
        # on crée le nom du fichier qui va recevoir le contenu de cette portion               
        out_name = id + '^' + prefix + '.txt'
     
        # on crée la sélection de lignes de cette portion qui va être enregistrée
        chout = ''
        for line in ( m.group() for m in patLigne.finditer(portion)):
            if line[0:5] ==  'START':   # ligne START
                L = [line[14:].split()]       # on met les nombres dans une liste L recréée
                chout += line                 # et on enregistre la ligne START dans chout
            elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                L.append(line[14:].split())   # on ajoute seulement la ligne à L        
            elif line[0:6]=='FINISH':   # ligne FINISH
                # on va faire les calculs sur les lignes BEND et FINISH avant d'enregistrer
                L.append(line[14:].split())   # ajout nécessaire de la denière ligne à L
                for i in xrange(1,len(L)-1):  # calculs et enregistrement dans chout des lignes BEND
                    li = [str(float(L[i][k])-float(L[i-1][k])) for k in xrange(5)]
                    chout += ('BEND' + str(i)).ljust(14)\
                             + ''.join(x.rjust(9) for x in li) + '\n'
                chout += 'FINISH        ' + ''.join(x.rjust(9) for x in L[-1]) + '\n' # ajout de FINISH
            else:
                chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
        # on enregistre la portion traitée dans un fichier de nom out_name
        with open(out_name, 'w') as g:
            g.write(chout)

  7. #7
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    1 )

    Le code de mon précédent message comporte une erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for i in xrange(1,len(L)-1): # calculs et enregistrement dans chout des lignes BEND
    li = [str(float(L[i][k])-float(L[i-1][k])) for k in xrange(5)]
    chout += ('BEND' + str(i)).ljust(14)\
    + ''.join(x.rjust(9) for x in li) + '\n'
    fait les soustractions jusqu’à la dernière ligne BEND, mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chout += 'FINISH ' + ''.join(x.rjust(9) for x in L[-1]) + '\n'
    ne fait pas la soustraction nécessaire.

    Il faut mettre à la place
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    chout += 'FINISH '\
    + ''.join(str(float(L[-1][k])-float(L[-2][k])).rjust(9)
    for k in xrange(5)) + '\n' # ajout de FINISH
    Ces calculs sont quand même bien rébarbatifs.





    2 )

    J’ai regardé ton code, nyko.
    Désolé, mais il ne suffit pas:

    - il ne sélectionne pas les lignes

    - les lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    START 0.0 0.0 0.0 0.0 0.0
    BEND1 360.0 0.0 0.0 120.0 45.0
    BEND2 656.2 -296.1 0.0 120.0 45.0
    BEND3 1129.7 -296.1 0.0 120.0 90.0
    FINISH 1129.7 -741.1 0.0 0.0 0.0
    sont transformées en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    START 0.0 0.0 0.0 0.0 0.0
    BEND1 360.0 0.0 0.0 120.0 45.0
    BEND2 296.2 -296.1 0.0 120.0 45.0
    BEND3 473.5 0.0 0.0 120.0 90.0
    FINISH 1129.7 -741.1 0.0 0.0 0.0
    alors qu’il faudrait obtenir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    START 0.0 0.0 0.0 0.0 0.0
    BEND1 360.0 0.0 0.0 120.0 45.0
    BEND2 296.2 -296.1 0.0 0.0 0.0
    BEND3 473.5 0.0 0.0 0.0 45.0
    FINISH 0.0 -445.0 0.0 -120.0 -90.0
    - il ne crée pas deux fichiers récepteurs mais un seul

    Ça explique pourquoi le mien met deux fois plus de temps à tourner.




    3 )

    Mais ton idée de travailler avec infoPrec et faire les calculs pour chaque ligne, au lieu de reporter les calculs après avoir parcouru toutes les lignes BEND comme je le fais dans mon code, est bonne.

    Je l’ai donc reprise et ça a donné le code 2 dans celui que je poste ci-dessous.

    Ça n’a pas apporté une baisse notable du temps d’exécution: seulement 2,6 % de baisse.



    Je me suis dit qu’au lieu de créer des listes L de nombres sous forme de chaînes, il serait peut être plus rapide de créer des listes L de floats directement, avec L = map(float,line[14:].split())

    Mais l’amélioration est insignifiante, sinon nulle.







    Alors j’ai pensé à tester un code sans utilisation d’expressions régulières, mais procédant uniquement par itération for line in f: et traitement des lignes tout de suite (code 4).

    Surprise: diminution du temps d’exécution de 34 % par rapport à mon premier code du message précédent.



    Si on crée des L = listes de floats par map(), la diminution est 37 %.



    Ces résultats sont issus de 100 exécutions de chaque code. Et ces 100 exécutions répétées 203 fois pour trouver le temps le plus petit possible pour chaque code i.





    Je pensais que l’utilisation d’expressions régulières serait plus rapide qu’une itération sur les lignes.
    J’avais tort. Avantage nyko.


    En comparant les codes par rapport au plus rapide, ça donne:

    code 1: 159 %
    code 2: 155 %
    code 3: 155 %
    code 4: 105 %
    code 5: référence



    Je donne le code tel quel, qui permet de faire les comparaisons, si ça amuse quelqu’un de vérifier les temps et surtout la sélection et la transformation correcte de lignes.

    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    from time import clock
    import re
     
    repet = 100
    A,B,C,D,E = [],[],[],[],[]
    for wq in xrange(203):
        print '* ',
     
     
        ### Code 1 = du precedent message
        #================================
        # 2 expressions regulieres, L = liste de listes de nombres sous forme de chaine
        # modification de L en entier avant enregistrement des lignes BEND
     
        te = clock()
     
        with open('piktux.txt','r') as f:
            ch = f.read()
     
        for y in xrange(100):
     
            patSpool = re.compile('/SPOOL\r?\nSPOOL-ID\s+(\d+)\r?\nSPOOL-PREFIX\s+(.+?)\r?\n'
                                  '(.+?)/END-SPOOL',re.DOTALL)
     
            agarder = ('^ND {23}', '^OD {23}', '^WALL-THICKNESS {11}',
                       '^START {9}','^BEND[\d ]{10}','^FINISH {8}')
            # dans agarder: en-têtes précis des lignes à garder
            patLigne = re.compile( '(' + '|'.join( ag+'.+\n' for ag in agarder ) + ')',re.MULTILINE )
     
            for id,prefix,portion in (m.groups() for m in patSpool.finditer(ch)):
                # on crée le nom du fichier qui va recevoir le contenu de cette portion               
                out_name = id + '^' + prefix + '.txt'
     
                # on crée la sélection de lignes de cette portion qui va être enregistrée
                chout = ''
                for line in ( m.group() for m in patLigne.finditer(portion)):
                    if line[0:5] ==  'START':   # ligne START
                        L = [line[14:].split()]       # on met les nombres dans une liste L recréée
                        chout += line                 # et on enregistre la ligne START dans chout
                    elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                        L.append(line[14:].split())   # on ajoute seulement la ligne à L        
                    elif line[0:6]=='FINISH':   # ligne FINISH
                        # on va faire les calculs sur les lignes BEND et FINISH avant d'enregistrer
                        L.append(line[14:].split())   # ajout nécessaire de la denière ligne à L
                        for i in xrange(1,len(L)-1):  # calculs et enregistrement dans chout des lignes BEND
                            li = [str(float(L[i][k])-float(L[i-1][k])) for k in xrange(5)]
                            chout += ('BEND' + str(i)).ljust(14)\
                                     + ''.join(x.rjust(9) for x in li) + '\n'
                        chout += 'FINISH        '\
                                 + ''.join(str(float(L[-1][k])-float(L[-2][k])).rjust(9)
                                           for k in xrange(5)) + '\n' # ajout de FINISH
                    else:
                        chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
                # on enregistre la portion traitée dans un fichier de nom out_name
     
     
     
        tf = clock()
        A.append(tf-te)
     
     
     
        ###  Code 2
        #==========
        # 2 expressions regulieres, L = liste de nombres sous forme de chaine
        # enregistrement des lignes BEND au fur et a mesure
     
        te = clock()
     
        for y in xrange(repet):
     
            patSpool = re.compile('/SPOOL\r?\nSPOOL-ID\s+(\d+)\r?\nSPOOL-PREFIX\s+(.+?)\r?\n'
                                  '(.+?)/END-SPOOL',re.DOTALL)
     
            agarder = ('^ND {23}', '^OD {23}', '^WALL-THICKNESS {11}',
                       '^START {9}','^BEND[\d ]{10}','^FINISH {8}')
            # dans agarder: en-têtes précis des lignes à garder
            patLigne = re.compile( '(' + '|'.join( ag+'.+\n' for ag in agarder ) + ')',re.MULTILINE )
     
            for id,prefix,portion in (m.groups() for m in patSpool.finditer(ch)):
                # on crée le nom du fichier qui va recevoir le contenu de cette portion               
                out_name = id + '^' + prefix + '.txt'
     
                # on crée la sélection de lignes de cette portion qui va être enregistrée
                chout = ''
                for line in ( m.group() for m in patLigne.finditer(portion)):
                    if line[0:5] ==  'START':   # ligne START
                        b = 0
                        LP = line[14:].split() # on met les nombres dans une liste L recréée
                        chout += line
                    elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                        b += 1
                        L = line[14:].split()
                        chout += ('BEND' + str(b)).ljust(14)\
                                 + ''.join(str(float(u)-float(LP[i])).rjust(9) for i,u in enumerate(L)) + '\n'
                        LP = L
                    elif line[0:6]=='FINISH':   # ligne FINISH
                        chout += 'FINISH        '\
                                 + ''.join(str(float(x)-float(LP[i])).rjust(9)
                                           for i,x in enumerate(line[14:].split())) + '\n'
                    else:
                        chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
                # on enregistre la portion traitée dans un fichier de nom out_name
                #with open(out_name, 'w') as g:
                    #g.write(chout)
     
        tf = clock()
        B.append(tf-te)
     
     
        #### Code 3
        #==========
        # 2 expressions regulieres, L = liste de floats grace a map()
        # enregistrement des lignes BEND au fur et a mesure
     
        te = clock()
     
        for y in xrange(repet):
     
            patSpool = re.compile('/SPOOL\r?\nSPOOL-ID\s+(\d+)\r?\nSPOOL-PREFIX\s+(.+?)\r?\n'
                                  '(.+?)/END-SPOOL',re.DOTALL)
     
            agarder = ('^ND {23}', '^OD {23}', '^WALL-THICKNESS {11}',
                       '^START {9}','^BEND[\d ]{10}','^FINISH {8}')
            # dans agarder: en-têtes précis des lignes à garder
            patLigne = re.compile( '(' + '|'.join( ag+'.+\n' for ag in agarder ) + ')',re.MULTILINE )
     
            for id,prefix,portion in (m.groups() for m in patSpool.finditer(ch)):
                # on crée le nom du fichier qui va recevoir le contenu de cette portion               
                out_name = id + '^' + prefix + '.txt'
     
                # on crée la sélection de lignes de cette portion qui va être enregistrée
                chout = ''
                for line in ( m.group() for m in patLigne.finditer(portion)):
                    if line[0:5] ==  'START':   # ligne START
                        b = 0
                        LP = map(float,line[14:].split()) # on met les nombres dans une liste L recréée
                        chout += line
                    elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                        b += 1
                        L = map(float,line[14:].split())
                        chout += ('BEND' + str(b)).ljust(14)\
                                 + ''.join(str(u-LP[i]).rjust(9) for i,u in enumerate(L)) + '\n'
                        LP = L
                    elif line[0:6]=='FINISH':   # ligne FINISH
                        chout += 'FINISH        '\
                                 + ''.join(str(x-LP[i]).rjust(9)
                                           for i,x in enumerate(map(float,line[14:].split()))) + '\n'
                    else:
                        chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
                # on enregistre la portion traitée dans un fichier de nom out_name
                #with open(out_name, 'w') as g:
                    #g.write(chout)
     
        tf = clock()
        C.append(tf-te)
     
     
        ### Code 4
        #=========
        # pas d'expressions regulieres, L = liste de nombres sous forme de chaine
     
        del patLigne,patSpool
     
        temps = 0
     
        for y in xrange(repet):
     
            f = open('piktux.txt', 'r')
     
            te = clock()
     
            agarder = ('ND            ', 'OD            ', 'WALL-THICKNESS')
            # dans agarder: en-têtes précis des lignes à garder
     
            for line in f:
                if line[0:9]=='SPOOL-ID ':
                    id = line.split()[1]
                elif line[0:13]=='SPOOL-PREFIX ':
                    out_name = id + '^' + line.split()[1] + '.txt'
                    chout = ''
                # on crée la sélection de lignes de la portion qui va être enregistrée
                elif line[0:6] ==  'START ':   # ligne START
                    b = 0
                    LP = line[14:].split()       # on met les nombres dans une liste L recréée
                    chout += line                 # et on enregistre la ligne START dans chout
                elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                    b += 1
                    L = line[14:].split()
                    chout += ('BEND' + str(b)).ljust(14)\
                                 + ''.join(str(float(u)-float(LP[i])).rjust(9) for i,u in enumerate(L)) + '\n'
                    LP = L
                elif line[0:7]=='FINISH ':   # ligne FINISH
                    chout += 'FINISH        '\
                                 + ''.join(str(float(x)-float(LP[i])).rjust(9)
                                           for i,x in enumerate(line[14:].split())) + '\n'
                elif line[0:10]=='/END-SPOOL':
                    pass
                elif line[0:14] in agarder:
                    chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
            tf = clock()
            f.close()
            temps += tf-te
     
        D.append(temps)
     
        ### Code 5
        #=========
        # pas d'expressions regulieres, L = liste de floats 
     
        temps = 0
     
        for y in xrange(repet):
     
            f = open('piktux.txt', 'r')
     
            te = clock()
     
            agarder = ('ND            ', 'OD            ', 'WALL-THICKNESS')
            # dans agarder: en-têtes précis des lignes à garder
     
            for line in f:
                if line[0:9]=='SPOOL-ID ':
                    id = line.split()[1]
                elif line[0:13]=='SPOOL-PREFIX ':
                    out_name = id + '^' + line.split()[1] + '.txt'
                    chout = ''
                # on crée la sélection de lignes de la portion qui va être enregistrée
                elif line[0:6] ==  'START ':   # ligne START
                    b = 0
                    LP = map(float,line[14:].split())       # on met les nombres dans une liste L recréée
                    chout += line                 # et on enregistre la ligne START dans chout
                elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                    b += 1
                    L = map(float,line[14:].split())
                    chout += ('BEND' + str(b)).ljust(14)\
                                 + ''.join(str(u-LP[i]).rjust(9) for i,u in enumerate(L)) + '\n'
                    LP = L
                elif line[0:7]=='FINISH ':   # ligne FINISH
                    chout += 'FINISH        '\
                                 + ''.join(str(x-LP[i]).rjust(9)
                                           for i,x in enumerate(map(float,line[14:].split()))) + '\n'
                elif line[0:10]=='/END-SPOOL':
                    pass
                elif line[0:14] in agarder:
                    chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
            tf = clock()
            f.close()
            temps += tf-te
     
        E.append(temps)
     
        ############################################################################### 
     
     
    print
    print '==============='
    for v in (A,B,C,D,E):
        print min(v)
     
     
    print '-- Fin du programme --'

  8. #8
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    je participe ^^ :
    le code est un peu caca, il reprend celui que j'ai fait pour ton precedent poste.

    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
    def spool(fichier) :
    	fname = ''
    	out = []
    	bendout = []
    	for l in open(fichier, 'r').readlines() :
    		try : bl = l.split()[0]
    		except : continue
    		if bl in ('/SPOOL', 'ND', 'OD', 'WALL-THICKNESS') : out.append(l)
    		elif bl == 'START' :
    			out.append(l)
    			bendout = l.split()[1:]
    		elif bl.startswith('BEND') or bl == 'FINISH' :
    			out.append(''.join([bl.ljust(14)]+[str(float(i[1])-float(i[0])).rjust(9) for i in zip(bendout,l.split()[1:])])+'\n')
    			bendout = l.split()[1:]
    		elif bl in ('SPOOL-ID', 'SPOOL-PREFIX') :
    			out.append(l)
    			fname = l.split()[1] + fname
    		elif bl == '/END-SPOOL' :
    			out.append(l)
    			with open(fname+'.txt','w') as outfile :
    				outfile.write(''.join(out))
    			fname = ''
    			out = []
    			bendout = []
     
    spool('my_file.txt')

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Points : 5
    Points
    5
    Par défaut
    Merci Niko, josmiley, eyquem
    C'est un vrai cours avec des exemples que vous donnez là.

    J'ai pris le code de Niko qui me conviens bien, j'ai ajouter 2 ou 3 lignes pour l'appliquer à tout un répertoire mais je n'arrive pas créer les fichiers dedans :
    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
     
    # -*- coding: UTF-8 -*-
     
    import os, glob, re, math, sys
    rep_cour = os.getcwd()
     
    # création répertoire pour les fichiers finaux
    if not os.path.exists(rep_cour + "/atraiter/final") :
    	os.mkdir(rep_cour + "/atraiter/final")
     
    # Liste les fichiers dans le répertoire result
     
    for filename in glob.glob(os.path.join(rep_cour,"/atraiter/result/*.txt")) :
    	fich_in = open(filename, 'r')
    	fileModif = open(os.path.join('atraiter/final/',filename), 'w')
     
    	#boucle les lignes
    	for line in fich_in:
    		#split la ligne en enlevant les espaces
    		info = re.split("\s*", line)
    		#si le nom est START, stoque les valeurs pour pouvoir les soustraire
    		if info[0] == "START":
    			infoPrec = info
    		#si le nopm commence par BEND, modifie la ligne
    		elif info[0][:4] == "BEND":
    			#boucle les 3 chiffres
    			for i in range(1,4):
    				#la nouvelle valeur
    				newVal = str(float(info[i]) - float(infoPrec[i]))
    				#remplace l'ancienne valeur par la nouvelle
    				line = line.replace(info[i], newVal, 1)
    			#stoque les valeurs pour le prochain BEND
    			infoPrec = info
     
    		#ecrit la ligne dans le fichier
    		fileModif.write(line)	
     
    	fich_in.close()
    	fileModif.close()

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Points : 5
    Points
    5
    Par défaut
    Bon bin déjà j'ai fait une erreur avec os.path.join. J'au supprimer les / dans cette fonction.
    Mais ça marche toujours pas

    Edit : J'ai chercher un peu et j'ai spliter filename pour n'avoir que le nom du fichier

    Mais maintenant, j'ai bien mes fichiers mais ils sont vident et là, je vois pas pourquoi

    Ca y est cela fonctionne.

    Je dois changer maintenant :
    - supprimer SPOOL-ID et SPOOL-PREFIX et le remplacer par X avec la valeur SPOOL-PREFIX + SPOOL-ID
    - START en PX
    - les BEND 1, 2 ... en PX
    - le FINISH en PX
    - le OD en D
    - le WALL-THICKNESS en W
    - Ajouter R avec la valeur de la quatrième colonne de BEND1

    Après ça j'ai fini mais c'est pour cet aprè-midi alors je vais patauger un peu encore

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Points : 5
    Points
    5
    Par défaut
    Bon voilà.
    J'ai édité le post au dessus. En grsi tout ce qui est fait et rest le dernier point mais qui n'est crucial (dommage quand même)

    J'ai fait avec les moyens du bord. Ca fonctionne comme il me convient et aurait le temps plus tard d'optimiser la chose (après quelques journée python )

    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
     
    if not os.path.exists(rep_cour + "\\atraiter\\pass3") :
    	os.mkdir(rep_cour + "\\atraiter\\pass3")
     
    for filenames in glob.glob(os.path.join(rep_cour,"atraiter\\pass2\\*.txt")) :
    	fich_in = open(filenames, 'r')
    	(rep, new_name) = os.path.split(filenames)
    	fileModif = open(os.path.join("atraiter\\pass3", new_name), "w")
    	(filepath, filename) = os.path.split(filenames)
    	(shortname, extention) = os.path.splitext(filename)
    	fileModif.write(shortname + "\n")
     
    	for line in fich_in :
    		#split la ligne en enlevant les espaces
    		info = re.split("\s*", line)
    		#si le nom est START, stoque les valeurs pour pouvoir les soustraire
    		if info[0] == "START":
    			line = line.replace("START", "PX")
     
    		#si le nopm commence par BEND, modifie la ligne
    		elif info[0][:4] == "BEND":
    			line = line.replace(info[0][:5], "PX")
     
    		elif info[0][:6] == "FINISH":
    			line = line.replace(info[0][:6], "PX")
     
     
     
    		#ecrit la ligne dans le fichier	
    		if info[0][:2] != "ND" and info[0][:6] != "/SPOOL" and info[0][:10] != "/END-SPOOL" and info[0][:8] != "SPOOL-ID" and info[0][:12] != "SPOOL-PREFIX" and info[0][:2] != "OD" and info[0][:14] != "WALL-THICKNESS" :
    			fileModif.write(line)	
    	fileModif.close()	
    	fich_in.close()
    Encore une fois merci à vous

  12. #12
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    josmiley, j’aime bien ton code du message #8 sur certains aspects, il n’est pas moche et il a l’avantage d’être plus court et lisible que les miens avec expressions régulières:

    - split de toutes les lignes comme préalable, pas besoin de s’embêter avec des line[0:13], line[0:4], line[0:7].
    - Bien vu de rassembler en un seul traitement d’une part les lignes 'SPOOL-ID' et 'SPOOL-PREFIX' et d’autre part les lignes BEND et FINISH.
    - enregistrer dans une liste out les lignes sélectionnées et faire un ''.join() au moment d’écrire les sorties: pas mal

    Question:
    - pourquoi le try except ?
    Même si une line est vide, line.split() existe.





    Le hic, c’est que ton code (code 6 dans la série ci-dessous) se situe au même niveau de durée d’exécution que ceux avec expressions régulières par lesquelles j’avais commencé de chercher à répondre au problème.

    J’ai un peu modifié la mesure des temps d’exécution dans la série de mes codes 1 à 5 que j’ai testés dans le message
    http://www.developpez.net/forums/d87...s/#post4976245

    Précédemment, j’excluais l’ouverture de fichier de la mesure. Mais ça posait des problèmes entre les codes avec regex et les autres.
    Maintenant, dans la série ci-dessous, toutes les ouvertures de fichier participent aux temps mesurés.


    En refaisant les mesures de temps d’exécution sur mes 5 codes déjà donnés, j’obtiens
    code 1: 169 % (avec regex)
    code 2: 165 % (avec regex)
    code 3: 162 % (avec regex)
    code 4: 104 % (sans regex, line[14:].split() et enumerate)
    code 5: référence (sans regex, map(line[14:].split()) et enumerate)

    Et donc aussi, maintenant:
    code 6: 158 % (code de josmiley)




    -----------------------------------




    J’ai essayé deux codes en modifiant un peu celui de josmiley:

    code 7 dans la série ci-dessous en remplaçant
    out.append(''.join([bl.ljust(14)]+[str(float(i[1])-float(i[0])).rjust(9) for i in zip(bendout,l.split()[1:])])+'\n')
    par
    out.append(bl0.ljust(14)+''.join(str(float(act)-float(prec)).rjust(9) for act,prec in zip(bl[1:],bendout))+'\n')

    et code 8 avec
    str(float(bl[k])-float(bendout[k])).rjust(9) for k in xrange(1,6)


    Dans ces deux codes, j’ai remplacé aussi bl = l.split()[0]
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bl = l.split()
    if not bl:
        break
    bl0 = bl[0]
    Mais ce n’est pas quelque chose qui influe paticulièrement sur la vitesse.


    Il n'y a pas de modification notable par rapport à ton code, josmiley:
    codes 7 et 8 se situent à 134 % du code 5 de référence.




    ------------------------



    J’ai eu une idée:
    on n’est pas obligé de créer deux listes pour deux lignes successives, c’est à dire LP et L dans mes codes, et bendout et l.split()[1:] dans le code de josmiley.
    Il suffit d’ajouter les groupes de 5 nombres à la fin d’une seule liste , qu’on ne prend même pas la peine de curer des premiers nombres, et on fait les calculs
    L[-5]-L[-10],
    L[-4]-L[-9],
    L[-3]-L[-8],
    L[-2]-L[7],
    L[-1]-L[-6]
    Comme ça, pas de déplacement de référence.
    Le code 9 que j’obtiens tourne à la même vitesse que le code 5.


    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    from time import clock
    import re
     
    repet = 100
    A,B,C,D,E,F,G,H,I = [],[],[],[],[],[],[],[],[]
    for wq in xrange(3):
        print '* ',
     
     
        ### Code 1 = du precedent message
        #================================
        # 2 expressions regulieres, L = liste de listes de nombres sous forme de chaine
        # modification de L en entier avant enregistrement des lignes BEND
     
        te = clock()
     
        with open('piktux.txt','r') as f:
            ch = f.read()
     
        for y in xrange(repet):
     
            with open('piktux.txt','r') as f:
                ch = f.read()
     
            patSpool = re.compile('/SPOOL\r?\nSPOOL-ID\s+(\d+)\r?\nSPOOL-PREFIX\s+(.+?)\r?\n'
                                  '(.+?)/END-SPOOL',re.DOTALL)
     
            agarder = ('^ND {23}', '^OD {23}', '^WALL-THICKNESS {11}',
                       '^START {9}','^BEND[\d ]{10}','^FINISH {8}')
            # dans agarder: en-têtes précis des lignes à garder
            patLigne = re.compile( '(' + '|'.join( ag+'.+\n' for ag in agarder ) + ')',re.MULTILINE )
     
            for id,prefix,portion in (m.groups() for m in patSpool.finditer(ch)):
                # on crée le nom du fichier qui va recevoir le contenu de cette portion               
                out_name = id + '^' + prefix + '.txt'
     
                # on crée la sélection de lignes de cette portion qui va être enregistrée
                chout = ''
                for line in ( m.group() for m in patLigne.finditer(portion)):
                    if line[0:5] ==  'START':   # ligne START
                        L = [line[14:].split()]       # on met les nombres dans une liste L recréée
                        chout += line                 # et on enregistre la ligne START dans chout
                    elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                        L.append(line[14:].split())   # on ajoute seulement la ligne à L        
                    elif line[0:6]=='FINISH':   # ligne FINISH
                        # on va faire les calculs sur les lignes BEND et FINISH avant d'enregistrer
                        L.append(line[14:].split())   # ajout nécessaire de la denière ligne à L
                        for i in xrange(1,len(L)-1):  # calculs et enregistrement dans chout des lignes BEND
                            li = [str(float(L[i][k])-float(L[i-1][k])) for k in xrange(5)]
                            chout += ('BEND' + str(i)).ljust(14)\
                                     + ''.join(x.rjust(9) for x in li) + '\n'
                        chout += 'FINISH        '\
                                 + ''.join(str(float(L[-1][k])-float(L[-2][k])).rjust(9)
                                           for k in xrange(5)) + '\n' # ajout de FINISH
                    else:
                        chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
                # on enregistre la portion traitée dans un fichier de nom out_name
     
     
     
        tf = clock()
        A.append(tf-te)
     
     
     
        ###  Code 2
        #==========
        # 2 expressions regulieres, L = liste de nombres sous forme de chaine
        # enregistrement des lignes BEND au fur et a mesure
     
        te = clock()
     
        for y in xrange(repet):
     
            with open('piktux.txt','r') as f:
                ch = f.read()
     
            patSpool = re.compile('/SPOOL\r?\nSPOOL-ID\s+(\d+)\r?\nSPOOL-PREFIX\s+(.+?)\r?\n'
                                  '(.+?)/END-SPOOL',re.DOTALL)
     
            agarder = ('^ND {23}', '^OD {23}', '^WALL-THICKNESS {11}',
                       '^START {9}','^BEND[\d ]{10}','^FINISH {8}')
            # dans agarder: en-têtes précis des lignes à garder
            patLigne = re.compile( '(' + '|'.join( ag+'.+\n' for ag in agarder ) + ')',re.MULTILINE )
     
            for id,prefix,portion in (m.groups() for m in patSpool.finditer(ch)):
                # on crée le nom du fichier qui va recevoir le contenu de cette portion               
                out_name = id + '^' + prefix + '.txt'
     
                # on crée la sélection de lignes de cette portion qui va être enregistrée
                chout = ''
                for line in ( m.group() for m in patLigne.finditer(portion)):
                    if line[0:5] ==  'START':   # ligne START
                        b = 0
                        LP = line[14:].split() # on met les nombres dans une liste L recréée
                        chout += line
                    elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                        b += 1
                        L = line[14:].split()
                        chout += ('BEND' + str(b)).ljust(14)\
                                 + ''.join(str(float(u)-float(LP[i])).rjust(9) for i,u in enumerate(L)) + '\n'
                        LP = L
                    elif line[0:6]=='FINISH':   # ligne FINISH
                        chout += 'FINISH        '\
                                 + ''.join(str(float(x)-float(LP[i])).rjust(9)
                                           for i,x in enumerate(line[14:].split())) + '\n'
                    else:
                        chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
                # on enregistre la portion traitée dans un fichier de nom out_name
                #with open(out_name, 'w') as g:
                    #g.write(chout)
     
        tf = clock()
        B.append(tf-te)
     
     
        #### Code 3
        #==========
        # 2 expressions regulieres, L = liste de floats grace a map()
        # enregistrement des lignes BEND au fur et a mesure
     
        te = clock()
     
        for y in xrange(repet):
     
            with open('piktux.txt','r') as f:
                ch = f.read()
     
            patSpool = re.compile('/SPOOL\r?\nSPOOL-ID\s+(\d+)\r?\nSPOOL-PREFIX\s+(.+?)\r?\n'
                                  '(.+?)/END-SPOOL',re.DOTALL)
     
            agarder = ('^ND {23}', '^OD {23}', '^WALL-THICKNESS {11}',
                       '^START {9}','^BEND[\d ]{10}','^FINISH {8}')
            # dans agarder: en-têtes précis des lignes à garder
            patLigne = re.compile( '(' + '|'.join( ag+'.+\n' for ag in agarder ) + ')',re.MULTILINE )
     
            for id,prefix,portion in (m.groups() for m in patSpool.finditer(ch)):
                # on crée le nom du fichier qui va recevoir le contenu de cette portion               
                out_name = id + '^' + prefix + '.txt'
     
                # on crée la sélection de lignes de cette portion qui va être enregistrée
                chout = ''
                for line in ( m.group() for m in patLigne.finditer(portion)):
                    if line[0:5] ==  'START':   # ligne START
                        b = 0
                        LP = map(float,line[14:].split()) # on met les nombres dans une liste L recréée
                        chout += line
                    elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                        b += 1
                        L = map(float,line[14:].split())
                        chout += ('BEND' + str(b)).ljust(14)\
                                 + ''.join(str(u-LP[i]).rjust(9) for i,u in enumerate(L)) + '\n'
                        LP = L
                    elif line[0:6]=='FINISH':   # ligne FINISH
                        chout += 'FINISH        '\
                                 + ''.join(str(x-LP[i]).rjust(9)
                                           for i,x in enumerate(map(float,line[14:].split()))) + '\n'
                    else:
                        chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
                # on enregistre la portion traitée dans un fichier de nom out_name
                #with open(out_name, 'w') as g:
                    #g.write(chout)
     
        tf = clock()
        C.append(tf-te)
     
     
        ### Code 4
        #=========
        # pas d'expressions regulieres, L = liste de nombres sous forme de chaine
     
        #del patLigne,patSpool
     
        te = clock()
     
        for y in xrange(repet):
     
            f = open('piktux.txt', 'r')
     
     
     
            agarder = ('ND            ', 'OD            ', 'WALL-THICKNESS')
            # dans agarder: en-têtes précis des lignes à garder
     
            for line in f:
                if line[0:9]=='SPOOL-ID ':
                    id = line.split()[1]
                elif line[0:13]=='SPOOL-PREFIX ':
                    out_name = id + '^' + line.split()[1] + '.txt'
                    chout = ''
                # on crée la sélection de lignes de la portion qui va être enregistrée
                elif line[0:6] ==  'START ':   # ligne START
                    b = 0
                    LP = line[14:].split()       # on met les nombres dans une liste L recréée
                    chout += line                 # et on enregistre la ligne START dans chout
                elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                    b += 1
                    L = line[14:].split()
                    chout += ('BEND' + str(b)).ljust(14)\
                                 + ''.join(str(float(u)-float(LP[i])).rjust(9) for i,u in enumerate(L)) + '\n'
                    LP = L
                elif line[0:7]=='FINISH ':   # ligne FINISH
                    chout += 'FINISH        '\
                                 + ''.join(str(float(x)-float(LP[i])).rjust(9)
                                           for i,x in enumerate(line[14:].split())) + '\n'
                elif line[0:10]=='/END-SPOOL':
                    pass
                elif line[0:14] in agarder:
                    chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
        tf = clock()
        f.close()
        temps = tf-te
     
        D.append(temps)
     
        for x in xrange(0):# v in (A,B,C,D,E,F,G,H):
            print '\v avant 5'
            print v,min(v),'len =',len(v)
     
        ### Code 5
        #=========
        # pas d'expressions regulieres, L = liste de floats 
     
        te = clock()
     
        for y in xrange(repet):
     
            f = open('piktux.txt', 'r')
     
            agarder = ('ND            ', 'OD            ', 'WALL-THICKNESS')
            # dans agarder: en-têtes précis des lignes à garder
     
            for line in f:
                if line[0:9]=='SPOOL-ID ':
                    id = line.split()[1]
                elif line[0:13]=='SPOOL-PREFIX ':
                    out_name = id + '^' + line.split()[1] + '.txt'
                    chout = ''
                # on crée la sélection de lignes de la portion qui va être enregistrée
                elif line[0:6] ==  'START ':   # ligne START
                    b = 0
                    LP = map(float,line[14:].split())       # on met les nombres dans une liste L recréée
                    chout += line                 # et on enregistre la ligne START dans chout
                elif line[0:4] == 'BEND':   # lignes BEND quand il y en a
                    b += 1
                    L = map(float,line[14:].split())
                    chout += ('BEND' + str(b)).ljust(14)\
                                 + ''.join(str(u-LP[i]).rjust(9) for i,u in enumerate(L)) + '\n'
                    LP = L
                elif line[0:7]=='FINISH ':   # ligne FINISH
                    chout += 'FINISH        '\
                             + ''.join(str(x-LP[i]).rjust(9)
                                       for i,x in enumerate(map(float,line[14:].split()))) + '\n'
                elif line[0:10]=='/END-SPOOL':
                    pass
                elif line[0:14] in agarder:
                    chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
        tf = clock()
        f.close()
        temps = tf-te
     
        E.append(temps)
     
        for x in xrange(0):#v in (A,B,C,D,E,F,G,H):
            print '\v apres 5'
            print v,min(v),'len =',len(v)
            print
     
        ############################################################################### 
     
        ### Code 6
        #=========
        # Code de josmiley
     
     
        t3 = clock()
     
        for y in xrange(repet):
            f = open('piktux.txt', 'r')
     
            def spool(fichier) :
     
                fname,out,bendout = '',[],[]
                for l in open(fichier, 'r').readlines() :
                        try : bl = l.split()[0]
                        except : continue
                        if bl in ('/SPOOL', 'ND', 'OD', 'WALL-THICKNESS') : out.append(l)
                        elif bl == 'START' :
                                out.append(l)
                                bendout = l.split()[1:]
                        elif bl.startswith('BEND') or bl == 'FINISH' :
                                out.append(''.join([bl.ljust(14)]+[str(float(i[1])-float(i[0])).rjust(9)
                                                                   for i in zip(bendout,l.split()[1:])])+'\n')
                                bendout = l.split()[1:]
                        elif bl in ('SPOOL-ID', 'SPOOL-PREFIX') :
                                out.append(l)
                                fname = l.split()[1] + fname
                        elif bl == '/END-SPOOL' :
                                out.append(l)
                                #with open(fname+'.txt','w') as outfile :
                                        #outfile.write(''.join(out))
                                fname,out,bendout = '',[],[]
     
            spool('piktux.txt')
     
        t4 = clock()
        temps = t4-t3
     
     
        F.append(temps)
     
     
     
        ### Code 7
        #=========
        # Code de josmiley modifie par eyquem
        t7 = clock()
     
        for y in xrange(repet):
     
            def spool(fichier) :
                fname,out,bendout = '',[],[]
                for l in open(fichier, 'r').readlines() :
                    bl = l.split()
                    if not bl:
                        break
                    bl0 = bl[0]
                    if bl0 in ('/SPOOL', 'ND', 'OD', 'WALL-THICKNESS'):
                        out.append(l)
                    elif bl0 == 'START':
                        out.append(l)
                        bendout = bl[1:]
                    elif bl0[0:4]=='BEND' or bl0 == 'FINISH':
                        out.append(bl0.ljust(14)+''.join(str(float(act)-float(prec)).rjust(9)
                                                           for act,prec in zip(bl[1:],bendout))+'\n')
                        bendout = bl[1:]
                    elif bl0 in ('SPOOL-ID', 'SPOOL-PREFIX'):
                        out.append(l)
                        fname = bl[1] + fname
                    elif bl0 == '/END-SPOOL':
                        out.append(l)
                        #with open('zz'+fname+'.txt','w') as outfile:
                            #outfile.write(''.join(out))
                        fname,out,bendout = '',[],[]
     
            spool('piktux.txt')
        t8 = clock()
        temps = t8-t7
        G.append(temps)
     
        ### Code 8
        #=========
        # Code de josmiley modifie par eyquem 2
        tj1 = clock()
     
        for y in xrange(repet):
     
     
            def spool(fichier) :
                fname,out,bendout = '',[],[]
                for l in open(fichier, 'r').readlines() :
                    bl = l.split()
                    if not bl:
                        break
                    bl0 = bl[0]
                    if bl0 in ('/SPOOL', 'ND', 'OD', 'WALL-THICKNESS'):
                        out.append(l)
                    elif bl0 == 'START':
                        out.append(l)
                        bendout = bl
                    elif bl0[0:4]=='BEND' or bl0 == 'FINISH':
                        out.append(bl0.ljust(14)+''.join(str(float(bl[k])-float(bendout[k])).rjust(9)
                                                           for k in xrange(1,6))+'\n')
                        bendout = bl
                    elif bl0 in ('SPOOL-ID', 'SPOOL-PREFIX'):
                        out.append(l)
                        fname = bl[1] + fname
                    elif bl0 == '/END-SPOOL':
                        out.append(l)
                        #with open('zz'+fname+'.txt','w') as outfile:
                            #outfile.write(''.join(out))
                        fname,out,bendout = '',[],[]
     
            spool('piktux.txt')
     
        tj2 = clock()
        temps = tj2-tj1
     
     
        H.append(tj2-tj1)
     
        ### Code 9
        #=========
        # pas d'expressions regulieres, L = liste de floats 
     
        te = clock()
     
        for y in xrange(100):
     
            f = open('piktux.txt', 'r')
     
     
            agarder = ('ND            ', 'OD            ', 'WALL-THICKNESS')
            # dans agarder: en-têtes précis des lignes à garder
     
            for line in f:
                if line[0:9]=='SPOOL-ID ':
                    id = line.split()[1]
                elif line[0:13]=='SPOOL-PREFIX ':
                    out_name = id + '^' + line.split()[1] + '.txt'
                    chout = ''
                # on crée la sélection de lignes de la portion qui va être enregistrée
                elif line[0:6] ==  'START ':   # ligne START
                    L = map(float,line[14:].split())     # on met les nombres dans une liste L recréée
                    chout += line                 # et on enregistre la ligne START dans chout
                elif line[0:4] == 'BEND' or line[0:7]=='FINISH ':   # lignes BEND et FINISH
                    L.extend(map(float,line[14:].split()))
                    chout += line[14:]\
                             + ''.join(str(L[k]-L[k-5]).rjust(9) for k in xrange(-5,0)) + '\n'
                elif line[0:10]=='/END-SPOOL':
                    pass
                    #g = open('zUh'+out_name,'w')
                    #g.write(chout)
                    #g.close()
                elif line[0:14] in agarder:
                    chout += line # on enregistre les lignes ND, OD, WALL-THICKNESS
     
        tf = clock()
        f.close()
        temps = tf-te
     
        I.append(temps)
     
     
     
    print
    print '==============='
    for j,v in enumerate([A,B,C,D,E,F,G,H,I]):
        if j+1==6:
            print str(j+1).rjust(3),min(v),'len =',len(v),'code de josmiley'
        elif j+1==9:
            print '\n'+str(j+1).rjust(3),min(v),'len =',len(v),'BEND or FINISH '
     
        else:
            print str(j+1).rjust(3),min(v),'len =',len(v)
     
     
     
    print '-- Fin du programme --'


    -------------------------------------------------



    J’ai fait d'autres tests de divers codes.
    Je n’ai pas de conclusion bien établie sur la raison de la différence de vitesse entre mes codes et ceux fondés sur le code de josmiley.
    est-ce que ca tient aux split() effectués pour chaque ligne ou à la façon d’ouvrir le fichier (for line in open() ) ?

    Il apparaît en tous cas que les codes les plus rapides sont ceux qui reposent sur f = open(’pitkux.py’) et for line in f

    Mais les diverses variantes que j’ai testées ont des temps très poches (1 ou 2 % près).
    Je ne donne pas ces variantes fastidieuses, je donne seulement le code qui me paraît le plus lisible. À ce niveau de vitesses quasi identiques, c’est le critère à privilégier à mon avis.

    Ça donne le code suivant dans lequel:
    - je préfère finalement ajouter les lignes à une chaînes plutôt que de les mettre en liste puis faire ''.join(liste) en sortie.
    - les cas BEND et FINISH sont séparés
    - 'BEND' + str(b) est remplacé par line[0:14] donc plus de b
    - pas de
    str(x-LP[i]).rjust(9) for i,x in enumerate(map(float,line[14:].split()))
    mais
    L[k]-P[k]).rjust(9) for k in xrange(5)



    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
    f = open('piktux.txt', 'r')
     
    agarder = ('ND            ', 'OD            ', 'WALL-THICKNESS')
     
    for line in f:
        if line[0:9]=='SPOOL-ID ':
            out_name = line.split()[1]
        elif line[0:13]=='SPOOL-PREFIX ':
            out_name = out_name + '^' + line.split()[1] + '.txt'
            chout = ''
        elif line[0:6] ==  'START ':
            P = map(float,line[14:].split())
            chout += line
        elif line[0:4] == 'BEND':
            L = map(float,line[14:].split())
            chout += line[0:14]\
                     + ''.join(str(L[k]-P[k]).rjust(9) for k in xrange(5)) + '\n'
            P = L
        elif line[0:7]=='FINISH ':
            L = map(float,line[14:].split())
            chout += 'FINISH        '\
                     + ''.join(str(L[k]-P[k]).rjust(9) for k in xrange(5)) + '\n'
        elif line[0:14] in agarder:
            chout += line
        elif line[0:10]=='/END-SPOOL':
            with open(out_name,'w') as g:
                g.write(chout)
     
    f.close()

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Points : 5
    Points
    5
    Par défaut
    OUfti !
    Vous me sidérer avec vos codes
    Je vois qu'il y a toujours moyen d'optimiser le code, je commence un peu mieux à comprendre mais c'est pas toujours évident.
    Le map par exemple j'ai pas encore saisi.
    Mais j'ai de la lecture à faire

  14. #14
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    La docu est là pour aider:

    http://www.python.org/doc/versions/

    http://www.python.org/doc/2.5.4/

    http://www.python.org/doc/2.6.4/

    http://www.python.org/doc/3.1/





    map() n’a rien de compliqué



    ingrédients:
    - un itérable: tuple, liste, itérateur,etc
    - une fonction func

    on regroupe dans un même récipient
    (func, li)

    on passe au four:
    map(func, li)


    Si le four est de version 3, on récupère un itérateur qui livre les éléments de l’itérateur traités par func.

    Si le four est de version 2.6 ou inférieure, on récupère une liste dont chaque élément a été cuit par func





    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    tu = ('4','34','89','109','459')
    print 'tu =',tu
    print type(tu[0]),tu[0]
     
    res = map(int,tu)
    print '\nres =',res
    print type(res[0]),res[0]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    tu = ('4', '34', '89', '109')
    <type 'str'> 4
     
    res = [4, 34, 89, 109]
    <type 'int'> 4



    Si on veut utiliser une fonction qui ne fait pas partie du langage, il faut
    - soit la définir en dehors du map()
    def func(x):
    .... instr1
    .... return ...
    - soit la définir à la volée (c’est à dire que l’objet fonction existe le temps qu’il sert mais on ne lui affecte pas de référence précise) comme une fonction lambda dans le map():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    tu = ('4','34','89','109')
    print 'tu =',tu
    print type(tu[0]),tu[0]
     
    res = map(lambda x: 4.2*int(x),tu)
    print '\nres =',res
    print type(res[0]),res[0]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    tu = ('4', '34', '89', '109')
    <type 'str'> 4
     
    res = [16.800000000000001, 142.80000000000001, 373.80000000000001, 457.80000000000001]
    <type 'float'> 16.8

  15. #15
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Question:
    - pourquoi le try except ?
    Même si une line est vide, line.split() existe.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    try : bl = l.split()[0]
    except : continue
    si on split() une ligne vide(ce qui arrive souvent à cause du saut de ligne en fin de fichier), il ne peut pas exister d'index [0], split() retournant une liste vide.

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Points : 5
    Points
    5
    Par défaut
    Merci pour les explications.

Discussions similaires

  1. Réponses: 6
    Dernier message: 01/10/2007, 12h29
  2. Réponses: 10
    Dernier message: 07/12/2006, 20h52
  3. Somme des valeurs de certaines lignes
    Par Tartenpion dans le forum Langage SQL
    Réponses: 6
    Dernier message: 16/02/2006, 16h46
  4. Imposer une valeur dans une ligne "identity" d'une
    Par mibo94 dans le forum Access
    Réponses: 1
    Dernier message: 26/11/2005, 16h59
  5. [vb excel]Tester une valeur dans une ligne
    Par Mugette dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 28/09/2005, 13h58

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