Noob: Habe nen Bug uns finde den Fehler nicht :(

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
zapatas
User
Beiträge: 26
Registriert: Dienstag 1. Februar 2022, 19:25

Hallo, vielleicht kurz erstmal was das Programm macht: Es packt Bilder die im gleichen ordner wie das Programm sind in eine .docx und erstellt darauf basierend dann eine Neue docx unter Berücksichtigung der Nutzereingaben. Eigentlich funktioniert das bei den meisten Datensätzen auch ganz gut, aber manchmal bekomme ich die Fehlermeldung s.u. ; hier erstmal der Code. Bitte nicht steinigen; einige Dinge stehen da einfach weil ich eben noch ein Anfänger bin und auch nicht so oft zum programmieren komme. Manche Dinge sind eben Bestandteil, da sie Teil des Prozesses sind irgendwas hinzufummeln das dann läuft ^^. Vielleicht kann mir ja wer sagen was der Fehler ist, v.a. aber was ich schnell tun kann damit das weg geht ? Wie gesagt, eigentlich funktioniert das Programm, aber heute stellte ich mit erschrecken fest: eben nicht überall. Kann es sein das die Größe der Ausgangsbildr nicht passt ? Also z:B., kleiuner als 5 cm sind oder so ?

Code: Alles auswählen

from keyword import kwlist
import os,sys
from docxtpl import DocxTemplate, InlineImage
import docx
from docx.shared import Cm, Inches, Pt
from openpyxl.styles import Alignment
from docx import Document
#import math
from datetime import date
from PIL import Image
#import PIL
from docx.enum.table import WD_TABLE_ALIGNMENT
import os
import getpass
#import pandas as pd
from openpyxl import Workbook, load_workbook
from pathlib import Path
import subprocess

#from pyfiglet import figlet_format

def main():
    def clearConsole():
        command = 'clear'
        if os.name in ('nt', 'dos'):  # If Machine is running on Windows, use cls
            command = 'cls'
        os.system(command)
    user=(getpass.getuser())

    
    path=os.getcwd()
    path_doc=path+'\\main.docx'
    datum=date.today()
    
    datum_today=datum.strftime("%d.%m.%Y")
    year=datum_today[8:]
    month=datum_today[3:]
    month=month[:2]
    day=datum_today[:2]
    print("SampleLog 1.0")
    print("developed by X.XXXXXXX")
    print("Feature: Das Programm erleichtert die Erstellung des Materialprobenberzeichnisses.")
    print("_________")
    anleitung=input("Hallo "+str(user)+", möchtest Du dir erstmal die Anleitung anschauen ?\n\n[y] - Zeig her... \n\nHinweis: Beliebige andere Eingabe führt dich weiter...\n\nEingabe: ")
    if anleitung=='y':
        clearConsole()
        print("Anleitung")
        print("_________")
        print("<Schritt 1> Sicherstellen, dass sich ausschließlich horizontal orientierte Fotos im Programm-Ordner befinden, welche für das Materialprobenverzeichnis (MPV) verwendet werden sollen.\n\nSehr sehr (!) wichtiger Hinweis:\n\nSämtliche Bilder sollten gem. ihres Aufnahmezeitpunktes sortiert sein, wobei der Zeitstempel kongruent der Probennennung ist. Dies kann beispielsweise mit dem Programm PicMan realisiert werden. Die Bilddateien erhalten dann automatisch einen Zeitstempel, sodass Windows die Bilder in der notwendigen Reihenfolge zeitlich automatisch ordnet.\nSolltest du in der Probenahme von einer aufsteigenden Probenbenennung abgewichen sein, so musst du entweder aufwändig editieren, oder erstellst das MPV manuell.\nSolltest du das Programm in diesem ungünstigen Fall dennoch nutzen, wird die Zuordnung mit großer Wahrscheinlichkeit falsch sein !")
        print("\n<Schritt 2> Achte bitte derzeit noch darauf Eingaben sauber anzugeben. Leerzeichen können aktuell noch zum Absturz führen (z.B. (falsch) 'y ' an Stelle von (richtig) 'y') ;)...\n\nHinweis: Ich werde dem Programm generell noch einem Feinschliff verpassen, sodass falsche Übergaben, welche zu Abstürzen führen würden, vermieden werden.")
        weiter=input("\nBereit ? Dann weiter mit <enter>")
    clearConsole()
    
    
    test=0

    abfrage_arbeiter='-'
    firma=''
    titel=''
    image=''
    if test==0:

        doc=DocxTemplate(path_doc)
        print("Fragerunde")
        print("__________")
        projektnummer=str(input("\nProjektnummer: "))
        clearConsole()
        
        postal=str(input("Anschrift des Untersuchungsobjektes in der Form 'Straße Nummer, PLZ Ort': "))
        while len(postal)==0 or len(postal.lstrip().rstrip())==0:
            print("Die Angabe einer Anschrift ist obligatorisch. Alternativ kann als Platzhalter ein Buchstabe oder eine Zahl angegeben werden. Eine 'leere' Eingabe ist nicht zulässig.")
            postal=str(input("Anschrift des Untersuchungsobjektes in der Form 'Straße Nummer, PLZ Ort': "))
        if len(postal)>0:
            clearConsole()
            class_main=input("Handelt es sich um ein Materialprobenverzeichnis für einen orientierenden Schadstoffbericht ?\n\n[n] - Nein\n\nHinweis: Gibst du nichts oder etwas anderes als 'n' an, so ist es ein MPV für einen orientierenden Schadstoffbericht..\n\nEingabe: ")
            if class_main=='n':# or ' n' or 'n ':
                    class_main=input("\nWas soll an Stelle von 'Bericht orientierende Schadstoffuntersuchung' in der Kopfzeile auftauchen ?\n\nEingabe: ")
            else:
                class_main='Bericht orientierende Schadstoffuntersuchung'

                print("\n<Ausgewählt: MPV für orientierenden Schadstoffbericht>")
           
            #clearConsole()
            if len(class_main)>0:
                class_detail=input("\nDie Kurzbezeichnung für das Objekt (z.B. 'Amtsgericht Wesel') lautet ?\n\nHinweis: Diese Angabe taucht ebenfalls in der Kopfzeile auf\n\nEingabe: ")
            class_main=class_main.lstrip().rstrip()
            clearConsole()
            id=input("Das Verzeichnis beginnt bei Verdachtsbauteilnummer 1 ?\n\n[y] - Ja\n\nHinweis: Falls nicht, bei welcher Zahl ?\n\nEingabe: ")
            id=id.lstrip().rstrip()
            id_add=0
            if id=='y' or len(id)==0:
                id_add=-1
            else:
                id_add=int(id)-1
                #o=id
            id=id.lstrip().rstrip()
            clearConsole()
            anlage=input("\nDie Anlagennummer ist Dir bereits bekannt ?\n\n[n] - nicht bekannt (in dem Fall wird der Dateiname 'MPV' tragen)\n[y] - Ja\n\nEingabe: ")
            if anlage=='y' or 'y ' or ' y' or ' y ':
                anlage=input("\nWelche Anlage soll es sein (Zahl reicht als Nennung aus) ?\n\nEingabe: ")
                anlage=" Anlage "+anlage
                anlage=anlage.rstrip()
                #print(anlage)
            else:
                anlage=''
                print("<Anlagenzahl wird im Dateinamen nicht berücksichtigt>")
            clearConsole()
            insert_image_folder=input("\nNochmal: Bitte sicherstellen, dass sich Zeitstempel-sortierte Bilder im Hauptverzeichnis der Programm.exe befinden.\n\nAchtung:\nDies ist ein äußerst wichtiger Schritt, da sonst die Zuordnungen aller Wahrscheinlichkeit durcheinander kommen werden.\nBilder sollten im Gelände zeitlich auffolgend mich sukzessiv zunehmender Probenbezeichnung aufgenommen wurden sein (M1..M2...M3... etc.).\nBilder, welche im Materialprobenverzeichnis nichts zu suchen haben, also etwa Fernaufnahmen, sollten nicht im Ordner der Programm-.exe auftauchen.\nSollten diese Voraussetzungen nicht gegeben sein, rate ich von der Verwendung des Programmes dringend ab !\n\n<enter> - weiter ")
            n_pictures=0
            if insert_image_folder=='':
                
                PICTURES=[]
                ID=[]
                Area=[]
                Local=[]
                Substance=[]
                Pics=[]
                Color=[]
                Com=[]
                Method=[]
                Name=[]
                Result=[]
                Width_new=[]
                Height_new=[]
                Datasize=[]
                counter=0
                for file in os.listdir():
                    if file.endswith('.jpg') or file.endswith('JPG'):
                        n_pictures+=1
                        size=os.stat(file)
                        size=size.st_size
                        Datasize.append(size)
                print("Im Root-Ordner wurden "+str(n_pictures)+" .jpg-Bilder gefunden.\n")
                counter_i=0
                for file in os.listdir():
                    if file.endswith('.jpg') or file.endswith('JPG'):
                            #print(file)
                            PICTURES.append(file)
                            
                            
                            if n_pictures>0:
                                print("")
                                counter_i+=1
                                id="{{id_"+str(counter_i+id_add)+"}}"
                                area="{{area_"+str(counter_i+id_add)+"}}"
                                local="{{local_"+str(counter_i+id_add)+"}}"
                                substance="{{substance_"+str(counter_i+id_add)+"}}"
                                color="{{color_"+str(counter_i+id_add)+"}}"
                                com="{{com_"+str(counter_i+id_add)+"}}"
                                method="{{method_"+str(counter_i+id_add)+"}}"
                                name="{{name_"+str(counter_i+id_add)+"}}"
                                result="{{result_"+str(counter_i+id_add)+"}}"
                                pics="{{image_"+str(counter_i+id_add)+"}}"
                                ID.append(id)
                                Area.append(area)
                                Local.append(local)
                                Substance.append(substance)
                                Color.append(color)
                                Com.append(com)
                                Method.append(method)
                                Name.append(name)
                                Result.append(result)
                                Pics.append(pics)
                                img=Image.open(file)
                                width=img.width                                
                                Width_new.append(width)
                                height=img.height
                                Height_new.append(height)
                                resize_factor=float(width/168)
                                height_new=int(height/resize_factor)
                                
                                
                                print("file detected: "+str(file)+" width: "+str(width)+"px , height: "+str(height)+" px")

                                
            print("______________________________")
            size_bytes=sum(Datasize)
            size_mb=size_bytes/(1024*1024)
            clearConsole()
            print("Die kumulative Datengröße der Bilddateien (.jpg) im Ordner beträgt ca. "+str(round(size_mb,2))+" Mb ("+str(size_bytes)+" Bytes).\nDie Daten werden nun auf das Dokument eingepasst. Das kann je nach Umfang und Dimension der Daten einen Moment dauern; je größer die Bilddateien, je länger dauert das jetzt....")
            print("\n")
        
        
        docname="["+str(year)+str(month)+str(day)+"] "+str(projektnummer)+str(anlage)+" MPV.docx"
        context={
            'pnx': docname,
            'class_main': class_main,
            'class_detail': class_detail,
            'id': "{{id}}",
            'area': "{{area}}",
            'image': "{{image}}",
            'postal': postal,
            'local':"{{local}}",
            'color':"{{color}}",
            'method':"{{method}}",
            'name':"{{name}}",
            'result':"{{result}}",
            'com':"{{com}}",
            'substance':"{{substance}}"
                    }

        


        doc.render(context)
        doc.save('render_one.docx')
        k=1
        if k==1:
            doc = docx.Document('render_one.docx')
            Table=doc.tables[0]
            for row in Table.rows:
                for cell in row.cells:
                    paragraphs = cell.paragraphs
                    for paragraph in paragraphs:
                        for run in paragraph.runs:
                            font = run.font
                            font.size= Pt(10)
                            font.name="Arial"

        for i in range(((len(PICTURES)-1))):
            #print(i)
            Table.add_row().cells


        #id=int(id)-1
        [i+id for i in ID]
        for i in range(len(PICTURES)):

            if int(i)==0:
                print("...*holt Klebestift und Schere, damit man die Bilder richtig einpassen kann...*")
                print("Kaffeezeit ? Sollten es größere und v.a. viele Bilder sein, könnte das etwas dauern...")
                print("...*schnip, schnap..*")
            
            #ID
            Table.cell(i+1,0).text=ID[i]       
            Table.cell(i+1,0).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,0).paragraphs[0].runs[0].font.bold = True

            #Area
            Table.cell(i+1,1).text=Area[i]       
            Table.cell(i+1,1).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,1).paragraphs[0].runs[0].font.bold = True
            #Local
            Table.cell(i+1,2).text=Local[i]       
            Table.cell(i+1,2).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,2).paragraphs[0].runs[0].font.bold = True
            #substance
            Table.cell(i+1,3).text=Substance[i]       
            Table.cell(i+1,3).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,3).paragraphs[0].runs[0].font.bold = True
            #image
            Table.cell(i+1,4).text=Pics[i]       
            Table.cell(i+1,4).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,4).paragraphs[0].runs[0].font.bold = True
            #color
            Table.cell(i+1,5).text=Color[i]       
            Table.cell(i+1,5).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,5).paragraphs[0].runs[0].font.bold = True
            #com
            Table.cell(i+1,6).text=Com[i]       
            Table.cell(i+1,6).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,6).paragraphs[0].runs[0].font.bold = True
            #method
            Table.cell(i+1,7).text=Method[i]       
            Table.cell(i+1,7).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,7).paragraphs[0].runs[0].font.bold = True
            #name
            Table.cell(i+1,8).text=Name[i]       
            Table.cell(i+1,8).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            Table.cell(i+1,8).paragraphs[0].runs[0].font.bold = True
            
            #result
            Table.cell(i+1,9).text=Result[i]       
            Table.cell(i+1,9).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
            
            Table.cell(i+1,9).paragraphs[0].runs[0].font.bold = True
            percentage=round((i/len(PICTURES)*100),1)
        
            
            print("...schneidet das Bildchen "+str(i)+" von "+str(len(PICTURES))+" passend aus und klebt es an die richtige Stelle... ["+str(percentage)+"/100 %]",end='\r')
            if int(len(PICTURES))-int(i)==1:
                print("...So !.. nun aber das letzte Klebchen.... :-) !                                            [100/100 %]")
            
                       
        
        for i in range(len(PICTURES)):
            Table.cell(i+1, 4).text = ''  
            Table.cell(i+1, 4).paragraphs[0].runs[0].add_picture(PICTURES[i],width=Cm(5))
       
        
              
        doc.save(docname)

        path = Path(
                    "O:/zielordner/Users/XXXXXXX/IT/templates/stat_mpvz.xlsx")
        WorkBook = load_workbook(path, read_only=False)
        WorkSheet = WorkBook['Tabelle1']
        check=WorkSheet.cell(row=2, column=2).value
        counter=0
        for i in range(2,19000,1):
            if WorkSheet.cell(row=i, column=2).value==None:
                WorkSheet.cell(row=i, column=2).value=1
                WorkSheet.cell(row=i, column=1).value=projektnummer
                break
            else:
                continue
        WorkBook.save(path)

        finish=input("\nDas sollte geklappt haben. Du solltest nun eine Datei namens \n\n----->   "+str(docname)+"   <-----\n\n..........im Programmordner finden............\n\n<o>              - Datei direkt öffnen\n\n<andere Eingabe> - beendet das Programm\n\nEingabe: ")
        finish=finish.lstrip().rstrip()
        subprocess.Popen('explorer "C:\"')
        if finish=='o':
            os.popen(docname)
        else:
            quit()
