Vorschlag zur Optimierung

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.
Antworten
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Ich bitte um Vorschläge zur Optimierung oder Verbesserung meines Programms.
Diese Programm bearbeitet Nc-Dateien(Textformat). Es sucht bestimmte Werte heraus und zeigt diese an. Außerdem fügt es einen bestimmten Wert von einer Stelle des Programms an eine andere hinzu.
Es werden sechsstellige Nc-Dateien nacheinandner bearbeitet, so viele wie vorhanden und falls vorhanden.
Hier der Code:

Code: Alles auswählen

import glob
from string import *
import re

#Dateien eingrenzen
NcFiles=glob.glob("?????1.nc")
NcFiles.sort()
zwischenzeile=73*"-"
#Dateien nacheinander oeffnnen
for x in NcFiles:
    NcFile=file(x,"rb+")
    name=x
    #Datei lesen
    for i in range(0,15):
        suche=NcFile.readline()
        #Fraeser suchen
        fraeser=re.findall("\(KUGELFRAESER.*D=.*?\...|\(SCHAFTFRAESER.*R=.*?\...\
                           |\(.*FRAESER.*D=.*?\...", suche)
        if fraeser <> []:
            fraeserausgabe=fraeser[0]+")"
        #Fraeserzeile suchen  
        ersetzen=re.findall("N.*FRAESER.*?\)", suche)
        if ersetzen <> []:         
            wert1=ersetzen[0]
            wert2=wert1[:-1]
        #A- oder B- und C-Winkel suchen                           
        winkel=re.findall("A.*C.*?G01|B.*C.*?G01", suche)
        if winkel <> []:
            ab=re.findall("A.*?\....|B.*?\....", winkel[0])
            c=re.findall("C.*?\....", winkel[0])
            #Anstellung in Datei einfuegen
            pruefen=re.findall("Anstellung|C.?.?.?\....", wert1)
            if pruefen == [] and ab[0][1:]+c[0] <> "0.000C0.000":
                NcFile.seek(0,0)
                suche=NcFile.read(1024)
                neuschreiben=suche.replace(wert1, wert2 + " (Anstellung = "
                                           + ab[0]+ " " + c[0] + "))")
                NcFile.seek(1024)
                rest=NcFile.read()
                NcFile.seek(0,0)
                NcFile.write(neuschreiben)
                NcFile.write(rest)
                NcFile.flush()
            #Winkel ausgeben    
            print "%-15s%-35s%-15s%-15s" % (name,fraeserausgabe,ab[0],c[0])
            print zwischenzeile
    #Datei schliessen
    NcFile.close()    
ralf
User
Beiträge: 4
Registriert: Donnerstag 29. Mai 2003, 09:28
Wohnort: Swansea

HarryH hat geschrieben:Diese Programm bearbeitet Nc-Dateien(Textformat). Es sucht bestimmte Werte heraus und zeigt diese an. Außerdem fügt es einen bestimmten Wert von einer Stelle des Programms an eine andere hinzu.
Es werden sechsstellige Nc-Dateien nacheinandner bearbeitet, so viele wie vorhanden und falls vorhanden.
Hallo Harry,

kannst du mal paar NC-Beispieldateien zum downloaden bereitstellen?
Wenn man sieht was das Programm macht wird's sicherlicherlich einfacher. Ich weiss von CNC aus der Schule bloss noch das eine Zeile in etwas so "Nxxx Gxx Xxxx Yxxx" aufgebaut ist. Bloss da kocht ja auch jeder Hersteller sein Sueppchen. Also noch eine Kurzbeschreibung des NC-Syntaxes (vorallem fuer die die noch nie was damit zu tun hatten)

Ralf
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Wie ich eine Datei zum Download bereitstellen soll weiß ich nicht, aber ich werde dir den Kopf der Nc-Datei hier hinein kopieren.
-------
N1(DATEI : 100011.nc)
N2(Pos.)
N3(00.00.2003)
N4(Name)
N5(neues Format)
N6(SchaftFRAESER D=5.00)
N7(WANDSTAERKE=0.00 AUFMASS=0.50 ZUSTELLUNG=0.20 EILRUECKLAUF MITTE)
N8(T153M06F0S0)
N9X158.510Y73.970Z250.000G00
N10A30.000C0.000G01
N11Z164.424G00
N12Y76.470Z160.094G00
N13Y78.970Z155.764G01
N14X158.422Y80.252Z154.811
N15X158.620Y80.096Z154.553
N16X158.730Y80.012Z154.382
N17X158.833Y79.940Z154.204
N18X158.900Y79.890Z154.057
N19X158.960Y79.847Z153.907
------------
Du kannst dir ja diesen Kopf kopieren und z.B. als "100011.nc" abspeichern. Natürlich sind die Dateien im Normalfall viel länger, teilweise einige MB's groß, aber zum probieren reichts.
(N1..., N2..., usw. bezeichnet die Satznummern, dahinter stehen die Angaben für die Maschine)
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!

