0
votes

Écrivez à logfile si les règles ne sont pas remplies

J'écris actuellement un code pour rechercher les fichiers dans le dossier d'entrée et copier les images, qui remplissent les conditions requises (liste 'règles') dans un autre répertoire. Si le fichier ne remplit aucune exigence donnée, cela doit être signalé à logfile.txt en indiquant quelque chose comme:

import os
from glob import glob
from PIL import Image
import shutil
from tqdm import tqdm

input_dir = 'data'
output_dir = 'out'

try:
    if os._exists(output_dir) == False:
        os.mkdir(output_dir)
except FileExistsError:
    print('Directory "out" already exists! Proceeding with script')

logfile = open('logfile.txt','w+')

ext = ('jpg', 'jpeg', 'JPG', '.PEG')

dirs = sorted(glob(os.path.join(input_dir, '**/*.jpg'),
                               recursive=True))

def checker(input_dir, output_dir, logfile):
    for i, file in tqdm(enumerate(input_dir), desc='Processing copied files!',
                              total=len(input_dir)):
        rules = [file.endswith(ext),
                 os.path.getsize(file) >= 10000,
                 Image.open(file),

                     ]

        if all(rules):
            # shutil.copy(file, output_dir)
                new_filename = str(i).zfill(6) + '.jpg'
                shutil.copy(file, os.path.join(output_dir, new_filename))
        else:
            for i, rule in enumerate(rules):
                logfile.write(f'\nError number {i+1}, file -> {file}\n')

checker(dirs, output_dir, logfile)

mais avec mon code actuel, j'obtiens des sorties répétées dans le fichier journal, sans relation avec la règle selon laquelle n'est pas remplie. Donc, pour chaque fichier dans le fichier journal, j'ai:

Error number 1, file -> data\0055\0100.jpg
Error number 2, file -> data\0055\0100.jpg
Error number 3, file -> data\0055\0100.jpg

Alors, comment pourrais-je écrire chaque entrée dans le fichier journal avec un numéro de «règle» distinct sans répétition? Aussi, comment vérifier si le fichier copié dans output_dir existe déjà?

Il y a mon code actuel:

Error number 1, file -> data\0055\0100.jpg

Merci de bien vouloir votre attention si vous lisez ceci!


0 commentaires

3 Réponses :


0
votes

l'appel Image.open (fichier) dans votre code ne renvoie pas Vrai / Faux, il renvoie un objet fichier. En tant que tel, vous ne testerez pas (Vrai / Faux, Vrai / Faux, Vrai / Faux), donc le test all () renverra toujours un "échec".

Vous devez retravailler le dernier test dans vos règles, je pense.


4 commentaires

J'ai supprimé la dernière règle `` Image.open (fichier) '' mais j'ai toujours des entrées répétées dans le fichier journal, je pense que le problème réside dans la boucle `` for '', mais je ne trouve toujours pas d'alternative


En fait, j'ai trouvé le moyen de sortir: j'ai fait une autre liste avant d'écrire dans le fichier journal qui enregistre l'index de la règle non remplie à chaque fois, puis sort dans le fichier journal. Je vais vous demander de l'aide!


ne pensez pas que c'est un problème avec votre boucle, car vous êtes en fait en train de faire une boucle à travers les choses, donc la boucle est, à tout le moins, de fournir quelque chose sur quoi travailler. Un problème différent, cependant ... dans votre premier test de règles, vous testez "se termine par ()" ce qui signifie que votre fichier ne se terminera jamais avec ça. Je crois que endswith () n'acceptera qu'une chaîne, vous devez donc parcourir chaque membre des membres du tuple, ou faire un test composé comme (file.endswith (ext [0]) ou file.endswith (ext [ 1])...)


Merci d'avoir remarqué! J'ai aussi retravaillé la première règle! Mon code ressemble cependant à Frankenstein absolu: D



0
votes

J'ai trouvé la solution: j'ai fait une autre liste avant d'écrire dans le fichier journal qui enregistre l'index de la règle non remplie à chaque fois, puis sort dans le fichier journal. Cela ressemble à ceci:

        else:
            errors = [num for (num, state) in enumerate(rules) if not state]
            for num in errors:
                logfile.write(f'{file};{num+1}\n')  

Mais une question que je me pose encore est de savoir comment vérifier si l'extension PIL ouvre le fichier sans erreur?


0 commentaires

0
votes

vous étiez sur la bonne voie en ouvrant le fichier. Faites simplement le Image.open () avec "try: / catch:". À partir des pages du document PIL :

PIL.Image.open(fp, mode='r')
...
Raises: 
IOError – If the file cannot be found, or the image cannot be opened and identified.
...


2 commentaires

Mais pour que cela fonctionne, je devrais l'écrire en dehors de la liste des «règles», non? De plus, si je veux convertir chaque image à l'intérieur de la boucle en tableau numpy pour vérifier la dimensionnalité, quel est le moyen le plus efficace de le faire en termes de performances?


vous pourriez écrire une fonction pour faire une ouverture avec un try / catch et retourner true en cas de succès, false en cas d'échec ... la fonction n'aurait qu'à s'ouvrir, vérifier qu'elle s'est ouverte, puis fermer. De cette façon, vous pouvez utiliser la fonction (fichier) dans vos règles. Pour convertir l'image, vous devez la rouvrir à l'intérieur de la boucle et la traiter là-bas. Je ne suis pas sûr des performances, mais ouvrir / fermer ne prend pas trop de temps, même si je ne suis pas sûr que ce soit terriblement efficace.