if __name__ == "__main__":
    main()                    

        

Fehlermeldung:

Code: Alles auswählen

Die kumulative Datengröße der Bilddateien (.jpg) im Ordner beträgt ca. 11.86 Mb (12439473 Bytes).
Die Daten werden nun auf das Dokument eingepassXXXXXXX Das kann je nach Umfang und Dimension der Daten einen Moment dauern; je größer die Bilddateien, je länger dauert das jetzXXXXXXX...


...*holt Klebestift und Schere, damit man die Bilder richtig einpassen kann...*
Kaffeezeit ? Sollten es größere und v.a. viele Bilder sein, könnte das etwas dauern...
...*schnip, schnap..*
...So !.. nun aber das letzte Klebchen.... :-) !                                            [100/100 %]
Traceback (most recent call last):
  File "C:\Coding\Programmierung\Materialprobenverzeichnis\mpzpy.py", line 318, in <module>
    main()
  File "C:\Coding\Programmierung\Materialprobenverzeichnis\mpzpy.py", line 289, in main
    Table.cell(i+1, 4).paragraphs[0].runs[0].add_picture(PICTURES[i],width=Cm(5))
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\text\run.py", line 62, in add_picture
    inline = self.parXXXXXXXnew_pic_inline(image_path_or_stream, width, height)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\parts\story.py", line 56, in new_pic_inline
    rId, image = self.get_or_add_image(image_descriptor)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\parts\story.py", line 29, in get_or_add_image
    image_part = self._package.get_or_add_image_part(image_descriptor)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\package.py", line 31, in get_or_add_image_part
    return self.image_parts.get_or_add_image_part(image_descriptor)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\package.py", line 74, in get_or_add_image_part
    image = Image.from_file(image_descriptor)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\image.py", line 55, in from_file
    return cls._from_stream(stream, blob, filename)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\image.py", line 176, in _from_stream
    image_header = _ImageHeaderFactory(stream)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\image.py", line 198, in _ImageHeaderFactory
    return cls.from_stream(stream)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\jpeg.py", line 47, in from_stream
    markers = _JfifMarkers.from_stream(stream)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\jpeg.py", line 111, in from_stream
    for marker in marker_parser.iter_markers():
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\jpeg.py", line 176, in iter_markers
    marker = _MarkerFactory(
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\jpeg.py", line 271, in _MarkerFactory
    return marker_cls.from_stream(stream, marker_code, offset)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\jpeg.py", line 413, in from_stream
    tiff = cls._tiff_from_exif_segment(stream, offset, segment_length)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\jpeg.py", line 455, in _tiff_from_exif_segment
    return Tiff.from_stream(substream)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\tiff.py", line 36, in from_stream
    parser = _TiffParser.parse(stream)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\tiff.py", line 63, in parse
    ifd_entries = _IfdEntries.from_stream(stream_rdr, ifd0_offset)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\tiff.py", line 176, in from_stream
    entries = dict((e.tag, e.value) for e in ifd_parser.iter_entries())
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\tiff.py", line 176, in <genexpr>
    entries = dict((e.tag, e.value) for e in ifd_parser.iter_entries())
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\tiff.py", line 204, in iter_entries
    ifd_entry = _IfdEntryFactory(self._stream_rdr, dir_entry_offset)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\tiff.py", line 231, in _IfdEntryFactory
    return entry_cls.from_stream(stream_rdr, offset)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\tiff.py", line 255, in from_stream
    value = cls._parse_value(
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\tiff.py", line 294, in _parse_value
    return stream_rdr.read_str(value_count-1, value_offset)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\helpers.py", line 70, in read_str
    chars = self._unpack_item(struct, base, offset)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\helpers.py", line 96, in _unpack_item
    bytes_ = self._read_bytes(strucXXXXXXXsize, base, offset)
  File "C:\Users\XXXXXXXXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\docx\image\helpers.py", line 88, in _read_bytes
    raise UnexpectedEndOfFileError
docx.image.exceptions.UnexpectedEndOfFileError
PS C:\Coding\Programmierung\Materialprobenverzeichnis> ^N





__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Also du musst dringend mal was ueber f-Strings und String-Formatting im allgemeinen lernen - dieses String-Gestueckel ist wirklich viel zu roedelig. Mit deinem Problem hat das aber nix zu tun. Wenn ich das richtig interpretiere, ist das ein Daten-Problem. Die Datei scheint kaputt. Lass dir ausgeben, welche das ist (zB durch abfangen der Fehlermeldung an der entsprechenden Stelle), und schau sie mit einem Bildbetrachter an, ob die ok ist.
zapatas
User
Beiträge: 26
Registriert: Dienstag 1. Februar 2022, 19:25

Hey danke dir erstmal. Du hast absolut Recht ich muss mir Mal einige Grundlagen anschauen. Ich hab tatsächlich eher durch seek und umsetzen programmiert und bin mittlerweile an einem Punkt wo ich meinen Stil auch als ungeeignet empfinde. Aber wie du schon sagst ist das nicht das Problem, denn bei anderen Bildern klappt es ohne Probleme. Aber alle jpg sind funktionsfähig, d.h. sie lassen sich zumindest problemlos öffnen. Daher dachte ich das da etwas kaputt gegangen ist. Einige Bilder wurden aber durch einen Kollegen editiert, d.h. es wurde ein Text an einigen Stellen, vermutlich mit Paint oder so, drüber gelegt. Könnte es a das sein ? Ich steh vollkommen auf dem Schlauch leider :(
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

@Zapatas: Aber __deets__ hat doch schon gesagt, was du machen musst. Lass dir ausgeben, bei welchem Bild der Fehler auftritt.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

`os` wird zweimal importiert. Man definiert im Normalfall keine Funktionen innerhalb anderer Funktionen. `os.system` benutzt man nicht, Du importierst doch schon subprocess.
Mich persönlich würde es ja stören, wenn ein Programm meinen Konsoleninhalt löscht.
Bei getpass.getuser ist ein Klammernpaar zu viel.
Pfade setzt man nicht mit + zusammen; du importierst schon pathlib.Path. Den Pfad um das aktuelle Arbeitsverzeichnis zu erweitern ist üblicherweise aber nicht nötig.
Es ist ziemlich umständlich, erst ein Datum in einen String zu formatieren um dann den String via Index wieder zu zerteilen.
Die Strings sind viel zu lange, vor allem weil Du Neue-Zeile-Zeichen innerhalb der Zeichenketten hast.
Man definiert keine Variablen auf Vorrat. `abfrage_arbeiter` wird gar nicht benutzt.
`input` liefert bereits Strings, diese per str nochmal in einen String umzuwandeln, ist unnötig.
Wenn man lstrip und rstrip aufruft, kann man gleich strip benutzten.
Durch die while-Schleife ist schon sichergestellt, dass len(postal)>0 gilt, das if ist unnötig.
Der Code garantiert dass len(class_main)>0 gilt, ansonsten wäre class_detail auch gar nicht definiert und es würde später zu einem Fehler führen.
Das `or´ in Deinen if-Abfragen tut nicht das, was Du denkst, Der Ausdruck `irgendwas or "y"` ist immer wahr.
Man speichert keine Informationen in 14 einzelnen Listen, sondern in einer Liste, wo zusammengehörende Daten auch zusammen stehen.
`with` und `height` werden gar nicht wirklich, das laden der Datei kann man sich also sparen.
os.listdir benutzt man nicht mehr, Du importierst doch schon pathlib.Path, warum nutzt Du es nicht?
Verzeichnisse werden in einer beliebigen Reihenfolge aufgelistet. Dein Langer Text, der irgendwas von einer Reihenfolge faselt ist daher falsch. Du mußt also Deine Dateinamen in irgendeiner Form sortieren.
Strings stückelt man nicht mit + zusammen, sondern nutzt Formatstrings.
Man iteriert nicht über einen Index, wenn man auch über die Elemente einer Liste iterieren kann.
Du erzeugst eine Liste per List-Comprehension, die Du gleich wieder wegwirfst? Warum?
Etwas, das nur beim ersten mal in einer Schleife ausgeführt wird, kann man auch einfach vor die Schleife schreiben.

Ich habe noch nicht alles verstanden, aber das Programm könnte ungefähr so aussehen:

Code: Alles auswählen

from datetime import date
from pathlib import Path
import subprocess
from docxtpl import DocxTemplate
import docx
from docx.shared import Cm, Inches, Pt
from docx.enum.table import WD_TABLE_ALIGNMENT
from openpyxl import load_workbook

def main():
    today = date.today()

    print("SampleLog 1.0")
    print("developed by X.XXXXXXX")
    print("Feature: Das Programm erleichtert die Erstellung des Materialprobenberzeichnisses.")
    print("_________")
    print()
    print("Anleitung")
    print("_________")
    print("<Schritt 1> Sicherstellen, dass sich ausschließlich horizontal orientierte Fotos im Programm-Ordner befinden, welche für das Materialprobenverzeichnis (MPV) verwendet werden sollen."
    print()
    print("Sehr sehr (!) wichtiger Hinweis:")
    print("Sämtliche Bilder sollten gem. ihres Aufnahmezeitpunktes sortiert sein, wobei der Zeitstempel kongruent der Probennennung ist. Dies kann beispielsweise mit dem Programm PicMan realisiert werden. Die Bilddateien erhalten dann automatisch einen Zeitstempel, sodass Windows die Bilder in der notwendigen Reihenfolge zeitlich automatisch ordnet.")
    print("Solltest du in der Probenahme von einer aufsteigenden Probenbenennung abgewichen sein, so musst du entweder aufwändig editieren, oder erstellst das MPV manuell.")
    print("Solltest du das Programm in diesem ungünstigen Fall dennoch nutzen, wird die Zuordnung mit großer Wahrscheinlichkeit falsch sein !")
    print("<Schritt 2> Achte bitte derzeit noch darauf Eingaben sauber anzugeben. Leerzeichen können aktuell noch zum Absturz führen (z.B. (falsch) 'y ' an Stelle von (richtig) 'y') ;)...")
    print()
    print("Hinweis: Ich werde dem Programm generell noch einem Feinschliff verpassen, sodass falsche Übergaben, welche zu Abstürzen führen würden, vermieden werden.")
    
    
    print()
    print("Fragerunde")
    print("__________")
    print()
    projektnummer = input("Projektnummer: ")
    while True:
        postal =input("Anschrift des Untersuchungsobjektes in der Form 'Straße Nummer, PLZ Ort': "))
        if postel.strip():
            break
        print("Die Angabe einer Anschrift ist obligatorisch. Alternativ kann als Platzhalter ein Buchstabe oder eine Zahl angegeben werden. Eine 'leere' Eingabe ist nicht zulässig.")
    print()
    print("Handelt es sich um ein Materialprobenverzeichnis für einen orientierenden Schadstoffbericht ?")
    print("[n] - Nein")
    print()
    print("Hinweis: Gibst du nichts oder etwas anderes als 'n' an, so ist es ein MPV für einen orientierenden Schadstoffbericht..")
    class_main = input("Eingabe: ")
    if class_main == 'n'
        print("Was soll an Stelle von 'Bericht orientierende Schadstoffuntersuchung' in der Kopfzeile auftauchen ?")
        class_main = input("Eingabe: ")
    else:
        class_main = 'Bericht orientierende Schadstoffuntersuchung'

    print("\n<Ausgewählt: MPV für orientierenden Schadstoffbericht>")
    print()
    print("Die Kurzbezeichnung für das Objekt (z.B. 'Amtsgericht Wesel') lautet ?")
    print("Hinweis: Diese Angabe taucht ebenfalls in der Kopfzeile auf")
    class_detail = input("Eingabe: ")
    class_main = class_main.strip()

    print("Das Verzeichnis beginnt bei Verdachtsbauteilnummer 1 ?")
    print("[y] - Ja")
    print("Hinweis: Falls nicht, bei welcher Zahl ?")
    id = input("Eingabe: ").strip()
    id_add = 0
    if id == 'y' or not id:
        id_add = -1
    else:
        id_add = int(id)-1

    print("Die Anlagennummer ist Dir bereits bekannt ?")
    print("[n] - nicht bekannt (in dem Fall wird der Dateiname 'MPV' tragen)")
    print("[y] - Ja")
    anlage = input("Eingabe: ").strip()
    if anlage=='y':
        print("Welche Anlage soll es sein (Zahl reicht als Nennung aus) ?")
        anlage = input("Eingabe: ")
        anlage = " Anlage " + anlage.strip()
    else:
        anlage = ''
        print("<Anlagenzahl wird im Dateinamen nicht berücksichtigt>")

    print("Nochmal: Bitte sicherstellen, dass sich Zeitstempel-sortierte Bilder im Hauptverzeichnis der Programm.exe befinden.")
    print("Achtung:")
    print("Dies ist ein äußerst wichtiger Schritt, da sonst die Zuordnungen aller Wahrscheinlichkeit durcheinander kommen werden.")
    print("Bilder sollten im Gelände zeitlich auffolgend mich sukzessiv zunehmender Probenbezeichnung aufgenommen wurden sein (M1..M2...M3... etc.).")
    print("Bilder, welche im Materialprobenverzeichnis nichts zu suchen haben, also etwa Fernaufnahmen, sollten nicht im Ordner der Programm-.exe auftauchen.")
    print("Sollten diese Voraussetzungen nicht gegeben sein, rate ich von der Verwendung des Programmes dringend ab !")
    insert_image_folder = input("<enter> - weiter ")
    pictures = []
    total_size = 0
    for index, imagepath in enumerate(Path('.').glob('*.jpg'), id_add):
        pictures.append((
            "{{id_%d}}" % index,
            "{{area_%d}}" % index,
            "{{local_%d}}" % index,
            "{{substance_%d}}" % index,
            str(imagepath),
            "{{color_%d}}" % index,
            "{{com_%d}}" % index,
            "{{method_%d}}" % index,
            "{{name_%d}}" % index,
            "{{result_%d}}" % index,
        ))
        total_size += imagepath.stat().st_size
        print(f"file detected: {imagepath}")

    print("______________________________")
    print(f"Im Root-Ordner wurden {len(pictures)} .jpg-Bilder gefunden.\n")
    size_mb = total_size / (1024*1024)
    print(f"Die kumulative Datengröße der Bilddateien (.jpg) im Ordner beträgt ca. {size_mb:.2f} Mb.")
    print("Die Daten werden nun auf das Dokument eingepasst. Das kann je nach Umfang und Dimension der Daten einen Moment dauern; je größer die Bilddateien, je länger dauert das jetzt....")
    print("\n")

    image=''
    docname = f"[{today:%Y%m%d}] {projektnummer}{anlage} MPV.docx"
    context = {
        'pnx': docname,
        'class_main': class_main,
        'class_detail': class_detail,
        'id': "{{id}}",
        'area': "{{area}}",
        'image': "{{image}}",
        'postal': postal,
        'local':"{{local}}",
        'color':"{{color}}",
        'method':"{{method}}",
        'name':"{{name}}",
        'result':"{{result}}",
        'com':"{{com}}",
        'substance':"{{substance}}"
    }

    doc = DocxTemplate("main.docx")
    doc.render(context)
    doc.save('render_one.docx')

    doc = docx.Document('render_one.docx')
    table = doc.tables[0]
    for row in table.rows:
        for cell in row.cells:
            paragraphs = cell.paragraphs
            for paragraph in paragraphs:
                for run in paragraph.runs:
                    font = run.font
                    font.size = Pt(10)
                    font.name ="Arial"

    print("...*holt Klebestift und Schere, damit man die Bilder richtig einpassen kann...*")
    print("Kaffeezeit ? Sollten es größere und v.a. viele Bilder sein, könnte das etwas dauern...")
    print("...*schnip, schnap..*")
    for row, picture in enumerate(pictures, 1):
        table.add_row().cells
        for column, entry in enumerate(picture):
            cell = table.cell(row, column)
            if column == 4:
                cell.text = ''  
                cell.paragraphs[0].runs[0].add_picture(entry, width=Cm(5))            
            else:
                cell.text = entry
                cell.paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
                cell.paragraphs[0].runs[0].font.bold = True
        print(f"...schneidet das Bildchen {row} von {len(pictures)} passend aus und klebt es an die richtige Stelle...",end='\r')
    print("...So !.. nun aber das letzte Klebchen.... :-) !                                            [100/100 %]")
    doc.save(docname)

    path = Path("O:/zielordner/Users/XXXXXXX/IT/templates/stat_mpvz.xlsx")
    workbook = load_workbook(path, read_only=False)
    worksheet = workbook['Tabelle1']
    for i in range(2,19000,1):
        if worksheet.cell(row=i, column=2).value is None:
            worksheet.cell(row=i, column=2).value = 1
            worksheet.cell(row=i, column=1).value = projektnummer
            break
    workbook.save(path)

    print("Das sollte geklappt haben. Du solltest nun eine Datei namens")
    print(f"----->   {docname}   <-----")
    print("..........im Programmordner finden............")
    print("<o>              - Datei direkt öffnen")
    print("<andere Eingabe> - beendet das Programm")
    finish = input("\nEingabe: ").strip()
    if finish == 'o':
        subprocess.call("startfile", docname)

if __name__ == "__main__":
    main()
zapatas
User
Beiträge: 26
Registriert: Dienstag 1. Februar 2022, 19:25

Hallo ihr und erstmal danke für die Antworten. Ja ich weiß mein Code ist grottig. Ich habs einfach nie richtig gelernt. Gibt es denn gute Lehrvideos die man sich hierzu reinziehen kann wo man, wenn man damit durch ist, sich zumindest in die richtige Richtung bewegt ? Also weniger aber diese - zumindest für mich- 'harter Tobak' Programmierwikis in englisch. Englisch naja okay, aber für mich ist vieles eher böhmisches Dorf, auch weil ich sehr spät damit angefangen hatte.

Einige Variablen die nie abgefragt werden stehen da eigentlich nur, weil ich da mal mit irgendwas machen wollte. Irgendwie musst es schnell gehen und naja, bei sonem Anfänger kommt dann leicht sowas bei rum :P Das Zerstückeln des Datums habe ich so gemacht gehabt weil ich das mal für eine spätere Dateibenennung brauche (oder auch nicht, da war ich mir in dem Moment net so sicher); ich hab den Code einfach aus nem anderen kleinen Skript was ich mal gemacht hatte rauskopiert.

Ich bin gerade etwas kurz angebunden und schau mir das Problem aber mal bei Gelegenheit an :) Das meiste deiner Lösung verstehe ich jedenfalls noch nicht, aber du hast das bestimmt richtig gemacht :) Danke jedenfalls soweit erstmal.
zapatas
User
Beiträge: 26
Registriert: Dienstag 1. Februar 2022, 19:25

Sirius3 hat geschrieben: Dienstag 14. März 2023, 21:57 dein Code etc.
Hi, also mal fern dem das ja einige Dinge im Code vielleicht so nicht i.O. , d.h. sauber ausgeführt wurden von mir, das Programm lief ja bisher. Dein Code jedenfalls führt leider zu dem exakt gleichen Fehler :( Danke dennoch
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Aber hast du dir denn inzwischen ausgeebebn lassen, bei welchem Bild der Fehler auftritt?
zapatas
User
Beiträge: 26
Registriert: Dienstag 1. Februar 2022, 19:25

Hey, ja auch das hatte ich mal versucht, aber da werde ich nicht schlau draus. Dimensionen sind die gleichen. Es handelt sich um eine .jpg und auch ist der Ursprung der gleiche, also alles Bilder die halt unterwegs aufgenommen wurden, kurz nach einander. Lassen sich alle öffnen etc.; bisher, auch wenn ich noob bin, konnte ich auch immer mit den Fehlermeldungen irgendwas anfangen, aber das ist mir zu hoch :(
geraldfo
User
Beiträge: 44
Registriert: Samstag 28. Januar 2023, 20:19
Wohnort: Nähe Wien

das ist mir zu hoch :(
Ich hab das jetzt nicht so genau verfolgt. Aber es geht wohl darum, ein Bild nach dem anderen einzulesen.
Klappt das Einlesen eines Bildes – Bild ok.
Scheitert das Einlesen eines Bildes, dann kann man annehmen, das diese jpg-File fehlerhaft ist.

LG Gerald
zapatas
User
Beiträge: 26
Registriert: Dienstag 1. Februar 2022, 19:25

Hm ja aber würden fehlerhafte jpeg nichtmal auf zu machen sein ? Manuell lassen sich die Bilder wo er abstürzt ja auch ohne Probleme anzeigen/einfügen. Kann es was mit dem Windowsupdate zu tun haben ? Seitdem haben generell viele die ich kenne Probleme die sie vorher nicht hatten.
zapatas
User
Beiträge: 26
Registriert: Dienstag 1. Februar 2022, 19:25

geraldfo hat geschrieben: Dienstag 21. März 2023, 10:41
das ist mir zu hoch :(
Ich hab das jetzt nicht so genau verfolgt. Aber es geht wohl darum, ein Bild nach dem anderen einzulesen.
Klappt das Einlesen eines Bildes – Bild ok.
Scheitert das Einlesen eines Bildes, dann kann man annehmen, das diese jpg-File fehlerhaft ist.

LG Gerald
Aber bisher war es sonst auch so das es eben geklappt hatte, hmm echt eigenartig :( Also die letzten 6 Monate nuze ich mein (mäß0iges )Skript dazu erfolgreich das umzusetzen was es soll, vielleicht war ich 6 Monate ein blindes Huhn, will ich nicht ausschließen.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

@geraldfo: Was __deets__ bereits in seiner ersten Antwort bemerkt hat, was aber ignoriert wurde.

@zapatas Wenn du dir sicher bist, welches Bild den Fehler auslöst (wie genau hast du das festgestellt, nicht dass du dir das vorherige Bild anschaust, das noch funktioniert hat), solltest du ein Mini-Programm schreiben, dass nichts weiter tut, als eben dieses eine Bild einzulesen und zu verarbeiten. Wenn das dann ebenfalls schief geht, weißt du, dass es am Bild liegt.
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wenn man sich anschaut welche Funktionen/Methoden da im Traceback sind, dann kann es sein, dass das JPG-Bild selbst nicht das Problem ist, sondern die EXIF-Metadaten kaputt sind. Also es kann gut sein, dass sich das betroffene Bild in Programmen laden und anzeigen lässt die einfach den Fehler in den Metadaten ignorieren.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
geraldfo
User
Beiträge: 44
Registriert: Samstag 28. Januar 2023, 20:19
Wohnort: Nähe Wien

@__blackjack__ hat das in der Zwischenzeit auch geschrieben:
Nicht jede Anwendung oder Library behandelt ein jgp-File gleich.

Es könnte sein, dass im "Problem-File" ein ungewöhnliches Bitmuster enthalten ist, dass von einzelnen Anwendungen toleriert wird, von anderen Anwendungen oder Libraries aber nicht.

Vielleicht gibt es unterschiedliche jpg-Versionen oder irgendwelche neuen jpg-Features, mit denen deine Library nicht umgehen kann.

Vielleicht gibt es irgendwo ein Tool zur genaueren Prüfung von jgp-Files.

LG Gerald
Benutzeravatar
grubenfox
User
Beiträge: 430
Registriert: Freitag 2. Dezember 2022, 15:49

eine schnelle Suche liefert mir unter anderem dieses (ich habe keine Ahnung wie tauglich die Suchergebnisse sind):
https://photo.stackexchange.com/questio ... -of-images
http://www.imageforensic.org/

Das `jpeginfo`, das im ersten Link erwähnt wird, erscheint mir aber recht interessant...
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@geraldfo: was auch immer Du mit Bitmuster meinst. Der JPEG-Reader von docx scheitert daran, dass es die Exif-Daten nicht richtig interpretieren kann. Ob das daran liegt, dass docx einen Bug hat, oder ob die Datei sich nicht an Standards hält, kann man nur sagen, wenn man die Datei hat. Man müßte das Problem auf eine Minimalbeispiel-Datei reduzieren und dann als Bug-Report melden.
geraldfo
User
Beiträge: 44
Registriert: Samstag 28. Januar 2023, 20:19
Wohnort: Nähe Wien

was auch immer Du mit Bitmuster meinst
Ich meine damit eine Folge von Bits oder Bytes, die von der einlesenden Library als ungültig interpretiert wird.
Könnte alles Mögliches. z. B. ein unerwarteter Wert in den Metadaten, ein unerwartetes Unicode-Zeichen.
zapatas
User
Beiträge: 26
Registriert: Dienstag 1. Februar 2022, 19:25

Hey danke schonmal für das Feedback. Ich komme berufsbedingt leider erst später dazu da nochmal hinzuschauen, wenn auch meine Mittel wie bereits erwähnt eher begrenzt sind. Dennoch kam mir gerade eine Idee die vielleicht die Fehler erklären könnte.

Manche Bilder müssen nochmal nacheditiert werden da die Etikettierung nicht korrekt war. Dazu werden manchmal Anzeigevorschauen der Bilder verwendet. Mittels Greenshot wird das Bild gescreenshottet, via PowerPoint dann z.B. die Bezeichnung auf der Grafik (es handelt sich um Probematerial) manuell geändert. Davon Screenshot, zurück als .jpg abgespeichert. D.h. zwar hat man eine Bildschirmlupe bei dieser Arbeit, doch es kann ja schnell passieren das man dann einige Pixel abknipst. Ich hatte mir dabei bisher nicht viel gedacht da zum einen ich pers. das nicht so verwende (da ich die Bezeichnungen typischerweise korrekt ausführe). Aber könnte hier der schwarze Peter stecken ? Ebenso dachte ich ja da die Bilder eh auf 5 cm eingepasst werden sollte auch das kein Problem sein oder? Mir fehlt leider die Erfahrung um mich da tiefer in die Materie einzudenken :(
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Fehlermeldung bezieht sich ziemlich klar (und wie jetzt wirklich mehrfach erwaehnt) auf die Tags im Bild. Die sind kaputt, und haben nichts mit Pixeln zu tun.
Antworten