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 :

Python: Réécrire une ligne selon la ligne suivante


Sujet :

Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 8
    Points : 3
    Points
    3
    Par défaut Python: Réécrire une ligne selon la ligne suivante
    Bonjour à tous,

    Je ne fais du python que très ponctuellement et suis donc très limité sur ce sujet

    Je cherche donc à écrire un petit programme qui permet de réécrire un fichier à quelques lignes près.
    Pour ce faire, je crée un nouveau fichier dans lequel je recopie les lignes une par une, sauf celles que je veux enlever.
    Les lignes qui doivent être enlevées contiennent "KP". Mais ce sont aussi les lignes suivantes jusqu'à la prochaine ligne ayant "21" au début.
    Jusque-là, pas de soucis.
    Or, il faut aussi enlever la ligne précédant les lignes "KP", et là c'est le drame

    Un petit exemple rapide en PJ: Je veux passer de test à test-post.

    Enlever :
    " kp
    346 678 234 6789 235
    2345 67 43 67 "
    est très simple, mais comment enlever aussi:
    "21 456 8 2" située juste avant???

    Je tiens à signaler que cela doit se faire sur des fichiers totalement aléatoires, d'où les nombres "bidon " que j'ai mis un peu partout...
    La structure du fichier est une succession de paragraphes:
    "21 Nombres qcq
    Nom du groupe (KP, tata...)
    Nombres qcq (sur plusieurs lignes)"

    Je n'ai pas le script que j'ai commencé à créer avec moi, je le posterai demain.

    Merci beaucoup pour la moindre petite aide!!
    Fichiers attachés Fichiers attachés

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 290
    Points : 426
    Points
    426
    Par défaut
    Bonjour,

    J'aurais 2 idées :

    1. votre fichier n'est jamais gros, vous pouvez vous permettre de le stocker entièrement dans une liste, ce qui sera plus simple pour avancer ou reculer dedans.
    2. sinon, faites 2 passes : une pour noter les lignes à supprimer, une autre pour écrire votre nouveau fichier.

    Je ne fais du python que très ponctuellement et suis donc très limité sur ce sujet
    Pourquoi ne pas choisir un langage que vous maîtrisez alors ?

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Si vous regardez le fichier comme une suite de lignes, il va falloir arriver a gérer les états de ligne précédente, ligne courante et la détection de cette qui commence par '21'.

    Coder le tout dans une boucle de quelques lignes demande de l'habilite et pourra être difficile a mettre au point a cause des dépendances qu'auront toutes ces variables entre elles.

    Regardez le fichier comme une suite de blocks qui commencent par 21.

    En supposant qu'on sache coder une fonction next_block(file) qui retourne le block suivant - une liste de lignes -, le tri des blocks a garder devient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        while True:
            block = next_block(file_in)
            if 'kp' in block[1]:
                 # ecriture du block...
    Le codage de next_block dépendra de la prise en compte de la fin du block: fin du fichier ou ligne suivante qui commence par '21'. Ce qui pourra être stocke dans un objet accessible via une variable globale.
    Python permet aussi de le stocker dans le locals() d'un generator ou l'attribut d'une instance de classe. Mais on pourra faire un fseek en arriere pour relire cette ligne.
    Quel que soit votre choix, ce sera plus facile a mettre au point: son comportement ne dépendra que d'une variable et de la ligne lue.

    A vous de voir.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 552
    Points : 3 918
    Points
    3 918
    Par défaut
    J'ai trouvé une solution qui reste simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    def myreadfile(fnIn, fnOut):
     
        def writeb(block):
            if (len(block)> 0) and (block[1].strip() != "kp"):
                # fait l'hypothèse que tous les blocs contiennent au moins 2 lignes
                for l in block:
                    fOut.write(l)    
     
        block = []
        fIn = open(fnIn, "r")
        try:
            fOut = open(fnOut, "w")
            try:
                for line in fIn:
                    if line.strip() == "$$fin":
                        # fin de fichier
                        writeb(block)
                        fOut.write(line)
                        break
                    elif (line[0] == " "):
                        # complète le bloc
                        block.append(line)
                    else:
                        # écriture du bloc lu si possible
                        writeb(block)
                        block = [line] #nouveau bloc
            finally:
                fOut.close()
        finally:
            fIn.close()
    Je charge le bloc courant dans une liste puis je l'écris s'il le faut.
    la détection des bloc est basée sur l'absence d'un espace en premier position de la ligne lue.

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Bonsoir et merci pour vos réponses!

    A Drawingrom:
    le fichier peut être ultra-lourd (j'ai un cas avec 1.5e7lignes!!)
    C'est bien pour ça que je dois le réduire...
    Je choisis le python pour 2 raisons:
    - je ne serais pas plus avancé dans un autre langage...
    - On peut normalement y manipuler facilement les fichiers

    A wiztricks:
    J'ai tenté aussi de considérer le fichier en blocs, mais pour le moment sans succès...
    Je suis aussi très peu au fait sur ces notions d'objets, generator, instance de classe...

    A e-ric: Que dire à part : bravo!!
    On voit la différence entre moi et mes if et autres traceurs et un vrai développeur


    Mais j'ai encore besoin de vous: En effet, mon cas test était trop simplifié:
    Il y a aussi des lignes en amont des cartes 21 et d'autres en aval.
    Pire: En amont, il y a la date du fichier, et aujourd'hui, on est le 21...
    Je me suis par contre trompé: la fin des cartes 21 est marqué par un 99 et non un $$fin (je l'ai évidemment remplacé dans le script d'Eric), mais il se peut que une ligne commençant par 99 revienne plus tard dans le fichier...

    Je remets donc un cas test en pj, ainsi que le code que j'avais commencé hier, bien loin de celui d'Eric^^
    Je tente bien sûr de mon côté en partant du script d'Eric...

    Merci encore!!
    Fichiers attachés Fichiers attachés

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Je suis idiot: je n'avais qu'à me ramener au cas test que je vous ai soumis avant de passer dans la fonction

    Pb résolu!

  7. #7
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 552
    Points : 3 918
    Points
    3 918
    Par défaut
    J'avoue que je comprends mal la structure de ton fichier et tes dernières explications, bon c'est vrai il est tard...

    Pour moi, le $$fin marquait la fin des données et chaque ligne commençant au premier caractère de la ligne annonçait le bloc de lignes commençant par une espace (je dis bien *une*...), je n'ai pas considéré la valeur des cartes.

    Pour l'apprentissage de Python, il y a de nombreux tutoriels et une communauté active, si tu veux y consacrer du temps, je pense que tu progresseras vite.
    Perso, cela fait peu de temps que je travaille avec, je viens du monde Delphi, j'apprécie beaucoup Python pour sa concision, la simplicité et le nombre restreint de ses concepts tout en étant puissant et assez rapide. Pour de petites applications on code très vite et l'IDE fourni permet une mise au point dans de bonnes conditions. Un vrai petit bijou.

    Enfin, si tu as résolu ton problème, c'est l'essentiel. Bonne continuation.

    @+

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

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

Discussions similaires

  1. [Vxi3] afficher une valeur selon la ligne du tableau
    Par aurelie83 dans le forum Deski
    Réponses: 10
    Dernier message: 23/10/2009, 20h56
  2. Réponses: 1
    Dernier message: 15/05/2008, 11h48
  3. Découper une ligne selon un separateur sans le 1er champ
    Par pascalbout1 dans le forum Langage
    Réponses: 2
    Dernier message: 31/10/2007, 11h18
  4. Réponses: 1
    Dernier message: 10/08/2007, 15h01
  5. Ne pas afficher une ligne selon une valeur
    Par uloaccess dans le forum Access
    Réponses: 3
    Dernier message: 18/11/2005, 14h04

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