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 :

Débutant en Python : comment surveiller un répertoire pour déclencher une action


Sujet :

Python

  1. #61
    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
    Citation Envoyé par LeNarvalo Voir le message
    Le roi de la casse est retour !
    Quand on poste du code sans préciser l'intention de ce qu'on voulait faire dans une discussion ouverte par un autre sur un sujet complètement différent... En sans dire que vous l'avez recopié "ailleurs".

    Citation Envoyé par LeNarvalo Voir le message
    effbot.org est mourru et tkinter.fdex.eu aussi, ça devient de plus en plus difficile de trouver une information fiable et détaillée.
    La seule information fiable et détaillée qu'on trouve sur Tk est ici.

    Et si aujourd'hui le site fedex est en panne, espérons qu'il le remettent en marche très bientôt mais il y a un tas de ressources qui ont été collectées au fil des dans dans cette discussion.


    Citation Envoyé par LeNarvalo Voir le message
    Le but est de faire une autocomplétion.
    Désolé mais je ne vois pas le rapport entre ce code et ce que je connais côté autocomplétion (on tape le début et çà complète).
    Dire que l'intention n'est pas lisible dans le code est juste un fait.

    Citation Envoyé par LeNarvalo Voir le message
    Voilà le problème :
    https://stackoverflow.com/questions/...-to-solve-this
    Et leurs solutions me plaisent pas vraiment, je trouve ça assez lourd.
    Outre que çà ne fait pas d'autocomplétion, ça mérite ouvrez une discussion... ça fait partie des règles du forum (qui s'ajoutent à celle de l'apprentissage de la programmation).

    ça intéresse peut être d'autres personnes et si tant est qu'on arrive à trouver une solution intéressante, il sera difficile de la retrouver dans celle-ci déjà bien chargée.

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

  2. #62
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 952
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 952
    Points : 9 281
    Points
    9 281
    Par défaut
    1 - Pour ce problème
    Citation Envoyé par jurassic pork Voir le message
    hello,
    LeNarvalo, bravo pour ton script. Par contre j'ai un souci sur cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #Open and resize image
    img = Image.open(f)
    j'ai cette erreur : permissionerror

    en mettant une temporisation avant l'ouverture du fichier je n'ai plus d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #Open and resize image
    time.sleep(1)
    img = Image.open(f)
    à la place du time.sleep(1) j'ai mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    i = 0       
    while not os.access(f, os.R_OK):
         i=i+1
         print(i)
         time.sleep(0.1)
    et je n'ai plus d'erreurs mais ce qui est étonnant c'est que je ne passe pas dans la boucle comme si l'instruction os.access suffisait à résoudre le problème.

    2 - J'ai adapté ton code pour utiliser watchdog . Les gros avantages :
    A - watchdog ne dépend pas de l'o.s, par exemple il tourne aussi sous linux.
    B - Dans l'événement géré par watchdog pour la surveillance d'un répertoire, il y a la source (le fichier) qui a provoqué l'événement . Plus la peine de scruter le répertoire pour savoir ce qui a changé.
    Voici par exemple ce que cela donne au début du traitement de l'événement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
       def handle_watchdog_event(self, event):        
    """Called when watchdog posts an event"""
            watchdog_event = self.queue.get()
            print("event:", str(watchdog_event))
            if watchdog_event.event_type == 'created':
                f=watchdog_event.src_path
                print("Added : ",f)
               #Open and resize image
                i = 0
                while not os.access(f, os.R_OK):
                    i=i+1
                    print(i)
                    time.sleep(0.1)
                img = Image.open(f)
    C - On ne lance plus de thread, c'est watchdog avec son Observer qui gère tout cela.

    Voici une copié d'écran réalisée sous Ubuntu 20.04

    Nom : watchDogUbuntu.png