Hast Du denn das Programm ausgiebig getestet? Die REs sehen teilweise etwas seltsam aus. So wie ich mir vorstelle, wie z.B. ABC-Winkelzeilen aussehen könnten, dürften die kaum erkannt werden. Solltest Du auf jeden Fall nochmal gezielt drauf prüfen.

Backslashs haben in Python-Stringliteralen eine Sonderbedeutung. Um sie in REs 'buchstäblich' verwenden zu können, muss Du sie mit einem weiteren Backslash schützen. Beispiel: "python\\.exe". Besser: Du verwendest immer sog. raw strings für REs. Beispiel: r"python\.exe".

Dateiaktionen sollte man möglichst auf ihren Erfolg prüfen, z.B. mit try.

<> ist recht unüblich, spricht aber wohl nichts dagegen. Meist wird != verwendet.

Jan
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi ralf,

besser als die funktionen aus re zu verwenden ist es mit matchobjekten zu arbeiten. Ich hab mal Deinen Code dementsprechend umgestrickt.

Code: Alles auswählen

import glob
from string import *
import re

#Dateien eingrenzen
NcFiles=glob.glob("?????1.nc")
NcFiles.sort()
zwischenzeile=73*"-"

fraeser_mobj = re.compile("\(KUGELFRAESER.*D=.*?\...|\(SCHAFTFRAESER.*R=.*?\...\
                           |\(.*FRAESER.*D=.*?\...")
ersetzen_mobj = re.compile("N.*FRAESER.*?\)")
winkel_mobj = re.compile("A.*C.*?G01|B.*C.*?G01")
ab_mobj = re.compile("A.*?\....|B.*?\....")
c_mobj = re.compile("C.*?\....")
pruefen_mobj = re.compile("Anstellung|C.?.?.?\....")

#Dateien nacheinander oeffnnen
for x in NcFiles:
    NcFile=file(x,"rb+")
    name=x
    #Datei lesen
    for i in xrange(0,15):
        suche=NcFile.readline()
        #Fraeser suchen
        fraeser=fraeser_mobj.findall(suche)
        if fraeser <> []:
            fraeserausgabe=fraeser[0]+")"
        #Fraeserzeile suchen 
        ersetzen = ersetzen_mobj.findall(suche)
        if ersetzen <> []:         
            wert1=ersetzen[0]
            wert2=wert1[:-1]
        #A- oder B- und C-Winkel suchen                           
        winkel=winkel_mobj.findall(suche)
        if winkel <> []:
            ab=ab_mobj.findall(winkel[0])
            c=c_mobj.findall(winkel[0])
            #Anstellung in Datei einfuegen
            pruefen=pruefen_mobj.findall(wert1)
            if pruefen == [] and ab[0][1:]+c[0] <> "0.000C0.000":
                NcFile.seek(0,0)
                suche=NcFile.read(1024)
                neuschreiben=suche.replace(wert1, wert2 + " (Anstellung = "
                                           + ab[0]+ " " + c[0] + "))")
                NcFile.seek(1024)
                rest=NcFile.read()
                NcFile.seek(0,0)
                NcFile.write(neuschreiben)
                NcFile.write(rest)
                NcFile.flush()
            #Winkel ausgeben   
            print "%-15s%-35s%-15s%-15s" % (name,fraeserausgabe,ab[0],c[0])
            print zwischenzeile
    #Datei schliessen
    NcFile.close()
Gruß

Dookie
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Schon mal vielen Dank für alle eure Anregungen! :D
Das manches vielleicht unüblich aussieht, kann leicht sein, da ich noch nicht sehr lange programmiere.

Antwort an Voges:
Ich habe das Programm getestet. Die Winkelsuche funktioniert. Ebenso das Ersetzen.
Um "N10A30.000C0.000G01" oder "N10B30.000C0.000G01" zu suchen habe ich folgenden Code geschrieben:

Code: Alles auswählen

winkel=re.findall("A.*C.*?G01|B.*C.*?G01", suche)
Um aus diesem Resultat A- oder B- und C-Winkel herauszusuchen:

