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. #81
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    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é...
    [...]
    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
    Ouai ça me paraît pas très dangereux dans le sens où l'erreur est claire et assez attendue, je m'attendais à un truc plus saugrenu.
    Après je comprends bien que ce n'est pas conventionnel de faire ce que je fais, bien que je pensais que ça l'était vu que ça paraît un peu partout sur le net.

    Sinon je ne soupçonnais pas l'existence du "__slots__", c'est un truc de capitaliste ! ^^
    "Tu ne rajouteras pas des attributs à mon instance de classe ! C'est à moi !!!"

    PS : J'imagine bien que ça à son utilité, humour, tout ça...

  2. #82
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 235
    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 235
    Points : 36 684
    Points
    36 684
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    bien que je pensais que ça l'était vu que ça paraît un peu partout sur le net.
    Ce qu'on voit partout n'est pas forcément "réfléchi".
    Et le code qu'on trouve ici ou là doit être revu avec précaution avant d'être utilisé.

    Le principal problème est qu'on préfère obtenir un résultat rapidement plutôt que d'apprendre à programmer et à développer son esprit critique sur les codes qu'on trouve: çà marche, on emporte sans réfléchir... et on réutilise une solution "pragmatique" a une situation donnée un peu n'importe comment.

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

  3. #83
    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
    Le isfile me permet justement de palier à une erreur possible : oublier d'arrêter la surveillance et démarrer une nouvelle session dans le logiciel photo en créant le répertoire dans le répertoire de la précédente session au lieu de remonter au répertoire au-dessus Il y a (très) longtemps j'ai appris qu'il faut toujours considérer l'utilisateur complètement idiot et prévoir les manipulations les plus farfelues ! J'avais un prof lorsqu'on présentait un projet de programmation qui commençait par taper n'importe quoi sur le clavier comme le ferait votre chat se promenant sur votre clavier ou un jeune enfant le prenant pour un piano Si ça se bananait, -2...
    Je ne sais pas comment interagir avec le logiciel photo, s'il faut que je me plonge dans le SDK je ne suis pas rendu... Peut-être un we pluvieux cet hiver si je n'ai rien d'autre à faire...

    Désolé si je n'ai pas pris le temps de passer des semaines à comprendre toutes les subtilités du langage, j'ai besoin que ça marche avant le 24/09 ! Enfin bon, en parallèle j'ai attaqué la lecture de "apprendre à programmer en Python 3"

    Je n'ai la hantise de rien du tout, j'ai pratiqué moult langages avec des variables globales et ne pas en avoir m'a justement interpelé

    Je note avec joie toutes vos remarques constructives pour améliorer mon code, car je ne compte pas en rester là et pense à :
    - charger les listes dans une BDD
    - générer les bons de commande pour chaque élève et fratrie en fonction des formats choisis par l'école
    - saisir les bons de commande et générer les fichiers images pour ne pas se poser de question à l'impression

  4. #84
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 630
    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 630
    Points : 30 860
    Points
    30 860
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    Le isfile me permet justement de palier à une erreur possible : oublier d'arrêter la surveillance et démarrer une nouvelle session dans le logiciel photo en créant le répertoire dans le répertoire de la précédente session au lieu de remonter au répertoire au-dessus
    Pour ça (éviter de pouvoir appeler deux fois un même programme) il existe différentes astuces (créer un fichier lock etc). Mais cela peut poser souci si le programme plante (faut alors libérer le lock manuellement). Il existe une autre astuce qui n'a pas cet inconvénient: le programme crée un serveur neutre qui se connecte sur un port de ta machine. Si on le lance une seconde fois, le port est déjà occupé...
    Code python : 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
    #!/usr/bin/env python3
    # coding: utf-8
     
    import socket
     
    def serveur(port):
    	# Il est nécessaire de créer la variable comme attribut de la fonction pour qu'elle ne soit pas détruite quand la fonction se termine
    	serveur.connect=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     
    	try:
    		serveur.connect.bind(("", port))
    	except OSError:
    		return False
    	else:
    		return True
    # serveur()
     
    if __name__ == "__main__":
    	import sys
    	if serveur(50000):
    		input("ok")					# Pour éviter qu'il ne s'arrête (et pouvoir en lancer un autre pendant ce temps)
    	else:
    		print("Programme %s déjà lancé" % sys.argv[0])
    # if

    Citation Envoyé par Vincent-vr Voir le message
    Il y a (très) longtemps j'ai appris qu'il faut toujours considérer l'utilisateur complètement idiot et prévoir les manipulations les plus farfelues !
    Tout à fait. C'est ce qu'on nomme "le test du crétin". Mais déjà avec les IHM on peut grandement limiter les manipulations possibles comme griser/dégriser certaines zones et objets quand c'est nécessaire par exemple (je le fais énormément dans mes applis)...

    Citation Envoyé par Vincent-vr Voir le message
    Je n'ai la hantise de rien du tout, j'ai pratiqué moult langages avec des variables globales et ne pas en avoir m'a justement interpelé
    Déjà Python possède aussi les globales mais généralement les utiliser à outrance n'est jamais une bonne idée. Dans 99,9% du temps on n'en a pas besoin.

    Citation Envoyé par Vincent-vr Voir le message
    Je note avec joie toutes vos remarques constructives pour améliorer mon code, car je ne compte pas en rester là et pense à :
    - charger les listes dans une BDD
    Python possède en interne une mini bdd nommée "sqlite3". Elle a tout d'une grande, seul souci: elle ne permet pas le multi-utilisateurs. Si ce pb ne t'importe pas alors tu peux partir là dessus...
    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]

  5. #85
    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
    Ce n'est pas du lancement une deuxième fois de l'application dont je parlais, mais bien simplement la création extérieure à l'application d'un nouveau répertoire depuis le logiciel photo. Là je vois pas de gestion depuis le programme Python...

    J'ai vu en effet qu'il y avait une BDD intégrée à Python, je vais me pencher dessus ! Non, pas besoin de plusieurs utilisateur, je serai le seul à m'en servir

  6. #86
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 235
    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 235
    Points : 36 684
    Points
    36 684
    Par défaut
    Salut,

    Citation Envoyé par Vincent-vr Voir le message
    Là je vois pas de gestion depuis le programme Python...
    Le soucis est de voir apparaître dans added autre chose que ce qu'on attend.

    Ce added est construit à partir de la différence dans le contenu du répertoire entre les instants T et T+1.

    Dans votre mouture, la surveillance du répertoire commence avant la prise de toutes les photos et renomme le premier fichier d'added en fonction de l'entrée de la liste ou est positionné le curseur (le .get(ACTIVE)).

    Si on démarre la surveillance après (la validation d')un ListboxSelect et qu'on l'arrête dès que le fichier a été renommé, on limite la possibilité de récupérer d'autres ajouts.

    En plus je suis sûr que les fichiers créés on un nom qui suit un pattern particulier ne récupérer que les fichiers qui ont ce pattern là (avec glob.glob) réduirait la possibilité de récupérer autre chose que ce qu'on attend.
    Et comme peu probable que les fichiers renommés "matchent" ce pattern, after ne devrait contenir qu'un fichier (et before devient inutile).

    note: ma remarque sur le sujet était en réponse à la question de LeNarvalo. Concernant votre code, comme je l'ai déjà dit, c'est un truc de débutant. Ca fonctionne pour vous, c'est très bien tant qu'il y a une cohérence entre ce que vous voulez et les moyens que vous vous donnez pour le réaliser.

    Citation Envoyé par Vincent-vr Voir le message
    J'avais un prof lorsqu'on présentait un projet de programmation qui commençait par taper n'importe quoi sur le clavier comme le ferait votre chat se promenant sur votre clavier ou un jeune enfant le prenant pour un piano
    C'est ce qu'on fait dans les phases de (bonnes) recettes (avant de se lancer dans la suite des fiches de tests).

    Citation Envoyé par Vincent-vr Voir le message
    Désolé si je n'ai pas pris le temps de passer des semaines à comprendre toutes les subtilités du langage
    Au plus vous allez ajouter des fonctionnalités, au plus la dette technique sera importante. Et un forum de discussion ne pourra pas payer cette dette à votre place.

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

  7. #87
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Salut

    Les réponses ont été assez copieuses sur ce sujet. J'ai parcouru les 5 pages de réponses, mais je n'ai pas vu une suggestion qui me parait très simple à mettre en oeuvre pour un débutant et qui n'a pas été suggérée (à moins que je sois passé à côté), donc je vais la faire.

    Pourquoi ne pas faire une IHM qui ne surveille pas le contenu du répertoire ? Je précise. Vous lancez votre appli, au démarrage elle scanne le contenu du répertoire à traiter et stocke la liste des fichiers en mémoire. Là vous démarrez votre séance photo, première élève, hop vous faites les photos. Autant que vous voulez (une ou plusieurs). Une fois terminez, vous avez un bouton "élève suivant" dans votre app, qui vous ouvre une petite fenêtre, vous demandant de taper le nom de l'eleve (ou bien de le sélectionner dans une liste si vous avez parser déjà un csv ou autre par exemple), puis une fois fait cela, refera un scan du répertoire, et renommera tous les nouveaux fichiers apparus depuis le dernier scan. Et ainsi de suite, on continu nouvel élève, nouvelles prises de photos, on rentre le noms, et sa renomme derrière juste après avoir spécifier le nom de l'élève.

    Cette manière me semble beaucoup plus simple à programmer car vous n'avez pas besoin de monitorer ce qui se passe sur votre disque dur. Juste vous dites, là j'ai fait tel élève, et à ce moment là, ca traite les fichiers pour tel élève. Donc très séquentiel comme raisonnement.

    Après si on veut modifier un peu l'utilisation, du style, demander le nom de l'élève avant de le prendre en photo plutôt qu’après, c'est possible aussi toujours en séquentiel. On peut imaginer des boutons aussi pour revenir en arrière, etc ...

    On peut aussi imaginer une première mouture sans tkinter (donc une IHM ultra basique), avec juste un truc en ligne de commande. Sans avoir pu tester correctement, en moins de 20 lignes (qui sont aussi optimisable/améliorable, j'ai fait ça rapidement), on peut avoir qqch qui fait le job :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import os
    dirtoscan = '.' ### Le dossier dans lequel le logiciel place les photos
     
    while True:
    	lstdir = os.listdir(dirtoscan)
    	name = input("nom de l'eleve que vous venez de photographier (taper exit pour terminer): ")
    	newlstdir = os.listdir(dirtoscan)
    	newfiles = [f for f in newlstdir if f not in lstdir]
    	for k,newfile in enumerate(newfiles) :
    		f1 = os.path.join(dirtoscan,newfile) ## le fichier à renommer
    		f2 = os.path.join(dirtoscan,name+"_"+str(k+1)) ## le fichier renommé
                    print('Renommage ',f1,'--->', f2)
    		os.rename(f1,f2)
    	if name == "exit": break
    Pour tester il faudrait soit avoir votre logiciel de création de photo, soit créer des fichiers factices à la main entre deux saisies de nom d'élèves.

  8. #88
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 235
    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 235
    Points : 36 684
    Points
    36 684
    Par défaut
    Citation Envoyé par lg_53 Voir le message
    Pourquoi ne pas faire une IHM qui ne surveille pas le contenu du répertoire ? Je précise. Vous lancez votre appli, au démarrage elle scanne le contenu du répertoire à traiter et stocke la liste des fichiers en mémoire.
    C'est ce que fait (à peu près) le code du PO. La différence est que plutôt que de déclencher un scan du répertoire et de renommer à la demande, c'est fait toutes les secondes en renommant l'image en fonction de l'élève actif dans la liste.

    La question initiale du PO était de surveiller l'arrivée de fichier dans un répertoire. Difficile de ne pas comparer avant/après (ou de passer par une bibliothèque évènementielle genre watchdog). Comme on veut associer un fichier juste arrivé à l'élève qu'on vient de photographier, "avant" c'est la sélection de l'élève dans la liste au plus tard et "après", c'est lorsqu'on a récupéré le fichier a lui associer.

    Ce qui me gène dans toutes ces logiques est qu'on fait l'hypothèse que le fichier arrivera assez vite dans le répertoire (avant de passer au suivant). Probable que çà va vite mais si on ne contrôle pas qu'on a pu associer un
    fichier à l'élève courant... on pourra avoir des résultats étranges.

    Réduire "après" au choix de l'élève suivant pouvant être fortuit (un clic malencontreux) n'apporte pas grand chose.

    Après c'est juste un prototype, donc çà va bouger... et si le PO peut faire quelque chose de toutes les idées qu'on a pu lui suggérer tant mieux pour lui.

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

  9. #89
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 630
    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 630
    Points : 30 860
    Points
    30 860
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lg_53 Voir le message
    mais je n'ai pas vu une suggestion qui me parait très simple à mettre en oeuvre pour un débutant et qui n'a pas été suggérée (à moins que je sois passé à côté) Pourquoi ne pas faire une IHM qui ne surveille pas le contenu du répertoire ?
    Ben... parce que le sujet du topic était "surveiller un répertoire"...

    Citation Envoyé par lg_53 Voir le message
    Une fois terminé, vous avez un bouton "élève suivant" dans votre app ... cela, refera un scan du répertoire
    A mon avis, entre "scanner un répertoire sur action d'un bouton" et "scanner un répertoire quand un timer donne le go" il n'y a pas beaucoup de différence...
    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]

  10. #90
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 235
    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 235
    Points : 36 684
    Points
    36 684
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    A mon avis, entre "scanner un répertoire sur action d'un bouton" et "scanner un répertoire quand un timer donne le go" il n'y a pas beaucoup de différence...
    Je crois surtout que le PO a choisi l'option d'une surveillance permanente dès le départ et qu'il s'y est accroché jusqu'au bout... en la faisant marcher coute que coute.

    Ce n'est pas une critique, c'est une attitude que je préfère à celle de récupérer un code qu'on ne comprend pas plutôt que de faire avec les connaissances qu'on a.

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

  11. #91
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Au cas où, il existe dans PyQt5 une classe qui surveille les modifications des répertoires et des fichiers: QtCore.QFileSystemWatcher.

    Voilà un petit exemple tout simple, qui surveille toutes les modifications du répertoire "E:\Temp\Toto" et du fichier "E:\Temp\Toto\titi.txt":

    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
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
     
    """
    Surveillance des modifications de répertoires et de fichiers
    """
     
    import sys
    import os
     
    from PyQt5 import QtCore
     
    ##############################################################################
    def repertoire_change(chemin):
        print('Répertoire changé: {}'.format(chemin))
     
    ##############################################################################
    def fichier_change(chemin):
        print('Fichier changé: {}'.format(chemin))
     
    ##############################################################################
    app = QtCore.QCoreApplication(sys.argv)
     
    # lance l'outil de surveillance
    fswatcher = QtCore.QFileSystemWatcher()
     
    # ajoute les répertoires et les fichiers à surveiller
    chemins = [
        r'E:\Temp\Toto',
        r'E:\Temp\Toto\titi.txt'
        ]
    fswatcher.addPaths(chemins)
     
    # crée les liens entre signaux et méthodes
    fswatcher.directoryChanged.connect(repertoire_change)
    fswatcher.fileChanged.connect(fichier_change)
     
    sys.exit(app.exec_())
    Cet exemple n'a même pas besoin de graphique, mais on pourrait l'intégrer dans un IHM complet. Il signale avec des print les modifications. On pourrait, bien sûr en profiter pour scanner le répertoire afin de connaître dans le détail le contenu de ces modifications (Quel fichier a été ajouté, modifié ou supprimé, etc...).
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  12. #92
    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
    Beaucoup d'idées intéressantes !

    Je suis parti sur la récupération du nom de l'élève d'abord et le renommage automatique pour justement limiter les manipulations et éviter par exemple d'oublier de renommer les fichiers du dernier élève de la classe avant de passer à la suivante.
    Vous n'imaginez pas le chahut qui peut régner lors d'une séance en école, entre les élèves qui s'impatientent, l'enseignant qui les rappelle à l'ordre, vous au milieu qui essayez d'obtenir une belle expression de l'élève que vous photographiez...
    Pas le temps de se dire "merde ! Ai-je cliqué sur le bouton ???!!!" Au moins le changement d'élève est un évènement sur : faut bien appeler le suivant Après le bazar doit se débrouiller tout seul... Ceci dit en l'état ça peut poser des problèmes lorsqu'on change de sélection alors que les fichiers ne sont pas finis de renommer... Peu de chances que ça arrive en live, faut quand même le temps de regarder les photos et de voir si on a une image correcte, mais sait-on jamais...

    Par contre un problème plus gênant se pose : mon logiciel photo perd aussitôt la trace des fichiers et ne peut plus m'afficher qu'une miniature de mauvaise qualité, pas top pour le contrôle... Donc le renommage en bloc au changement d'élève reprend l'avantage !

    Sinon faire une copie des fichiers dans un autre répertoire avant de les renommer... Bonjour les volumes !

    Bref, je cogite, toutes suggestions sont les bienvenues !

  13. #93
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 630
    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 630
    Points : 30 860
    Points
    30 860
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    Sinon faire une copie des fichiers dans un autre répertoire avant de les renommer... Bonjour les volumes !
    Pas une recopie, un simple déplacement. Et au lieu de déplacer les photos, déplacer le dossier qui les contient et ça, quand cela se passe sur le même système disque (fs), c'est alors instantané. L'OS change juste le lien entre le parent et le dossier déplacé. Si par exemple le dossier se nomme "/home/machin/photo" (home -> machin -> photo) et qu'on le déplace dans "/home/machin/work/photo" alors l'OS supprime la liaison machin -> photo et crée une nouvelle liaison work -> photo et ça c'est immédiat (le dossier final "photo", lui, n'ayant pas réellement bougé).
    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]

  14. #94
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 235
    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 235
    Points : 36 684
    Points
    36 684
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    Par contre un problème plus gênant se pose : mon logiciel photo perd aussitôt la trace des fichiers et ne peut plus m'afficher qu'une miniature de mauvaise qualité, pas top pour le contrôle... Donc le renommage en bloc au changement d'élève reprend l'avantage !
    Vous devriez pouvoir visualiser les photos sur l'ordinateur.

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

  15. #95
    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, finalement j'ai décidé de renommer les fichiers seulement sur des évènements IHM. Voilà donc mon code pour ce faire, l'idée étant de renommer quand on change d'élève dans la liste ou quand on quitte pour traiter les dernières photos prises...
    Et il faudrait aussi que je le fasse lors de la sélection d'un autre fichier
    Bon, question : si je définis ma "procédure" de renommage sans paramètre, lors de l'appel ça me fait cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Users\richa\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
        return self.func(*args)
    TypeError: selection_eleve() takes 0 positional arguments but 1 was given
    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Users\richa\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
        return self.func(*args)
    TypeError: selection_eleve() takes 0 positional arguments but 1 was given
    J'ai solutionné ça en ajoutant un paramètre "bidon", mais bon ça me semble pas top... Car j'ai pas compris le truc vu que normalement on utilise ça semble-t-il pour une méthode et non une fonction !
    Je vais encore passer pour un sagoin trop pressé qui veut pas apprendre à afficher des "hello world" mais si dans votre grande indulgence vous pouviez m'expliquer... Merci !!!
    J'ai bien lu le tuto sur les appels de fonctions (enfin là, procédure) de développez.com, mais ça ne parle de rien de particulier, genre : tu mets pas de paramètre, tu fais un appel où tu veux et ça marche... Qu'ai-je loupé ?

    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
     
    # 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="."
    EleveCourant=""
    before=[""]
    after=[""]
    IndiceEleveCourant=0
    toto=""
     
    # Fonctions
    def ouvrir_fichier():
        global EleveCourant, IndiceEleveCourant, before, RepertoireASurv
        FichierExcel = askopenfilename(title="Choisir une liste d'élèves",filetypes=[('Excel files','.xlsx'),('all files','.*')])
        if FichierExcel:
            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
            liste.selection_set(0)
            EleveCourant = liste.get(ACTIVE).replace(" ","_")
            IndiceEleveCourant = liste.curselection()
        RepertoireASurv = askdirectory(title="Choisir le répertoire de prise de vue")
        if RepertoireASurv:
            LabelRepertoire['text']=RepertoireASurv
            before = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
     
    def selection_eleve(self):
        global EleveCourant, after, before, RepertoireASurv, IndiceEleveCourant
        print("Traitement eleve")
        # Renommer les fichiers de l'élève précédent
        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:
            for fichier in added:
                NouveauFichier = EleveCourant + "_" + fichier[-8:]
                renommerOK=False
                while not renommerOK:
                    try :
                        os.rename(RepertoireASurv+'/'+fichier,RepertoireASurv+'/'+NouveauFichier)
                        renommerOK=True
                    except IOError :
                        #fichier occupé
                        renommerOK=False
            liste.itemconfigure(IndiceEleveCourant,background="#5afb55")
     
        before = [f for f in listdir(RepertoireASurv) if isfile(join(RepertoireASurv, f))]
        # Nouvel élève sélectionné    
        IndiceEleveCourant = liste.curselection()
        liste.activate(IndiceEleveCourant)
        EleveCourant = liste.get(ACTIVE).replace(" ","_")
     
    def quitter():
        selection_eleve(toto)
        Photoscol.destroy()
     
    # Initialisations
     
    # Widgets et code
     
    Photoscol = Tk()
    Photoscol.title('Photoscol')
    Photoscol.geometry('565x800')
     
    #Bouton choix fichier élèves
    BoutonFichier = Button(Photoscol, text="Fichier élèves", command=ouvrir_fichier, width=20)
    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=52, anchor="w")
    LabelNomFichier.grid(row=0, column=1, sticky=NW, padx=10, pady=10)
     
    #Répertoire à surveiller
    LabelRepertoireASurveiller = Label(Photoscol, text="Répertoire de prise de vue", bg='#f0f0f0', width=20, anchor="w")
    LabelRepertoireASurveiller.grid(row=1, column=0, sticky=NW, padx=10, pady=10)
     
    #Chemin Répertoire à surveiller
    LabelRepertoire = Label(Photoscol, text="Répertoire de prise de vue", bg='#ffffff', width=52, anchor="w")
    LabelRepertoire.grid(row=1, column=1, sticky=NW, padx=10, pady=10)
     
    #Affichage liste élèves
    liste = Listbox(Photoscol, width=90, bg="Ivory", height=40)
    liste.grid(row=3, columnspan=2, sticky=NW, padx=10)
     
    #Sortir de l'appli
    BoutonQuitter = Button(Photoscol, text='Quitter', width=70, command=quitter)
    BoutonQuitter.grid(row=4, columnspan=2, padx=10, pady=20)
     
    liste.bind('<<ListboxSelect>>',selection_eleve)
     
    Photoscol.mainloop()
     
    # Fin widget et code

  16. #96
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2003
    Messages : 1 563
    Points : 2 003
    Points
    2 003
    Par défaut
    Bonjour,

    ligne 44 de votre code, fonction selection_eleve(), enlevez le self.

    Ici, c'est une fonction, pas une méthode de classe

    Et du coup, enlevez le toto ligne 70.

  17. #97
    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
    Si je fais ça, j'ai l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Exception in Tkinter callback
    Traceback (most recent call last):
    File "C:\Users\richa\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
    TypeError: selection_eleve() takes 0 positional arguments but 1 was given
    Exception in Tkinter callback
    Traceback (most recent call last):
    File "C:\Users\richa\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
    TypeError: selection_eleve() takes 0 positional arguments but 1 was given

  18. #98
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2003
    Messages : 1 563
    Points : 2 003
    Points
    2 003
    Par défaut
    Même en enlevant le toto dans l'appel à la fonction ligne 70 ?

  19. #99
    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
    Oui, lorsque je sélectionne un autre élève dans la liste voilà ce que ça renvoie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Users\richa\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
        return self.func(*args)
    TypeError: selection_eleve() takes 0 positional arguments but 1 was given

  20. #100
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 235
    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 235
    Points : 36 684
    Points
    36 684
    Par défaut
    Salut,

    Citation Envoyé par Vincent-vr Voir le message
    J'ai bien lu le tuto sur les appels de fonctions (enfin là, procédure) de développez.com, mais ça ne parle de rien de particulier, genre : tu mets pas de paramètre, tu fais un appel où tu veux et ça marche... Qu'ai-je loupé ?
    ligne 105, selection_eleve est déclaré callback pour l'évènement <<ListboxSelect>> via .bind. "callback" parce qu'appelé par tkinter lorsque l'évènement se produit... et avec, en paramètre, un objet de type Event.

    Citation Envoyé par Vincent-vr Voir le message
    Je vais encore passer pour un sagoin trop pressé qui veut pas apprendre à afficher des "hello world" mais si dans votre grande indulgence vous pouviez m'expliquer...
    Ben oui, c'est la dette technique... qui frappe.

    Code trop long, mal structuré, pas beaucoup de monde ira le lire et comprendre... et ça se focalise sur des détails qui n'ont rien à voir avec le problème de base.
    C'est comme écrire des choses importantes en français. S'il y a plein de fautes d'orthographe et de constructions grammaticales inventées: beaucoup bloqueront sur la forme... pas facile de transmettre le "fond".

    - 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, 12h16
  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, 19h04
  3. Réponses: 2
    Dernier message: 31/12/2008, 13h16
  4. Réponses: 7
    Dernier message: 21/10/2004, 10h13
  5. [PowerAMC] Comment s'en servir pour creer une base?
    Par Elmilouse dans le forum Access
    Réponses: 2
    Dernier message: 27/07/2004, 10h53

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