Affichages : 129
Taille : 102,8 Ko

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  3. #63
    Invité
    Invité(e)
    Par défaut
    @jurassic pork et je n'ai plus d'erreurs mais ce qui est étonnant c'est que je ne passe pas dans la boucle comme si l'instruction os.access suffisait à résoudre le problème.
    Du coup peut-être que la boucle est inutile ?

    Watchdog fonctionne pas sur un thread ?

    Chui pas fan des modules tiers, sauf quand j'ai pas le choix ou pas le niveau pour faire autrement. J'ai essayé d'éviter shutil par exemple dans mon script, mais j'ai été confronté à des problèmes de permissions qui m'ont découragé. Bref, j'aime bien réinventé la roue même si la mienne est généralement plus carré que circulaire.

  4. #64
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 952
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 952
    Points : 9 281
    Points
    9 281
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Du coup peut-être que la boucle est inutile ?
    oui on peut essayer de mettre seulement :

    Citation Envoyé par LeNarvalo Voir le message
    fonctionne pas sur un thread ?
    certainement mais lui il communique avec le thread principal par événement. La mise à jour de l'interface graphique est faite dans le traitement de l'événement dans le thread principal.


    Citation Envoyé par LeNarvalo Voir le message
    Chui pas fan des modules tiers, sauf quand j'ai pas le choix ou pas le niveau pour faire autrement. J'ai essayé d'éviter shutil par exemple dans mon script, mais j'ai été confronté à des problèmes de permissions qui m'ont découragé. Bref, j'aime bien réinventé la roue même si la mienne est généralement plus carré que circulaire.
    et pywin32 ce n'est pas un module tiers ?
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  5. #65
    Invité
    Invité(e)
    Par défaut
    et pywin32 ce n'est pas un module tiers ?
    Faux ce n'est pas !

  6. #66
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 952
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 952
    Points : 9 281
    Points
    9 281
    Par défaut
    hello,
    Citation Envoyé par LeNarvalo Voir le message
    Faux ce n'est pas !
    En fait qu'entends-tu par module tiers ? parce que watchdog est dans le dépôt pypi (4924 stars) et la dernière release date d'août 2021
    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  7. #67
    Futur Membre du Club
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Points : 9
    Points
    9
    Par défaut
    Bon, j'ai réussi à faire marcher la détection avec un after
    Je vous laisse débattre de l'élégance de mon code :

    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
     
    # Modules
    from tkinter import *
    from tkinter import ttk
    from tkinter.filedialog import *
    from openpyxl import load_workbook
    import os, time
    from os import listdir
    import win32file
    import win32event
    import win32con
    import threading, time
    from os.path import isfile, join
     
    RepertoireASurv="."
    before=""
    after=""
    Surveiller=False
     
    # Fonctions
    def ouvrir_fichier():
        FichierExcel = askopenfilename(title="Choisir une liste d'élèves",filetypes=[('Excel files','.xlsx'),('all files','.*')])
        Fichier = load_workbook(FichierExcel)
        Feuille = Fichier.active
        i=1
        LabelNomFichier['text']=FichierExcel
        liste.delete(0,END)
        for row in Feuille.iter_rows(min_row = 2, min_col = 1, max_col = 4, values_only=True):
            Eleve = row[0]+' '+row[1]+' '+row[2]
            liste.insert(i,Eleve)
            i=i+1
     
    def repertoire_asurv():
        global RepertoireASurv
        RepertoireASurv = askdirectory(title="Choisir le répertoire à surveiller")
        LabelRepertoire['text']=RepertoireASurv
        before = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
     
    def surveillance():
        global before,Surveiller
        if Surveiller:
            Surveiller=False
            BoutonSurveiller['text']="Surveiller"
        else:
            Surveiller=True
            BoutonSurveiller['text']="Surveillance active"
            before = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
     
    def surveiller_rep():
        global after, before, RepertoireASurv
        if Surveiller:
            after = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
            added = [f for f in after if not f in before]
            if added: print("Added: ", ", ".join (added))
            before = after
     
        Photoscol.after(1000,surveiller_rep)
     
    # Initialisations
     
    # Widgets et code
     
    Photoscol = Tk()
    Photoscol.title('Photoscol')
    Photoscol.geometry('1080x960')
    surveiller = 1
    #Bouton choix fichier élèves
    BoutonFichier = Button(Photoscol, text="Fichier élèves", command=ouvrir_fichier)
    BoutonFichier.grid(row=0, column = 0,sticky=NW, padx=10, pady=10)
     
    #Liste d'élèves en cours
    LabelNomFichier = Label(Photoscol, text="Choisir un fichier élèves", bg='#ffffff', width=50)
    LabelNomFichier.grid(row=0, column=1, sticky=NW, pady=10)
     
    #Bouton choix répertoire pdv
    BoutonRepertoire = Button(Photoscol, text="Répertoire de prise de vue", command=repertoire_asurv)
    BoutonRepertoire.grid(row=0, column = 2,sticky=NW, padx=10, pady=10)
     
    #Répertoire à surveiller
    LabelRepertoire = Label(Photoscol, text="Choisir un répertoire de prise de vue", bg='#ffffff', width=50)
    LabelRepertoire.grid(row=0, column=3, sticky=NW, pady=10)
     
    #Affichage liste élèves
    liste = Listbox(Photoscol, width=80, bg="Ivory", height=50)
    liste.grid(row=1, columnspan=2, sticky=NW)
     
    #Bouton surveillance
    BoutonSurveiller = Button(Photoscol, text="Surveiller", command=surveillance)
    BoutonSurveiller.grid(row=1, column=2, sticky=NW, padx=10, pady=10)
     
    #Sortir de l'appli
    BoutonQuitter = Button(Photoscol, text='Quitter', command=Photoscol.destroy)
    BoutonQuitter.grid(row=2, columnspan=2, padx=10, pady=40)
     
    Photoscol.after(1000,surveiller_rep)
     
    Photoscol.mainloop()
     
    # Fin widget et code
    Maintenant, faut que je renomme les fichiers détectés, je pensais simplement parcourir la liste "added", renommer les fichiers ainsi listés et les ajouter à la liste "before" avec la méthode append() ?

  8. #68
    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
    Citation Envoyé par Vincent-vr Voir le message
    ... et les ajouter à la liste "before" avec la méthode append() ?
    Ils sont déjà dans after... et ligne 55 vous avez écrit before = after pour la mettre à jour. Pourquoi changer çà?

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

  9. #69
    Futur Membre du Club
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Points : 9
    Points
    9
    Par défaut
    Parce qu'une fois renommés j'ai bien peur qu'il ne les reconnaisse plus

  10. #70
    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
    Citation Envoyé par Vincent-vr Voir le message
    Parce qu'une fois renommés j'ai bien peur qu'il ne les reconnaisse plus
    Si vous avez une réponse logique et cohérente au pourquoi faire ceci plutôt que cela, vous le codez et vous vérifier que çà le fait.

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

  11. #71
    Futur Membre du Club
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Points : 9
    Points
    9
    Par défaut
    C'est ce que j'ai fait en effet Et ça marche ! Je fignole ça et je vous soumet mon code pour voir si je n'ai pas pondu un truc affreux !

  12. #72
    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
    Citation Envoyé par Vincent-vr Voir le message
    Je fignole ça et je vous soumet mon code pour voir si je n'ai pas pondu un truc affreux !
    Un débutant écrit toujours des trucs affreux.
    C'est comme çà, mais si çà fonctionne c'est pas si grave.

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

  13. #73
    Futur Membre du Club
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Points : 9
    Points
    9
    Par défaut
    Quel a priori

    Bon ben voilà, ça fait ce que je veux, soit surveiller un répertoire de prise de vue donné et renommer les fichiers au fur et à mesure qu'ils arrivent avec la classe et le nom de l'élève sélectionné dans la liste importée depuis un fichier Excel.
    Ca fonctionne sans accroc même en déclenchant à 12 images par seconde... Ce qui est plutôt déconseillé au flash

    Plus qu'à fignoler un peu l'interface, comme passer en vert les élèves de la liste qui ont déjà des photos prises, histoire de pouvoir passer et revenir sur un élève qui se serait absenté momentanément (il y en a toujours qui stressent et qui doivent aller faire pipi )...

    Merci à LeNarvalo d'avoir pris la peine de me faire un exemple avec un thread, faudra que je m'y mette plus tard, à chaque jour suffit sa peine

    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
     
    # Modules
    from tkinter import *
    from tkinter import ttk
    from tkinter.filedialog import *
    from openpyxl import load_workbook
    import os, time
    from os import listdir
    import win32file
    import win32event
    import win32con
    import threading, time
    from os.path import isfile, join
     
    RepertoireASurv="."
    before=""
    after=""
    Surveiller=False
     
    # Fonctions
    def ouvrir_fichier():
        FichierExcel = askopenfilename(title="Choisir une liste d'élèves",filetypes=[('Excel files','.xlsx'),('all files','.*')])
        Fichier = load_workbook(FichierExcel)
        Feuille = Fichier.active
        i=1
        LabelNomFichier['text']=FichierExcel
        liste.delete(0,END)
        for row in Feuille.iter_rows(min_row = 2, min_col = 1, max_col = 4, values_only=True):
            Eleve = row[0]+' '+row[1]+' '+row[2]
            liste.insert(i,Eleve)
            i=i+1
     
    def repertoire_asurv():
        global RepertoireASurv
        RepertoireASurv = askdirectory(title="Choisir le répertoire à surveiller")
        LabelRepertoire['text']=RepertoireASurv
        before = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
     
    def surveillance():
        global before,Surveiller
        if Surveiller:
            Surveiller=False
            BoutonSurveiller['text']="Surveiller"
        else:
            Surveiller=True
            BoutonSurveiller['text']="Surveillance active"
            before = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
     
    def surveiller_rep():
        global after, before, RepertoireASurv
        if Surveiller:
            after = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
            added = [f for f in after if not f in before]
            if added:
                #print("Added: ", ", ".join (added))
                for fichier in added:
                    NouveauFichier=liste.get(ACTIVE).replace(" ","_")+"_"+fichier[-8:]
                    renommerOK=False
                    while renommerOK!=True:
                        try :
                            os.rename(RepertoireASurv+'/'+fichier,RepertoireASurv+'/'+NouveauFichier)
                            renommerOK=True
                        except IOError :
                            #fichier occupé
                            renommerOK=False
                    before.append(NouveauFichier)
     
        Photoscol.after(1000,surveiller_rep)
     
    # Initialisations
     
    # Widgets et code
     
    Photoscol = Tk()
    Photoscol.title('Photoscol')
    Photoscol.geometry('1080x960')
    surveiller = 1
    #Bouton choix fichier élèves
    BoutonFichier = Button(Photoscol, text="Fichier élèves", command=ouvrir_fichier)
    BoutonFichier.grid(row=0, column = 0,sticky=NW, padx=10, pady=10)
     
    #Liste d'élèves en cours
    LabelNomFichier = Label(Photoscol, text="Choisir un fichier élèves", bg='#ffffff', width=50)
    LabelNomFichier.grid(row=0, column=1, sticky=NW, pady=10)
     
    #Bouton choix répertoire pdv
    BoutonRepertoire = Button(Photoscol, text="Répertoire de prise de vue", command=repertoire_asurv)
    BoutonRepertoire.grid(row=0, column = 2,sticky=NW, padx=10, pady=10)
     
    #Répertoire à surveiller
    LabelRepertoire = Label(Photoscol, text="Choisir un répertoire de prise de vue", bg='#ffffff', width=50)
    LabelRepertoire.grid(row=0, column=3, sticky=NW, pady=10)
     
    #Affichage liste élèves
    liste = Listbox(Photoscol, width=80, bg="Ivory", height=50)
    liste.grid(row=1, columnspan=2, sticky=NW)
     
    #Bouton surveillance
    BoutonSurveiller = Button(Photoscol, text="Surveiller", command=surveillance)
    BoutonSurveiller.grid(row=1, column=2, sticky=NW, padx=10, pady=10)
     
    #Sortir de l'appli
    BoutonQuitter = Button(Photoscol, text='Quitter', command=Photoscol.destroy)
    BoutonQuitter.grid(row=2, columnspan=2, padx=10, pady=40)
     
    Photoscol.after(1000,surveiller_rep)
     
    Photoscol.mainloop()
     
    # Fin widget et code

  14. #74
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    Bon ben voilà, ça fait ce que je veux
    Juste un truc qui me saute aux yeux sur cette ligne: ater = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]: Si "after" doit être la liste des fichiers d'un dossier, alors vu qu'un dossier ne peut pas avoir deux fichiers de même noms, "after" n'aura que des noms uniques. De là, peut-être alors remplacer la liste par un ensemble peut optimiser encore un peu le bouzin (et pareil pour "added"). D'autant plus que les ensembles possèdent des opérateurs d'union et d'intersection qui peuvent alors eux aussi montrer leur plein potentiel.
    Seul bémol: dans un ensemble, les fichiers sont stockés dans un ordre interne Python qui n'a rien d'humain. Si les fichiers doivent être affichés ensuite ça peut être un souci. Souci qui peut être résolu alors avec sorted().
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #75
    Invité
    Invité(e)
    Par défaut
    @Vicent-vr
    Tiens du fignolage, ligne 29, tu peux utiliser join par exemple, ça fait plus pro... (Je te dis ça alors que je n'utilise presque pas ces fonctions)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> row = ('Toto','Dupont','15')
    >>> Eleve = ' '.join(x for x in row)
    >>> Eleve
    'Toto Dupont 15'
    Et puis je me répète, tu peux utiliser enumerate() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for i, row in enumerate(Feuille.iter_rows(min_row = 2, min_col = 1, max_col = 4, values_only=True)):
            Eleve = ' '.join(x for x in row)
            liste.insert(i,Eleve)
    Ah tiens ça c'est bien ligne 37, 47 et 52 ! J'apprends/revois un truc : join(RepertoireASurv, f).
    Mais tu peux te passer complètement d'utiliser isfile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    next(files  for root, dirs, files in os.walk(directory_to_survey))
    Ca fait intervenir des notions un peu compliqué pour un débutant et que je ne maitrise pas vraiment, os.walk est un générateur qui parcours tout un dossier et ses sous-dossiers.
    Contrairement à une liste de compréhension (ex: [x for x in [1,2,3]]), le générateur marche par étape donc on peut ne demander que la première étape avec next(), là où il n'analyse que les fichiers et sous-dossiers qu'il contient (pas les sous-sous-dossier, sous-fichiers, ...)
    Nom : 22222.PNG
Affichages : 95
Taille : 82,2 Ko

    Ligne 57 Ca je pense que c'est améliorable ! =) Pourquoi -8 ? C'est lié à la longueur du numéro que te renvois ton appareil photo ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NouveauFichier=liste.get(ACTIVE).replace(" ","_")+"_"+fichier[-8:]
    Ligne 58 J'ai vu que tu avais aussi des problèmes de renommage ?
    Tu peux peut-être utiliser os.access plutôt que de faire un try except ? (Pareil je ne suis pas une référence là dessus !) Cf. jurassic pork.

    Ligne 77 Tu peux utiliser la class Photoscol, pour stocker les variables que tu veux rendre "globales" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> from tkinter import *
    >>> root = Tk()
    >>> root.variable = 5
    >>> def tata():
    	print('tata() -> ',root.variable)
     
     
    >>> def toto(x):
    		root.variable = x
    		tata()
     
     
    >>> toto(6)
    tata() ->  6
    Ca sera tout pour moi !

  16. #76
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Tiens du fignolage, ligne 29, tu peux utiliser join par exemple, ça fait plus pro...>>> Eleve = ' '.join(x for x in row)
    >>> Eleve = ' '.join(row)

    Citation Envoyé par LeNarvalo Voir le message
    Ah tiens ça c'est bien ligne 37, 47 et 52 ! J'apprends/revois un truc : join(RepertoireASurv, f).
    Ca c'est le join() de os.path mais ça m'a aussi surpris, ayant plus l'habitude de l'utiliser sous sa dénomination complète...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  17. #77
    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,

    Pour compléter les remarques de Sve@r...

    Citation Envoyé par LeNarvalo Voir le message
    Ligne 77Tu peux utiliser la class Photoscol, pour stocker les variables que tu veux rendre "globales"
    Photoscol n'est pas une "class" mais une instance de Tk.

    Y ajouter des attributs à la volée, c'est juste du travail de cochon: si on fabrique des "class", c'est pour éviter que l'espace de nommage définit soit pollué par l'extérieur et limiter le nombre de variables "globales".

    Cette idée peut être mise en œuvre plus "proprement" en créant une "class globs" et en accédant aux attributs à modifier via globs.v1, globs.v2,... au lieu des variables v1, v2 sans omettre de les déclarer "global".

    Mais techniquement ça n'a aucun intérêt pour de petits programmes où le nombre de variables globales est raisonnable et où seul un petit nombre de fonctions les modifient (les autres y accédant en lecture).

    Lorsqu'on est un peu moins débutant, on peut constater que le mot clef global n'est nécessaire que pour mettre à jour des objets non mutables: str, int, float,...

    Exemple ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def repertoire_asurv():
        global RepertoireASurv
        RepertoireASurv = askdirectory(title="Choisir le répertoire à surveiller")
        LabelRepertoire['text']=RepertoireASurv
        ....
    Déjà LabelRepertoire est une variable globale associée à un objet "mutable".
    on peut récupérer son contenu via s = LabelRepertoire['text'].
    La variable globale RepertoireASurv est superflue.

    Si on connait un peu tkinter, on sait que les Label sont des widgets qui acceptent une variable (Tk cette fois) qui sont des objets mutables. Utiliser un StringVar permet aussi de se débarrasser de cette variable globale et pas besoin côté fonction de savoir quels Labels, Entry, Button,... y sont associés pour que leur mise à jour soit affichée automatiquement

    On peut aussi coder pour éviter les variables globales.
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def surveillance():
        global before,Surveiller
        if Surveiller:
             ....
        else:
            Surveiller=True
            BoutonSurveiller['text']="Surveillance active"
            before = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
     
    def surveiller_rep():
        global after, before, RepertoireASurv
        if Surveiller:
              .....
         Photoscol.after(1000,surveiller_rep)
    Le parti du PO a été de faire tourner en permanence surveiller_rep, la variable "Surveiller" contrôlant l'activité (on passe ou pas dans le block du if).

    On peut aussi démarrer et arrêter via l'action sur le Button:
    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
    def surveillance():
        global Surveiller
        if Surveiller:
             ....
        else:
            Surveiller=True
            BoutonSurveiller['text']="Surveillance active"
            before = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
            surveiller_rep(before)
     
    def surveiller_rep(before):
        global RepertoireASurv
        if not Surveiller:
              .....
              #mise à jour de before.
         Photoscol.after(1000,surveiller_rep, before)
    note: je n'ai pas remplacé les autres variables globales par des variables Tk... mais l'un dans l'autre, plus de mot clef global.

    Mais un travail de compréhension n'a rien à voir avec cacher la poussière sous le tapis parce qu'on a la hantise des variables globales (qui n'existent pas en Python).
    Et c'est sur que ce genre de considération est inutile pour le débutant qui code à l'arrache pour que çà fonctionne au plus vite. Programmer proprement et programmer juste pour ce çà fonctionne, c'est pas la même chose côté dette technique (l'effort qu'on devra faire pour améliorer un peu le programme plus tard).

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

  18. #78
    Invité
    Invité(e)
    Par défaut
    @Wiz
    Pourtant on ajoute parfois des attributs aux instances de classe comme l'explique le tuto developpez.com : label.image
    En tout cas, rajouter des attributs me facilite la saisie et ça me permet de faire moins d'oubli qu'avec global.

    Ici, comme tu le dis, le plus simple c'est encore de récupérer le contenu de l'option text du bouton surveiller : BoutonSurveiller['text'].

    Sinon c'est une bonne suggestion : next(files for root, dirs, files in os.walk(directory_to_survey)) pour remplacer le test isfile ?

  19. #79
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Pourtant on ajoute parfois des attributs aux instances de classe comme l'explique le tuto developpez.com : label.image
    C'est faisable mais un petit peu dangereux car deux instances différentes d'une même classe n'ont alors plus les mêmes attributs => tu ne peux plus créer un traitement généralisé...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class personne:
    	def __init__(self, nom):
    		self.nom=nom
     
    >>> p1=personne("LeRoi")
    >>> p1.prenom="Arthur"
    >>> p2=personne("Autre")
    >>> for x in (p1, p2):
    ...	print(x.nom, x.prenom)
    LeRoi, Arthur
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: personne' object has no attribute 'prenom'

    Perso je m'astreints toujours à définir tous mes attributs dans le __init__(). Et j'utilise l'attribut global "__slots__" pour éviter la possibilité de rajouter un attribut non prévu
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class personne:
    	__slots__=("nom", "prenom")
     
    	def __init__(self, nom, prenom):
    		self.nom=nom
    		self.prenom=prenom
     
    >>> p=personne("LeRoi", "Arthur")
    >>> p.age=800
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'personne' object has no attribute 'age'

    Citation Envoyé par LeNarvalo Voir le message
    En tout cas, rajouter des attributs me facilite la saisie et ça me permet de faire moins d'oubli qu'avec global.
    Effectivement. Le global est un outil mais l'utiliser à tort et à travers dans une solution de facilité fait qu'on le paye toujours tôt ou tard. Et plus on le paye tard, plus on le paye cher.

    Citation Envoyé par LeNarvalo Voir le message
    Sinon c'est une bonne suggestion : next(files for root, dirs, files in os.walk(directory_to_survey)) pour remplacer le test isfile ?
    Effectivement os.walk() te range d'un côté les dossiers et de l'autre les fichiers. Et il gère aussi les liens symboliques.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  20. #80
    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
    Citation Envoyé par LeNarvalo Voir le message
    Pourtant on ajoute parfois des attributs aux instances de classe comme l'explique le tuto developpez.com : label.image
    Dans ce cas, on cannibalise une instance de Label pour ajouter une référence à une image. Dans l'exemple, çà ne sert à rien puisque photo (variable qui référence l'Image TK) est déjà globale.

    Ca peut aider lorsqu'on écrit un brouillon de code... mais on ne peut pas le recommander de façon "générale" comme ici:
    Ligne 77Tu peux utiliser la class Photoscol, pour stocker les variables que tu veux rendre "globales"
    Citation Envoyé par LeNarvalo Voir le message
    En tout cas, rajouter des attributs me facilite la saisie et ça me permet de faire moins d'oubli qu'avec global.
    On a besoin du mot clef global que pour les objets non-mutables.

    Comme on essaie toujours d'écrire des fonctions pures (qui n'accèdent qu'aux arguments qu'on leur passe) et de faire méthodes toutes celles qui modifient l'état d'un objet qui change l'état du programme, le mot clef global ne sert presque qu'au débutant ou faire des brouillons de code à la va vite.

    Citation Envoyé par LeNarvalo Voir le message
    Sinon c'est une bonne suggestion : next(files for root, dirs, files in os.walk(directory_to_survey)) pour remplacer le test isfile ?
    L'intention est de récupérer la liste des entrées d'un répertoire à l'instant T pour trouver les nouvelles entrées à l'instant T+1.

    Pendant que le programme tourne, est-ce qu'on va s'amuser à créer des sous-répertoires dans le répertoire en question? Probablement que non... et le tri (même avec isfile) ne sert à rien.

    Par contre, probable que l'appareil qui prend des photos créer ses fichiers suivant un pattern régulier genre "IMGnnnnn.JPG". glob.glob permettrait de ne sélectionner que ceux là (et de ne pas attraper autre chose que des fichiers image).

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 10/08/2011, 11h16
  2. comment surveiller un répertoire à distance?
    Par rainy_kll dans le forum Développement de jobs
    Réponses: 2
    Dernier message: 08/07/2010, 18h04
  3. Réponses: 2
    Dernier message: 31/12/2008, 12h16
  4. Réponses: 7
    Dernier message: 21/10/2004, 09h13
  5. [PowerAMC] Comment s'en servir pour creer une base?
    Par Elmilouse dans le forum Access
    Réponses: 2
    Dernier message: 27/07/2004, 09h53

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