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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    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
    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 expérimenté
    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
    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
    Membre averti
    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
    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 expérimenté
    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
    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
    Membre averti
    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
    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 Expert
    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
    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)

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