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 :

Optimisation de code - parsing de données


Sujet :

Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Optimisation de code - parsing de données
    Bonjour à tous, je suis étudiant en license de bio et j'ai un programme de parsing de données a faire sous python.

    J'arrive à un résultat plutôt correct, le problème est le temps d'exécution du programme, près d'une demi heure, sur un macbook intel a 2GHZ et 2Go de ram...

    Et je trouve ça long...
    J'ai donc regardé un peu sur internet, le multithreading et l'optimisation de code python mais je dois avouer que c'est un peu du charabia pour moi et en plus dans un anglais pas toujours facile d'accès à mon goût...

    Alors si vous avez un peu de temps pour m'aider ce serai sympa de jeter un coup d'oeil au code, que j'ai mis en download sur free :
    http://dl.free.fr/rDwQyoKEx
    Les quatre zipés postés sont a mettre dans le même dossier (je l'ai testé sous mac et normalement, python étant portable, ca ne devrais pas poser de problème sous d'autres OS).

    Merci à tous de votre aide,
    nicom

    ps: tout commentaire sur le code est bienvenue mais faut savoir que je comprends vite si on m'explique lentement...
    pps: bien sur le code vous pouvez en faire ce que vous voulez, aucune propriété intellectuelle ou quoi ce soit...
    ppps : faites pas gaffe au nom du programme, j'étais un peu fatigué

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    Bonjour,

    avant d'envisager le multithreading, je te suggère de profiler ton code. Python inclut dans sa lib standard le nécessaire:

    http://docs.python.org/library/profile.html

    ceci va te permettre de localiser les bouts de code les plus gourmands en temps. du coup, tu peux concentrer tes efforts "localement", plutôt que "globalement".

    on apprend toujours des choses intéressantes en profilant son code (et notamment que la méthode "index" des listes est une horreur en terme d'optimisation)

  3. #3
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Effectivement, avant de paralléliser (ce qui reste un énorme travail, puisque le multi-threading est inutile en Python pur), il est indispensable que tu aies déjà un code optimisé.
    Par exemple, tu passes ton temps à faire des boucles for imbriquées. C'est vraiment pas optimal du tout.
    Par la suite, tu peux aussi passer par Cython pour compiler ton parseur et gagner encore de la perf, une fois le code optimisé.

  4. #4
    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
    Bonjour ,



    Pardon, mais où voyez vous du multithreading ?
    Je crois que vous vous laissez induire en erreur par l'emploi très mauvais et trompeur des nom "threads" et "threading" que fait nicom. Mais "threads" est avec un "s" , ce qui ne correspond, sauf erreur de ma part, à aucune instruction Python.
    Et "threading" est le nom d'une fonction que définit nicom, pas le nom du module threading puisque de toutes façons nicom ne fait aucune importation et que ce module est non-built-in.


    Par contre, j'ai commencé à analyser le code, ça me fait penser à la formule des Shadocks. Il y a une grosse insuffisance de conception, il va falloir corriger l'algorithme au plus haut niveau, c'est à dire la fonction La-Mal-Nommée (threading).

    À mon avis, l'objectif poursuivi par ce code doit pouvoir être exécuté en moins de 4 secondes, et je ne serais pas étonné que je dise 10 fois trop.

  5. #5
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Pardon, mais où voyez vous du multithreading ?
    Dans le premier message.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Tout d'abords merci a tous pour vos réponses.
    En effet il y a confusion sur le multithreading.
    En fait pendant que je tentais de glaner des information pour améliorer mon code, je suis tombé sur plusieurs forum (lunixfr par ex) qui rapportaient que python 2.5, que j'utilise, n'utilise qu'un seul des 2 coeur de mon core 2 duo... Alors j'y ai vu un moyen pour booster un peu mon code...

    Mais apparemment il y est possible d'améliorer mon code plus facilement.

    J'ai suivi les conseil de kangoo voici le résultat :

    Je n'y comprends pas grands chose, mais je crois que la procédure la plus longue est le traitement des mots clefs, mais c'est assez logique puisque je dois parcourir une longue liste de mot clefs et chaque phrase de chaque article.
    Ensuite vient (la mal nommée ^^) threads() : et c'est là que le bas blesse... J'ai retourné le problème dans tout les sens, parce que je me suis rapidement rendu compte que ce code était lourd et avec l'info de kangoo sur les index et le profiling qu'il était bon de revoir sa conception.

    Mais ce que je vois pas c'est comment...
    En effet mon code fonctionne selon le modèle suivant : il y a n article.
    Je sais que chaque article débute par n1: , n2: , ..., n: . Donc je met en cache dans une variable le texte entre chaque n1, n2...

    Le problème c'est pour le dernier, du coup je recours à l'index du dernier pour créer une exception qui me permet de mettre le dernier dans mon dictionnaire.

    @eyquem : merci d'avoir lu mon code. Si tu pouvait me décrire le raisonnement qui te permet de gagner tout ce temps...
    Pour l'insuffisance de conception (vexation powaaa ), je l'ai assez mal pris au début puisque j'y ai quand même passer pas mal de temps (environ 10h).
    Certes mon niveau en programmation, notamment python, est assez naze mais bon je pensais quand même avoir produit un algorithme logique et assez bien construit...

    Citation Envoyé par Matthieu Brucher Voir le message
    Par exemple, tu passes ton temps à faire des boucles for imbriquées. C'est vraiment pas optimal du tout.
    Les boucles while sont mieux ?


    Merci encore à tous pour vos réponses,
    nicom

  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
    Désolé si tu as mal pris ce que j'ai dit. J'ai préféré ne pas perdre du temps à trouver des formules diplomatiques, pour plutôt regarder ton code. Il y a des moments, il faut dire les choses telles qu'elles sont.
    Rassure toi, ton algorithme est logique et bien construit, mais c'est son principe qui ne va pas. Je pense que c'est pour cause d'inexpérience dans le langage Python: ne connaissant pas ses possibilités dans le détail, tu te diriges vers des solutions qui ne sont pas bonnes. Il faut commencer par regarder dans le carquois pour trouver toutes les flêches, pas seulement celles qui dépassent (j'ai regardé Danse Avec Les Loups hier soir, ça doit être ça).
    Rassure toi encore: j'ai passé deux ans à faire tourner des codes dont je me suis aperçu peu à peu qu'ils sont infâmes. Suis un peu lent à explorer le carquois. Suis persuadé que tu vas vite progresser parce que je n'ai pas eu de difficulté à comprendre ton code. Des fois, c'est pire.

    Bon, ceci dit, pour les 4 secondes, ça me semble évident maintenant que j'ai regardé ton code:
    1 - ce que tu veux faire faire à ton programme est très simple pour Python
    2 - ton code revient à demander à une fourmi de tourner les pages d'une édition pour personnes agées des œuvres complètes de Lénine

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

    Il faut commencer par dire que les noms que tu donnes aux variables et fonctions ne vont pas du tout.

    Une instruction print type(item) rajoutée après l'instruction item = item.split('\n') montre que item est une liste. Je n'appelle pas une liste avec le nom item, sauf si elle est un élément d'un objet qui en contient plusieurs, et encore.... Ce n'est même pas le cas ici, ta liste item est ta matière de base. Donc il FAUT changer ce nom.

    Les éléments de ton item sont des lignes. Pourquoi ne pas les appeler "ln", "ligne", "line" ou je ne sais quoi d'autre ?

    Quand tu appelles addtodict(organizing, current_num) , le deuxième argument porte bien un nom en accord avec ce qu'il est, un nombre.
    Mais quand on regarde la définition de addtodict(), on voit que ce deuxième argument est affublé du nom "title", nom qui est plus adapté à une chaine, ce qui ne fait pas penser que ça va recevoir uniquement un nombre en numérique. Ce n'est pas bon.

    Donc j'ai envie de réécrire:

    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
    def traitement_de(chaine_d_articles):
        num, organizing = 2, []
        li = chaine_d_articles.split('\n')
     
        for line in li:
            num_str = str(num) + ": "
     
            if (num_str in line):
                current_num = num - 1
                addtodict(organizing, current_num)
                num = num + 1
                organizing = [line]
     
            # Exeption pour le dernier article	
            elif (li.index(line) == li.index(li[-2])):
                current_num = num - 1
                organizing.append(line)
                organizing.append('')
                addtodict(organizing, current_num)
                break
     
            else:
                organizing.append(line)





    Analysons un peu ça. Rajoutons les instructions

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            print 'num_str  est ',num_str
            print '\norganizing =',organizing
    après for line in li:
    On s'aperçoit que tu charges progressivement les lignes dans organizing. C'est déjà beaucoup de travail pour rien (cf plus loin) mais en plus tu fais un truc absolument dingue au niveau des tests:
    tu mets le test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    elif (li.index(line) == li.index(li[-2])):
    en deuxieme position, c'est à dire qu'avant d'arriver au
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    else: organizing.append(line)
    le programme doit pour absolument faire ce test à chaque examen de ligne:
    1- c'est inutile pour toutes les lignes sauf une puisque ce test n'est égal à True que pour l'avant dernière ligne. Or il suffit de mettre l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print 'len de li =',len(li)
    apès
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    li = chaine_d_articles.split('\n')
    pour voir qu'il y a 191714 lignes.
    Tu fais faire 191712 fois un test inutile à ton programme !!!!

    2- Tenant compte de la remarque de kango, la méthode index() est lourde (je l'ignorais). Or à chaque ligne tu forces le programme à tester
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    elif (li.index(line) == li.index(li[-2])):
    c'est à dire à faire 2 fois une détermination d'index !!!
    dont la deuxième est ubuesque puisque li.index(li[-2]), c'est -2 !!!





    Si tu veux obtenir la succession des lignes d'un article dans une variable organizing, il va falloir procéder autrement.
    Si li[m] est la première ligne et li[n] la dernière ligne, organizing est instantanément déterminée par li[m:n+1]
    C'est du découpage, ou slicing, de liste.
    Il faut repenser ton algorithme pour trouver m et n.

    Voici par exemple une piste:
    remplacer for line in li:
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in xrange(len(li)):
        print i,li[i]
    et faire un test sur chaque ligne pour voir si elle contient "1: ","2: ","3: ",etc


    Cependant il y a mieux à faire. Je te laisse là dessus un moment pour que tu assimiles tout ça avant d'aller plus loin.



    Mais une chose va devoir être à corriger impérativement aussi: ton test pour trouver la première ligne de chaque article est de mon point de vue insuffisant:
    peut donner lieu à des erreurs si dans un article il se trouve une telle succession de caractères comme "102: " ou "1001: ' etc.

    Ces repères de début d'articles sont censés être situés au début d'une ligne, mais ton test détecte ce motif même s'il est au milieu d'une ligne.
    Il faut absolument étudier un minimum les méthodes de string:
    http://www.python.org/doc/2.5.2/lib/...s.html#l2h-233




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


    Pour ma part, au lieu de passer en liste, je ferais un traitement de ton document "articles" sous forme de chaine.
    C'est une autre approche, que je préfère depuis quelques temps au traitement de listes quand c'est possible.
    Je me sers dans ces cas de find() qui est très très rapide.

  8. #8
    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 @ Matthieu
    Effectivement, dans le message il y a le mot. Mais j'ai estimé que nicom se trompait lui même en parlant de multithreading à propos de son code. J'aurais dû préciser «où DANS LE CODE voit-on du multithreading ?»

    À part ça, eyquem ètre comme tige d'herbe dans grandes plaines de la connaissance Python que sorcier Matthieu parcourt au galop

  9. #9
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par nicom1752 Voir le message
    Les boucles while sont mieux ?
    Non. En fait dans tout interpréteur (non compilé), les boucles, c'est le mal. Il y a en général des outils permettant de passer outre les boucles, c'est ce qui doit être recherché.

  10. #10
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Effectivement, dans le message il y a le mot. Mais j'ai estimé que nicom se trompait lui même en parlant de multithreading à propos de son code. J'aurais dû préciser «où DANS LE CODE voit-on du multithreading ?»

    À part ça, eyquem ètre comme tige d'herbe dans grandes plaines de la connaissance Python que sorcier Matthieu parcourt au galop
    Tu parles

    En fait, on avait grosso modo compris ce qu'il voulait, mais on a chacun interprété la réponse optimale de manière différente

  11. #11
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    Citation Envoyé par nicom1752 Voir le message
    Je n'y comprends pas grands chose, mais je crois que la procédure la plus longue est le traitement des mots clefs, mais c'est assez logique puisque je dois parcourir une longue liste de mot clefs et chaque phrase de chaque article.
    Ensuite vient (la mal nommée ^^) threads() : et c'est là que le bas blesse... J'ai retourné le problème dans tout les sens, parce que je me suis rapidement rendu compte que ce code était lourd et avec l'info de kangoo sur les index et le profiling qu'il était bon de revoir sa conception.
    dans le profil que tu donnes, le traitement global prend 2559.147 secondes et tu passes au total 2490.873 secondes dans la méthode "index" des listes, c'est à dire dans du code que tu n'as pas écrit .

    si tu arrives à trouver une solution pour ne plus utiliser "index", ton programme sera beaucoup plus rapide que maintenant.

    la méthode "index" est d'ordre n, c'est à dire que sa vitesse dépend 'linéairement' de la taille de la liste.

    la méthode "append" est d'ordre 0, c'est à dire que sa vitesse ne dépend pas de la taille de la liste.

    compare le ratio (temps_cumulé/nombre_executions) (c'est à dire le per_call) entre ces deux méthodes dans le profile pour visualiser la différence de performance entre une méthode d'ordre n et une méthode d'ordre 0

  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
    Tu parles
    Comment ça ?
    Attention, je vais mal le prendre si on ne me croit pas.

  13. #13
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Comment ça ?
    Attention, je vais mal le prendre si on ne me croit pas.
    C'était par rapport à ta métaphore, ça m'a fait sourire

  14. #14
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Voilà après avoir lu et relut vos conseil j'ai (enfin) réussit a améliorer la vitesse d'exécution de mon code, qui passe de 30' à 1'30"...

    Pour se faire j'ai supprimer la recherche d'index qui était tout simplement complètement superflue...

    Ca donne ca :
    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
    def threading (articles_full):
    	num, organizing = 2, []
    	articles_full = articles_full.split('\n')
    	for ligne in articles_full:
     
    		num_str = str(num) + ": "
     
    		if (num_str in ligne):
    			current_num = num - 1
    			addtodict(organizing, current_num)
    			num = num + 1
    			organizing = [ligne]
     
    		else:
    			organizing.append(ligne)
    	current_num = num -1
    	addtodict(organizing, current_num)
    Et j'ai changer les noms de variables
    Sinon je reste avec le pb du "num_str in line" mais quand je fais "num_str in line[0:3] il s'arrète au 9éme article et ensuite bug...

    Voilà, donc j'ai bien avancé, merci beaucoup de votre aide à tous.
    Il me reste encore l'interface graphique, le tri par mots clefs et l'export en HTMl et c'est fini

    Bonne journée,
    nicom

    ps: Réponse au précédents topics :
    Citation Envoyé par eyquem Voir le message
    On s'aperçoit que tu charges progressivement les lignes dans organizing.
    En fait j'ai pas trouvé dans la suite comment changer mon fusil d'épaule.
    J'ai essayé plusieurs fois mais à chaque fois je retombe sur le premier algorithme que j'ai fait. Limité nicom ?
    Je ne sais pas en fait j'ai tourné autour du pot longtemps et je vois pas comment lui faire mettre en mémoire l'article en cours d'une manière plus simple...

    Citation Envoyé par eyquem Voir le message
    Si tu veux obtenir la succession des lignes d'un article dans une variable organizing, il va falloir procéder autrement.
    Si li[m] est la première ligne et li[n] la dernière ligne, organizing est instantanément déterminée par li[m:n+1]
    C'est du découpage, ou slicing, de liste.
    Il faut repenser ton algorithme pour trouver m et n.

    Voici par exemple une piste:
    remplacer for line in li:
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in xrange(len(li)):
        print i,li[i]
    et faire un test sur chaque ligne pour voir si elle contient "1: ","2: ","3: ",etc
    J'ai essayé de me docummenter sur la fonction xrange mais je ne comprend pas son interêt par rapport à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in list
         print i, list[i]
    Citation Envoyé par eyquem Voir le message
    Mais une chose va devoir être à corriger impérativement aussi: ton test pour trouver la première ligne de chaque article est de mon point de vue insuffisant:
    peut donner lieu à des erreurs si dans un article il se trouve une telle succession de caractères comme "102: " ou "1001: ' etc.

    Ces repères de début d'articles sont censés être situés au début d'une ligne, mais ton test détecte ce motif même s'il est au milieu d'une ligne.
    Il faut absolument étudier un minimum les méthodes de string:
    http://www.python.org/doc/2.5.2/lib/...s.html#l2h-233
    Oui ca fait un bout de temps que j'avais se problème en tête après je me suis dit qu'il était peu probable que je trouve 'num: ' pour chaque article, c'est vrai que pour les premier c'est plus plausible mais pour les derniers c'est carrément hautement improbable.


    Citation Envoyé par eyquem Voir le message

    Pour ma part, au lieu de passer en liste, je ferais un traitement de ton document "articles" sous forme de chaine.
    C'est une autre approche, que je préfère depuis quelques temps au traitement de listes quand c'est possible.
    Je me sers dans ces cas de find() qui est très très rapide.
    Ok, mais je reste toujours avec le même problème. A un moment il faut que j'organise mes données en fonction des mots clefs et des données interne de chaque article.
    Si j'enlève :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    articles_full = articles_full.split('\n')
    Ce qui transforme le texte de base en liste en fonction des retours à la ligne qui sont les séparateurs des : thêmes, auteurs, ...
    Je me retrouve avec un texte formaté et le même problème en aval de traitement sans pouvoir parcourrir mes lignes aussi facilement.

    Donc je suis pas sur que cette piste me permette d'améliorer encore la vitesse de mon code, mais peut être n'en ais-je pas compris les suptilitées...


    pps: Encore merci à tous

  15. #15
    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
    30mn à 1mn30", c'est dire combien index() faisait du frottement !

    Mais 1mn 30" , c'est encore 20 fois trop.
    L'élimination de index() était une chose nécessaire mais pas suffisante, on ne peut pas appeler ça une amélioration.
    Si on passe de 1'30" à 4 secondes, ce sera une amélioration.

    Pour cela il faut une amélioration de l'algorithme à tous les niveaux.
    Le fait d'enelever index() ne change pas le fait que tu fais une accrétion progressive de lignes dans la variable organizing.
    Puis tu fais la mêm chose dans la sous-fonction donnes_traitement.
    Et il y a plein de trucs qui ne vont pas à droite et à gauche.

    Plutôt que de te décrire par le menu ce qui ne va pas, je crois qu'il vaut mieux s'attaquer à la racine directement:
    J'ai réfléchi à ton problème depuis l'autre jour et je pense qu'il se prête très bien à une utilisation de regex exclusivement, lancée sur ton fichier sous forme chaine, c'est à dire même pas la peine de le transformer en liste. Il n'y a même pas besoin de find().

    Mais il y a 3 problèmes:
    - en me voyant évoquer les regex, tu vas te dire "oh non non, trop compliqué".
    Pas du tout. Quand on connait les regex, le code s'écrit en une demie heure. Je connais suffisamment les regex pour faire ça.
    - je n'aime pas trop balancer un code tout fait. Mais je peux te donner les pistes, et écrire le code si tu bloques. Y en a pas pour 107 ans. Tu seras surpris de la vitesse avec laquelle ça peut se faire.
    - Tu as sans doute un problème de temps. Sans doute un projet à rendre à une certaine date, et de toutes façons tu n'as pas que ça à faire. Cependant, tu apprendrais pas mal de choses en peu de temps et tu aurais un code assez bon je crois.

    À toi de voir.
    Tout dépend de si tu auras encore besoin de ce code à l'avenir ou si c'est juste un devoir à jeter ensuite.
    Et si le code lui même est noté ou non. Tel quel, il vaut ......

    Je te mets de toutes façons dans le prochain message un aspect du problème auquel j'ai réfléchi et que je n'ai pas posté parce que je me demandais si tu allais repasser après la vex de l'autre jour.

  16. #16
    Membre habitué
    Inscrit en
    Mars 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2003
    Messages : 127
    Points : 149
    Points
    149
    Par défaut
    Ne pas utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in xrange(len(li)):
    mais
    for i ,value in enumerate(li):
    c'est plus optimisé
    comme on n'a pu le voir dans le post précédent eyquem

  17. #17
    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
    Le fichier 'pubmed_result_hiv_gag.txt' posséde 107 lignes qui comportent un motif "nombre: " au sein de la ligne et pas dans les premiers caractères,
    c'est à dire qui ne sont pas des numéros d'articles:

    ligne 52 - numero d'artcile 3
    Gag transport and virus particle formation. STRUCTURED SUMMARY: MINT-7014185: Gag

    ligne 54 - numero d'artcile 3
    cosedimentation (MI:0027) MINT-7014239: Cullin 2 (uniprotkb:Q13617) physically

    ligne 57 - numero d'artcile 3
    by pull-down (MI:0096) MINT-7014046: gag (uniprotkb: P05888), SOCS1

    ligne 59 - numero d'artcile 3
    fluorescence microscopy (MI:0416) MINT-7014269: tubulin alpha (uniprotkb:Q13748)

    ligne 61 - numero d'artcile 3
    coimmunoprecipitation (MI:0007) MINT-7014036: tubulin alpha (uniprotkb:Q13748)

    ligne 63 - numero d'artcile 3
    (MI:0416) MINT-7014201: Cullin 2 (uniprotkb:Q13617) physically interacts

    ligne 66 - numero d'artcile 3
    MINT-7014257: Gag (uniprotkb: P05888) physically interacts (MI:0218) with

    ligne 68 - numero d'artcile 3
    MINT-7014221: Cullin 2 (uniprotkb:Q13617) physically interacts (MI:0218) with Gag

    ligne 3037 - numero d'artcile 87
    n=94, after 1997: n=1617) from drug-naïve patients were analysed in the

    ligne 3039 - numero d'artcile 87
    were included according to the collection date of the blood sample (before 1997:

    ligne 3040 - numero d'artcile 87
    n=200, after 1997: n=375). RESULTS: Only CS mutations 431V and 452S were

    ligne 5332 - numero d'artcile 150
    Biopolymers 91: 283-296, 2009.This article was originally published online as an

    ligne 10260 - numero d'artcile 290
    EV01: a phase I trial in healthy HIV negative volunteers to evaluate a clade C

    ligne 15605 - numero d'artcile 444
    significant in patients with CD4 cell counts > 500 cells/microl [HIV-1: n = 14;

    ligne 15606 - numero d'artcile 444
    median, 2.5; interquartile range (IQR), 2.1-2.7; HIV-2: n = 22, median, 1.6; IQR,

    ligne 15608 - numero d'artcile 444
    cells/microl (HIV-1: n = 12; median, 2.7; IQR, 2.3-2.8; HIV-2: n = 11; median,

    ligne 15611 - numero d'artcile 444
    in HIV-2-infected patients (HIV-1: n = 14; median, 2.9; IQR, 2.2-3.2; HIV-2: n =

    ligne 17406 - numero d'artcile 498
    Beyond Tsg101: the role of Alix in 'ESCRTing' HIV-1.

    ligne 19833 - numero d'artcile 565
    Laboratoire de Microscopie Moléculaire, UMR 8126: Interactions moléculaires et

    ligne 24738 - numero d'artcile 710
    Selection promotes organ compartmentalization in HIV-1: evidence from gag and pol

    ligne 24996 - numero d'artcile 717
    full-length SL1 stemloop of HIV-1: sequence effects and mechanism of RNA

    ligne 25794 - numero d'artcile 740
    (p7/p1: A431V-K436R-I437V and p1/p6-gag: L449F/V-P452S-P453L/A). Further rare CS

    ligne 30979 - numero d'artcile 890
    Human T-cell lymphotropic virus type 3: complete nucleotide sequence and

    ligne 32504 - numero d'artcile 935
    Assembly of human immunodeficiency virus (HIV) antigens on bacteriophage T4: a

    ligne 34586 - numero d'artcile 996
    protease inhibitor (PI)-resistant HIV-1 protease (IC50: 0.23-0.32 microM).

    ligne 34589 - numero d'artcile 996
    infected MT-2 cells from HIV-1-induced cytotoxicity (IC50: 5.1 microM). P27 also

    ligne 36623 - numero d'artcile 1055
    Annexin 2: a novel human immunodeficiency virus type 1 Gag binding protein

    ligne 44627 - numero d'artcile 1291
    1.88 A crystal structure of the C domain of hCyP33: a novel domain of

    ligne 47060 - numero d'artcile 1359
    of subtype C were less diversive in Xinjiang (p17: 0.0192 +/- 0.0078, C2-V4:

    ligne 47061 - numero d'artcile 1359
    0.0455 +/- 0.0145) than in Yunnan (p17: 0.0279 +/- 0.0102, C2-V4: 0.0482 +/-

    ligne 47065 - numero d'artcile 1359
    0.0473 +/- 0.0105, C2-V4: 0.1114 +/- 0.0112) in Yunnan, but no recombination was

    ligne 47067 - numero d'artcile 1359
    in Henan and the peripheral provinces (p17: 0.0381 +/- 0.0101, C2-V4: 0.0691 +/-

    ligne 48288 - numero d'artcile 1394
    The Vpr protein from HIV-1: distinct roles along the viral life cycle.

    ligne 48649 - numero d'artcile 1404
    The vertical transmission of human immunodeficiency virus type 1: molecular and

    ligne 49313 - numero d'artcile 1423
    surrounding p2: implications for particle assembly and RNA packaging.

    ligne 49529 - numero d'artcile 1429
    DNA/MVA vaccine for HIV type 1: effects of codon-optimization and the expression

    ligne 54297 - numero d'artcile 1569
    Total chemical synthesis of N-myristoylated HIV-1 matrix protein p17: structural

    ligne 55798 - numero d'artcile 1613
    Humoral immunity to HIV-1: kinetics of antibody responses in chronic infection

    ligne 56637 - numero d'artcile 1637
    The central domain of the matrix protein of HIV-1: influence on protein structure

    ligne 56648 - numero d'artcile 1637
    region of p17 (amino acid residues 47 to 55: NPG LLE TSE). Introduction of the

    ligne 57449 - numero d'artcile 1660
    Early diagnosis of HIV-1: infected infants in Brazil using nested-PCR.

    ligne 58512 - numero d'artcile 1691
    Comparative proteomics of the Mycobacterium leprae binding protein myelin P0: its

    ligne 62958 - numero d'artcile 1816
    PA-457: a potent HIV inhibitor that disrupts core condensation by targeting a

    ligne 63926 - numero d'artcile 1843
    Full-length sequence analysis of HIV-1 isolate CM237: a CRF01_AE/B intersubtype

    ligne 64506 - numero d'artcile 1859
    DNA condensation by the nucleocapsid protein of HIV-1: a mechanism ensuring DNA

    ligne 67980 - numero d'artcile 1960
    M. Selby, G. R. Otten, and S. W. Barnett, J. Virol. 74: 2628-2635, 2000). Here we

    ligne 68179 - numero d'artcile 1966
    Stem of SL1 RNA in HIV-1: structure and nucleocapsid protein binding for a 1 x 3

    ligne 73360 - numero d'artcile 2114
    Cross-clade T lymphocyte-mediated immunity to HIV type 1: implications for

    ligne 75111 - numero d'artcile 2164
    Unité des Rickettsies, UMR 6020, IFR 48: Pathologies Transmissibles et

    ligne 77263 - numero d'artcile 2227
    (Sparacio et al. 2000, Virology 271: 248-252). We have extended these analyses

    ligne 78167 - numero d'artcile 2253
    Tsg101: HIV-1's ticket to ride.

    ligne 83894 - numero d'artcile 2418
    p26 protein of human immunodeficiency virus type 2: identification of a new

    ligne 86203 - numero d'artcile 2484
    virus type 1: predominance of drift and purifying selection.

    ligne 90155 - numero d'artcile 2602
    class I molecule mamu-A*01: implications for vaccine design and testing.

    ligne 91503 - numero d'artcile 2639
    Calmodulin and HIV type 1: interactions with Gag and Gag products.

    ligne 92291 - numero d'artcile 2661
    Escherichia coli, LTK63: with no measurable ADP-ribosyltransferase activity, and

    ligne 92292 - numero d'artcile 2661
    LTR72: with residual ADP-ribosyltransferase activity, as mucosal adjuvants for

    ligne 94533 - numero d'artcile 2727
    process of HIV-1: expression and susceptibility of chimeric Vpr as a substrate

    ligne 95334 - numero d'artcile 2751
    immunodeficiency virus type 1: evidence for a role in genomic RNA encapsidation.

    ligne 96306 - numero d'artcile 2780
    placebo-controlled trial of zidovudine between 1991 and 1995: four received

    ligne 96478 - numero d'artcile 2785
    NCp8 exhibited a base preference analogous to that of NCp7: G approximately I > T

    ligne 99007 - numero d'artcile 2858
    Nucleic acid sequence discrimination by the HIV-1 nucleocapsid protein NCp7: a

    ligne 107924 - numero d'artcile 3116
    Functional characterization of the protease of human endogenous retrovirus, K10:

    ligne 109240 - numero d'artcile 3154
    K. (1996). J. Virol. 70: 771-777], were shown to reduce virus assembly

    ligne 109244 - numero d'artcile 3154
    R. B. (1994) J. Biol. Chem. 269: 28420-28428] released pelletable material

    ligne 110341 - numero d'artcile 3187
    HIV-1: fifteen proteins and an RNA.

    ligne 116679 - numero d'artcile 3380
    for alanines in the carboxy-terminal portion (amino acids 341-352: ATL EEM MTA

    ligne 118541 - numero d'artcile 3432
    (CTL) epitopes (Phillips, R. E. et al., Nature 1991. 354: 453) and are subject to

    ligne 118543 - numero d'artcile 3432
    USA 1997. 94: 1890). We studied the effects of naturally occurring mutations in

    ligne 123699 - numero d'artcile 3583
    Genetic variation in human immunodeficiency virus type 2: identification of a

    ligne 123721 - numero d'artcile 3584
    HIV-1 p17/p24: Ty virus-like particles (p24-VLP). All treated subjects showed

    ligne 130848 - numero d'artcile 3797
    Heteroduplex mobility assay for subtyping HIV-1: improved methodology and

    ligne 135730 - numero d'artcile 3946
    functions have been proposed for p6: incorporation of the HIV-1 accessory protein

    ligne 136736 - numero d'artcile 3977
    Incorporation of Vpr into human immunodeficiency virus type 1: role of conserved

    ligne 136954 - numero d'artcile 3983
    volunteers immunized with gag p24: Ty virus-like particles, a Th1 clone specific

    ligne 137998 - numero d'artcile 4015
    cyclosporin A, maps to chromosome 7p11.2-p13: four pseudogenes map to chromosomes

    ligne 138220 - numero d'artcile 4021
    of their own CTL (Klenerman et al., Nature 1994, 369: 403). The most important

    ligne 139531 - numero d'artcile 4062
    HIV-1 p17 synthetic peptide vaccine HGP-30: induction of immune response in human

    ligne 139920 - numero d'artcile 4074
    activity against human immunodeficiency virus (HIV) type 1: interference with HIV

    ligne 143849 - numero d'artcile 4194
    Genetic diversity of human immunodeficiency virus type 2: evidence for distinct

    ligne 145287 - numero d'artcile 4235
    The gag proteins of human immunodeficiency virus type 1: mechanisms of virus

    ligne 156473 - numero d'artcile 4580
    (F12) has been described (Federico et al, AIDS Res Hum Retrov 1989; 5: 365-96).

    ligne 156501 - numero d'artcile 4581
    p19: use in a specific capture enzyme immunoassay.

    ligne 157248 - numero d'artcile 4603
    presence of IgA antibodies to HIV-1: 44 samples were found positive and 37 were

    ligne 161732 - numero d'artcile 4745
    Sensitive non-radioactive detection of HIV-1: use of nested primers for the

    ligne 162287 - numero d'artcile 4762
    type 1: posttranslational modifications, proteolytic processings, and complete

    ligne 163427 - numero d'artcile 4797
    donor lacking anti-p24: a case report. The Transfusion Safety Study Group.

    ligne 163456 - numero d'artcile 4798
    Cells surviving infection by human immunodeficiency virus type 1: vif or vpu

    ligne 164464 - numero d'artcile 4830
    immunodeficiency virus type 1 p24: cytotoxic activity and secretion of

    ligne 166151 - numero d'artcile 4882
    (endpoint titers 1: greater than 500,000). Chimpanzees immunized with

    ligne 166153 - numero d'artcile 4882
    P18, respectively (endpoint titers 1: greater than or equal to 35,000).

    ligne 166155 - numero d'artcile 4882
    but were present at titers of 1: greater than or equal to 400 only in sera of 2

    ligne 166622 - numero d'artcile 4898
    (dilution endpoints 1: greater than 16,000, 1: greater than 80,000 for the nef

    ligne 167164 - numero d'artcile 4915
    Oligomeric nature of transmembrane glycoproteins of HIV-2: procedures for their

    ligne 167562 - numero d'artcile 4928
    Genomic diversity and antigenic variation of HIV-1: links between pathogenesis,

    ligne 167852 - numero d'artcile 4938
    Neutralization of HIV-1: a paradox of humoral proportions.

    ligne 170726 - numero d'artcile 5029
    higher CD4: CD8 ratios (0.92 versus 0.64; P = 0.004), lower immunoglobulin (Ig) G

    ligne 175099 - numero d'artcile 5177
    protein p25: comparative evaluation of in vitro HIV1 infection by

    ligne 175266 - numero d'artcile 5183
    MAP 30: a new inhibitor of HIV-1 infection and replication.

    ligne 177167 - numero d'artcile 5248
    A novel proviral clone of HIV-2: biological and phylogenetic relationship to

    ligne 178883 - numero d'artcile 5305
    April 1989: 29 cases of AIDS occurred during the follow-up period. The risk of

    ligne 180234 - numero d'artcile 5350
    p24: Ty virus-like particles (VLP). T cell lines from two immunized animals

    ligne 180235 - numero d'artcile 5350
    responded to p24: Ty-VLP, control Ty-VLP, purified p24, and whole inactivated

    ligne 182725 - numero d'artcile 5436
    Mother-to-infant transmission of human immunodeficiency virus type 1: association

    ligne 183383 - numero d'artcile 5460
    Human monoclonal antibodies to HIV-1: cross-reactions with gag and env products.

    ligne 183726 - numero d'artcile 5470
    HIV1 and HIV2: two ancient viruses for a new disease?

    ligne 187944 - numero d'artcile 5616
    The gag gene products of human immunodeficiency virus type 1: alignment within





    Imagine si



    la ligne
    Gag transport and virus particle formation. STRUCTURED SUMMARY: MINT-7014185: Gag
    était dans l'article numéro 4 ou 84 ou 184 ou 4184

    la ligne
    n=200, after 1997: n=375). RESULTS: Only CS mutations 431V and 452S were
    était dans l'article numéro 6 ou 96 ou 196 ou 1996

    la ligne
    Biopolymers 91: 283-296, 2009.This article was originally published online as an
    était dans l'article 90

    la ligne
    median, 2.5; interquartile range (IQR), 2.1-2.7; HIV-2: n = 22, median, 1.6; IQR,
    était dans l'article 1

    la ligne
    Beyond Tsg101: the role of Alix in 'ESCRTing' HIV-1.
    était dans l'article 100

    la ligne
    p19: use in a specific capture enzyme immunoassay.
    était dans l'article 8 ou 18

    la ligne
    MAP30: a new inhibitor of HIV-1 infection and replication.
    était dans l'article 29

    la ligne
    April 1989: 29 cases of AIDS occurred during the follow-up period. The risk of
    était dans l'article 8 ou 88 ou 988 ou 1988

    la ligne
    of their own CTL (Klenerman et al., Nature 1994, 369: 403). The most important
    était dans l'article 8 ou 68 ou 368

    etc etc

    Ton test if (num_str in line): s'allumerait sur ces lignes qui ne sont pas des lignes de titres d'article.

    En fait , ce cas n'existe pas dans ton fichier, je l'ai vérifié. Ce qui te sauve, c'est que tu as codé de telle façon que lorsque le programme a trouvé l'article n, il cherche ensuite l'article n+1 et non pas la prochaine ligne commençant par un "nombre: " quelconque. D'où il est relativement peu probable qu'un nombre n+1 soit dans l'article n.

    Mais cette probabilité n'est pas nulle, ni même négligeable,
    vu le nombre 107 de telles lignes , et compte tenu en outre que plusieurs situations pour chaque ligne pourrait donner une détection erronée.

    Il faut donc affiner ce test.

    if line.startswith(num_str ):
    est déjà mieux mais n'élimine pas entièrement tout risque:
    il y a 2 lignes qui commencent par"nombre: " sans être des lignes de titres:

    226: Virology. 2008 Sep 15;379(1):152-60. Epub 2008 Jul 26.

    Suboptimal inhibition of protease activity in human immunodeficiency virus type
    1: effects on virion morphogenesis and RNA maturation.
    3222: J Virol. 1998 Sep;72(9):7632-7.

    Resistance-associated loss of viral fitness in human immunodeficiency virus type
    1: phenotypic analysis of protease and gag coevolution in protease
    inhibitor-treated patients.
    La probabilité est cette fois très très faible, mais quand on est rigoureux on traite tout de même la possibilité






    Comme il semble que les titres d'article soient toujours du modèle suivant (en j'ai vérifié aussi que cette RE permet de trouver le même nombre de lignes de titres que la recherche de 'nombre: ' en début de ligne):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'nombre:(1 blanc)titre_de_revue.(1 blanc)annee(1 blanc ou ;)autres_caracteres\n'
    je propose le test suivant pour augmenter la fiabilité de caractérisation d'une ligne de titre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import re 
    patT = re.compile(r'\d{1,7}: .+\. (?:(?:19\d\d)|(?:20\d\d))(?: |;).+\n')
     
    if str(n)+': ' in li[i] and patE.match(li[i]):

    Regular expression:
    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
     
    \d  désigne un chiffre : '0' ou '1' ou '2' ou.... ou '9'
     
    {1,7} spécifie que 1 à 7 caracères comme celui indiqué devant {1,7} peuvent
     se suivre. Un maximum de 9999999 articles à analyser, je pense que ça peut
     aller....
     
    . = n'importe quel caractère sauf '\n'
    .+ signifie 1 ou plus fois le caractère qui précède le +, donc n'importe quel
    caractère sauf '\n' présent une fois ou  plus
     
    \. échappe le caractère spécial qu'est le point . et désigne simplement un
    vrai point '.'
     
    (...) constitue un groupe numéroté par le moteur de regex
    (?:...) est un rassemblement de caractères que le moteur de regex ne
     cherche pas à numéroter, donc on n'appelle pas ça un groupe --> ça va
     plus vite
     
    |  signifie OU
    (?:19\d\d)|(?:20\d\d) symbolise les années 1900 a 2099
    (?: |;) designe un blanc ou ;
    patE est une regex = un objet RE-compilée (personnellement je fais une différence entre RE qui est la chaine de représentation et regex qui est la RE compilée)
    patE.search(ch) cherche le motif représenté par RE partout dans ch
    patE.match(ch) ne cherche qu'à vérifier si le motif se trouve à partir du début de ch


    L'intérêt de garder ton test str(n)+': ' in li[i] en premier, c'est que sur toutes les lignes qui ne sont pas des lignes de titres, ce test sera faux et le programme ne cherchera pas à évaluer le deuxième test constitué d'une regex. Or ton test est plus rapide à évaluer que le test avec une regex.

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

    Cette étude de la vérification de la ligne de titre m'a conduit à modifier un peu mon idée concernant ton programme.

    Je pense depuis le début qu'il serait facile de développer un algorithme qui traiterait ton fichier sous forme de chaine, sans avoir à le transformer en liste. De mon point de vue, c'est plus cohérent avec la forme qu'a un fichier (c'est une succession de caractères; une liste est nécessairement une structure de donnée plus compliquée), ça donne un code plus concis et je pense que ce serait plus rapide.

    Dans un tel algorithme pour traiter ton fichier, il faut trouver successivement les débuts des lignes de titre dans une seule chaine, c'est à dire sans s'appuyer sur une liste des lignes.
    Il y a deux moyens de faire ça: avec une regex ou avec find().
    Avec find() seulement, la localisation est très rapide, mais il manque la vérification de la conformité de la ligne trouvée.
    Avec une regex, on a le problème de la lenteur des regex quand on les lance dans une recherche de localisation d'un motif dans une longue chaine. Par contre elles sont hyper-utiles pour sortir des données d'une chaine courte ou d'une portion de chaine quand on connait la localisation approximative de la portion dans une chaine plus longue.
    L'astuce, c'est de combiner les deux: find() localise, puis une regex extrait les données.

    Dans le cas de ton fichier, tu veux récupérer l'ensemble des donnès contenues dans chaque article, c'est à dire qu'entre deux lignes de titres il n'y a aucun déchet.
    Dans ce cas, une regex n'a pas à parcourir beaucoup de caractères pour passer d'un article au suivant. Je pense donc qu'on peut demander à une regex à la fois de localiser et d'extraire les données.
    Pour cela il faut utiliser finditer() , fonction absolument géniale.

    Je crains que l'idée ne te plaise pas beaucoup. Pourtant tu seras surpris de la rapidité à écrire un tel algorithme et de sa concision. Tout repose sur l'écriture d'une RE pouvant tout faire d'un coup, et ça c'est fastoche.


    Le début de la RE est ci-dessus, il suffit de continuer. Tu peux t'y essayer....si tu repasses ici avant d'avoir rendu ton sujet.

  18. #18
    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
    Ah oui merci Tyrus,
    mais j'ai écrit ce message hier à nicom avant qu'on se mette à parler de enumerate()

  19. #19
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par eyquem Voir le message
    30mn à 1mn30", c'est dire combien index() faisait du frottement !
    Oui
    Et maintenant c'est dire combien je me sens con de pas avoir compris ca du début... ^^

    Citation Envoyé par eyquem Voir le message
    Mais 1mn 30" , c'est encore 20 fois trop.
    L'élimination de index() était une chose nécessaire mais pas suffisante, on ne peut pas appeler ça une amélioration.
    Si on passe de 1'30" à 4 secondes, ce sera une amélioration.
    Je suis entièrement d'accord, mais il faut savoir que jusque ici je n'ai eu qu'une formation de trois mois en python a raison de 2h par semaine.
    Donc le probleme de l'évaluation du programme que je vais rendre est double :
    - premièrement si j'écris des choses qui ne sont pas de mon niveau et que le proff risque l'interpréter comme un copier-coller. Je risque le zéro pointé et les 5 ans sans examens nationnaux...
    - deuxièmement nous sommes tous notés les uns par rapport aux autres, c'est à dire que si le proffesseur voit qu'il y a un écart trop grands entre mon code et celui de mes camarades ceux ci risquent de voir leur note baisser.

    Et quelque part ça m'emmerde...

    Citation Envoyé par eyquem Voir le message
    Pour cela il faut une amélioration de l'algorithme à tous les niveaux.
    Le fait d'enelever index() ne change pas le fait que tu fais une accrétion progressive de lignes dans la variable organizing.
    Puis tu fais la mêm chose dans la sous-fonction donnes_traitement.
    Et il y a plein de trucs qui ne vont pas à droite et à gauche.
    Oui, mais ce faisant j'utilise mon cours c'est à dire les définition de fonctions et les variables global tout en 'parsant' un texte.

    Citation Envoyé par eyquem Voir le message
    Plutôt que de te décrire par le menu ce qui ne va pas, je crois qu'il vaut mieux s'attaquer à la racine directement:
    J'ai réfléchi à ton problème depuis l'autre jour et je pense qu'il se prête très bien à une utilisation de regex exclusivement, lancée sur ton fichier sous forme chaine, c'est à dire même pas la peine de le transformer en liste. Il n'y a même pas besoin de find().

    Mais il y a 3 problèmes:
    - en me voyant évoquer les regex, tu vas te dire "oh non non, trop compliqué".
    Pas du tout. Quand on connait les regex, le code s'écrit en une demie heure. Je connais suffisamment les regex pour faire ça.
    - je n'aime pas trop balancer un code tout fait. Mais je peux te donner les pistes, et écrire le code si tu bloques. Y en a pas pour 107 ans. Tu seras surpris de la vitesse avec laquelle ça peut se faire.
    - Tu as sans doute un problème de temps. Sans doute un projet à rendre à une certaine date, et de toutes façons tu n'as pas que ça à faire. Cependant, tu apprendrais pas mal de choses en peu de temps et tu aurais un code assez bon je crois.
    Je ne peux pas dire si c'est dur ou pas je n'ai jamais connu cette fonction (?) ou du moins cet outil avant.

    Citation Envoyé par eyquem Voir le message
    À toi de voir.
    Tout dépend de si tu auras encore besoin de ce code à l'avenir ou si c'est juste un devoir à jeter ensuite.
    Et si le code lui même est noté ou non. Tel quel, il vaut ......

    Je te mets de toutes façons dans le prochain message un aspect du problème auquel j'ai réfléchi et que je n'ai pas posté parce que je me demandais si tu allais repasser après la vex de l'autre jour.
    En soit, pour moi le code lui même n'a aucun intérêt. Je ne l'utiliserai sûrement jamais plus. C'est tout bêtement par passion pour l'informatique que j'ai choisit cette option. En effet j'ai codé mon premier 'HelloWorld" en C++ quand j'avais 12 ans et ensuite quelques programme de calculs trigonométrique basiques (à l'époque je faisait des rêves avec <include iostream.h> ^^)
    J'ai toujours été fasciné par la puissance d'un ordinateur.
    Et le temps n'est pas vraiment un obstacle, ou en tout cas un faux obstacle .
    On trouve toujours le temps de faire ce qui nous plaît

    Citation Envoyé par Tyrus Voir le message
    Ne pas utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in xrange(len(li)):
    mais

    c'est plus optimisé
    comme on n'a pu le voir dans le post précédent eyquem
    Oui, j'ai lu la doc que vous m'aviez passé sur les recherche de string et après quelque recherche sur google ('python : fonction xrange'), mais tout ça est assez complexe. Et j'ai peur d'utiliser des chose que je ne comprends pas... (en plus de trouver ça débile )

    ######

    Citation Envoyé par eyquem Voir le message
    if line.startswith(num_str ):
    est déjà mieux mais n'élimine pas entièrement tout risque:
    il y a 2 lignes qui commencent par"nombre: " sans être des lignes de titres:
    Je teste dès maintenant cette fonction

    Citation Envoyé par eyquem Voir le message
    La probabilité est cette fois très très faible, mais quand on est rigoureux on traite tout de même la possibilité

    Comme il semble que les titres d'article soient toujours du modèle suivant (en j'ai vérifié aussi que cette RE permet de trouver le même nombre de lignes de titres que la recherche de 'nombre: ' en début de ligne):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'nombre:(1 blanc)titre_de_revue.(1 blanc)annee(1 blanc ou ;)autres_caracteres\n'
    Oui, c'est exact.

    Citation Envoyé par eyquem Voir le message
    je propose le test suivant pour augmenter la fiabilité de caractérisation d'une ligne de titre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import re 
    patT = re.compile(r'\d{1,7}: .+\. (?:(?:19\d\d)|(?:20\d\d))(?: |;).+\n')
     
    if str(n)+': ' in li[i] and patE.match(li[i]):
    Ohlalalalaaaa...
    Ca fout quand même une sacrée frousse quand on voit cette ligne de code...
    ^^

    Citation Envoyé par eyquem Voir le message
    Regular expression:

    \d désigne un chiffre : '0' ou '1' ou '2' ou.... ou '9'

    {1,7} spécifie que 1 à 7 caracères comme celui indiqué devant {1,7} peuvent
    se suivre. Un maximum de 9999999 articles à analyser, je pense que ça peut
    aller....

    . = n'importe quel caractère sauf '\n'
    .+ signifie 1 ou plus fois le caractère qui précède le +, donc n'importe quel
    caractère sauf '\n' présent une fois ou plus
    Donc c'est comme ça que tu parcours chaque ligne du texte ?

    Citation Envoyé par eyquem Voir le message
    \. échappe le caractère spécial qu'est le point . et désigne simplement un
    vrai point '.'

    (...) constitue un groupe numéroté par le moteur de regex
    (?:...) est un rassemblement de caractères que le moteur de regex ne
    cherche pas à numéroter, donc on n'appelle pas ça un groupe --> ça va
    plus vite

    | signifie OU
    (?:19\d\d)|(?:20\d\d) symbolise les années 1900 a 2099
    ...?

    Citation Envoyé par eyquem Voir le message
    (?: | designe un blanc ou ;

    patE est une regex = un objet RE-compilée (personnellement je fais une différence entre RE qui est la chaine de représentation et regex qui est la RE compilée)
    patE.search(ch) cherche le motif représenté par RE partout dans ch
    patE.match(ch) ne cherche qu'à vérifier si le motif se trouve à partir du début de ch



    L'intérêt de garder ton test str(n)+': ' in li[i] en premier, c'est que sur toutes les lignes qui ne sont pas des lignes de titres, ce test sera faux et le programme ne cherchera pas à évaluer le deuxième test constitué d'une regex. Or ton test est plus rapide à évaluer que le test avec une regex.
    En fait, je crois que j'ai compris.
    Mais c'est vraiment trop complexe pour mon niveau.
    Imagine la tête de mon prof quand il va lire une ligne de code pareille.
    Il va tout doucement rigoler et si je met ce site dans les sources qui m'on permis de faire mon programme il va dire que j'ai pompé tout le code.
    (ce qui en soit ne sera pas entièrement faux).

    Citation Envoyé par eyquem Voir le message
    -------------------------------

    Cette étude de la vérification de la ligne de titre m'a conduit à modifier un peu mon idée concernant ton programme.

    Je pense depuis le début qu'il serait facile de développer un algorithme qui traiterait ton fichier sous forme de chaine, sans avoir à le transformer en liste. De mon point de vue, c'est plus cohérent avec la forme qu'a un fichier (c'est une succession de caractères; une liste est nécessairement une structure de donnée plus compliquée), ça donne un code plus concis et je pense que ce serait plus rapide.

    Dans un tel algorithme pour traiter ton fichier, il faut trouver successivement les débuts des lignes de titre dans une seule chaine, c'est à dire sans s'appuyer sur une liste des lignes.
    Il y a deux moyens de faire ça: avec une regex ou avec find().
    Avec find() seulement, la localisation est très rapide, mais il manque la vérification de la conformité de la ligne trouvée.
    Avec une regex, on a le problème de la lenteur des regex quand on les lance dans une recherche de localisation d'un motif dans une longue chaine. Par contre elles sont hyper-utiles pour sortir des données d'une chaine courte ou d'une portion de chaine quand on connait la localisation approximative de la portion dans une chaine plus longue.
    L'astuce, c'est de combiner les deux: find() localise, puis une regex extrait les données.

    Dans le cas de ton fichier, tu veux récupérer l'ensemble des donnès contenues dans chaque article, c'est à dire qu'entre deux lignes de titres il n'y a aucun déchet.
    Dans ce cas, une regex n'a pas à parcourir beaucoup de caractères pour passer d'un article au suivant. Je pense donc qu'on peut demander à une regex à la fois de localiser et d'extraire les données.
    Pour cela il faut utiliser finditer() , fonction absolument géniale.

    Je crains que l'idée ne te plaise pas beaucoup. Pourtant tu seras surpris de la rapidité à écrire un tel algorithme et de sa concision. Tout repose sur l'écriture d'une RE pouvant tout faire d'un coup, et ça c'est fastoche.


    Le début de la RE est ci-dessus, il suffit de continuer. Tu peux t'y essayer....si tu repasses ici avant d'avoir rendu ton sujet.
    Je vais me documenter sur finditer(), et je trouve assez incroyable le nombre de fonction que contient python (d'entrée de jeu).
    Mais je pense que je vais utiliser :
    Citation Envoyé par eyquem Voir le message
    if line.startswith(num_str ):
    Ce qui, avec la recherche par numéro de chaque article, je trouve, me permet d'avoir une probabilité d'erreur plus qu'acceptable
    Et m'occuper de la deuxième partie de mon cahier des charges qui est de trier chaque article par occurrence des mots clefs qu'il contient et les afficher dans l'ordre dans une page HTML.
    Parce que ça déjà ça risque de m'occuper un bout de temps.
    La deadline est dans 3 semaine donc je préfère commencer par faire en sorte que le programme fonctionne et ensuite je pense essayer de l'améliorer encore .
    Toutefois j'envisage de m'intéresser aux REGEX puisque cet été j'ai envie de coder un site web sans php en utilisant exclusivement python à sa place (je déteste php ...).

    Merci beaucoup de votre aide eyquem et tyrus.
    Ca m'a permit de gagner beaucoup de temps et de trouver pas mal de méthodes pour améliorer mes scripts.
    Je continuerai de fréquenter souvent ce forum, et si quelqu'un à besoin d'aide en quoi que ce soit dans le domaine de mes compétences (j'ai des super cours de physio, viro et immuno ) ce sera avec plaisir.

    A bientôt.

  20. #20
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par nicom1752 Voir le message
    Je vais me documenter sur finditer(), et je trouve assez incroyable le nombre de fonction que contient python (d'entrée de jeu).
    Eh oui, Python est fourni "batteries incluses"
    Citation Envoyé par nicom1752 Voir le message
    Parce que ça déjà ça risque de m'occuper un bout de temps.
    La deadline est dans 3 semaine donc je préfère commencer par faire en sorte que le programme fonctionne et ensuite je pense essayer de l'améliorer encore .
    Toutefois j'envisage de m'intéresser aux REGEX puisque cet été j'ai envie de coder un site web sans php en utilisant exclusivement python à sa place (je déteste php ...).
    Commence par modifier au fur et à mesure ton script avec des outils que tu maîtrises. Comme tu le dis, tu viens juste de commencer avec Python et tu as des scrupules par rapport à tes camarades de classe, mais je t'encourage à suivre les très bons conseils d'eyquem pour les expressions régulières, car elles sont très très utiles dès que tu as du texte un peu compliqué à analyser.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 13
    Dernier message: 20/04/2006, 15h37
  2. optimiser le code
    Par bibi2607 dans le forum ASP
    Réponses: 3
    Dernier message: 03/02/2005, 14h30
  3. syntaxe et optimisation de codes
    Par elitol dans le forum Langage SQL
    Réponses: 18
    Dernier message: 12/08/2004, 11h54
  4. GDT Descripteur de segment de code & segment de données
    Par Edouard Kaiser dans le forum x86 32-bits / 64-bits
    Réponses: 15
    Dernier message: 03/04/2004, 12h40
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

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