Code: Alles auswählen

ab=re.findall("A.*?\....|B.*?\....", winkel[0]) 
c=re.findall("C.*?\....", winkel[0]) 

Frage an Dookie:
Was sind Matchobjekte und warum sind sie besser als die Funktionen aus "re"?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

gukst Du da,
http://www.python.org/doc/current/lib/node99.html
"but the version using compile() is more efficient when the expression will be used several times in a single program."
Heisst soviel wie, daß die Verwendung von compile und des daraus erheltenen MatchObjekts effizienter ist in der Ausführung wenn die gleiche "regular expression" mehrmals im Programm verwendet wird. Lass mal Deine Programmversion auf ein Megabytefile los und dann meine und vergleiche die Ausführungszeiten. Da sollte sich schon ein Unterschied feststellen lassen.


Gruß

Dookie
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!
HarryH hat geschrieben:Ich habe das Programm getestet. Die Winkelsuche funktioniert.
Ja, tatsächlich. Ich war der irrigen Meinung, dass die Alternativen jeweils geklammert werden müssen.
Jan
Nachtrag: Vielleicht hilft Dir noch sowas:

Code: Alles auswählen

>>> print re.findall(r"N\d+(A|B)(.*)C(.*?)G01","N10B30.000C0.000G01")
[('B', '30.000', '0.000')]
>>> 
So hast Du das Erkennen und das Extrahieren der Daten in einem Schritt.
XT@ngel
User
Beiträge: 255
Registriert: Dienstag 6. August 2002, 14:36
Kontaktdaten:

Kurze OT Frage :)
was macht

N3(00.00.2003)
N4(Name)
N5(neues Format)
N6(SchaftFRAESER D=5.00)
N7(WANDSTAERKE=0.00 AUFMASS=0.50 ZUSTELLUNG=0.20 EILRUECKLAUF MITTE)
N8(T153M06F0S0)

Sind das die Werte die mit den Variablen im NC Programm ausgetauscht werden
Und ist das ganze für eine bestimmte Steurung geschrieben?

MfG
Andreas
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!
Dookie hat geschrieben:Heisst soviel wie, daß die Verwendung von compile und des daraus erheltenen MatchObjekts effizienter ist in der Ausführung wenn die gleiche "regular expression" mehrmals im Programm verwendet wird.
Nochmal zu den Begriffen: re.compile() liefert ein "regular expression object" zurück und einige Methoden dieser RE-Objekte, z.B. search(), geben ein "match object" zurück.
>>> reObj = re.compile("N\d+(A|B)(.*)C(.*?)G01")
>>> matchObj = reObj.search("N10B30.000C0.000G01")
>>> matchObj.groups()
('B', '30.000', '0.000')
>>>

Jan
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

hallo

Danke für deinen Code, Jan! :D

Code: Alles auswählen

print re.findall(r"N\d+(A|B)(.*)C(.*?)G01","N10B30.000C0.000G01")
Damit spare ich zwei zusätzliche Zeilen.

An Andreas:
N3(00.00.2003)
N4(Name)
N5(neues Format)
N6(SchaftFRAESER D=5.00)
N7(WANDSTAERKE=0.00 AUFMASS=0.50 ZUSTELLUNG=0.20 EILRUECKLAUF MITTE)
N8(T153M06F0S0)

Sind das die Werte die mit den Variablen im NC Programm ausgetauscht werden
Und ist das ganze für eine bestimmte Steurung geschrieben?
Diese Zeilen sind nur Zusatzinformationen für den Maschinenbediener, außer N8... Da stecken Infos für die Steuerung drin.



An Dookie
Die Berechnungszeit mit Matchobjekten ist genau gleich mit "re".
Fuer 100 Files, zusammen 181mb groß, benötigte ich bei beiden Programmen jeweils 4:14 min.
Das die Berechnung überhaupt solange dauerte, liegt daran das die Programme auf einem Linux-Server liegen und mein Betriebssystem
Win2000 ist.
hans
User
Beiträge: 728
Registriert: Sonntag 22. September 2002, 08:32
Wohnort: Sauerland
Kontaktdaten:

HarryH hat geschrieben: Das die Berechnung überhaupt solange dauerte, liegt daran das die Programme auf einem Linux-Server liegen und mein Betriebssystem
Win2000 ist.
Installier doch einfach Cygwin auf W2K und greif direkt auf Linux zu, oder hat da ein Admin etwas dagegen?

Hans
Antworten