Seite 1 von 2

OHwei, wer kann mir helfen? Bitte

Verfasst: Sonntag 26. Dezember 2004, 21:54
von Gast
Sorry Leute dass ich das Board einfach so missbrauche, aber ich muss dringend über die Feiertage hier das System umstellen und stosse auf ein kleines Problemchen...

Forlgende Situation:
Ich hab eine XML-Datei, die zb folgendes Codestück enthält

Code: Alles auswählen

			<CALIB DETECTOR_ID="DET1" column1="ID" column2="EpochInc" column3="Mean" column4="Sigma" column5="Peak" column6="Skewness" column7="Kurtosis" column8="Number">
				0 134518476560000 43434 16 43431 0.0003 0.0000 995
				1 474922911440000 43436 17 43430 0.0003 0.0000 1028
			</CALIB>
Nun erhält nicht jede XML-Datei 2 oder mehr Kalibartionen. Daher muss ich jedes File einzeln durchparsen und eine evtl nicht vorhandene 2te Calibartion anhängen. Also sprich wenn nur 1 Calibration vorhanden ist muss ich eine 2te hinzufügen, sonst kann die Messung nicht ausgewertet werden
Sprich wenn also folgender Fall auftritt:

Code: Alles auswählen

			<CALIB DETECTOR_ID="DET1" column1="ID" column2="EpochInc" column3="Mean" column4="Sigma" column5="Peak" column6="Skewness" column7="Kurtosis" column8="Number">
				0 134518476560000 43434 16 43431 0.0003 0.0000 995
			</CALIB>
Also nur eine Kalibration vorhanden ist, soll er eine weitere (fiktive) Kalibration anhängen. Sprich eine 2te Zeile und statt der 0 eine 1 als Counter. Die restlichen Werte können gleich bleiben bis auf die Zahl 134518476560000 (Timestamp) bei der Zahl sollen die ersten 2 Stellen jeweils um 2 erhöht werden, also in diesem Falle 354518476560000, so dass dann die korregierte XML so aussieht

Code: Alles auswählen

			<CALIB DETECTOR_ID="DET1" column1="ID" column2="EpochInc" column3="Mean" column4="Sigma" column5="Peak" column6="Skewness" column7="Kurtosis" column8="Number">
				0 134518476560000 43434 16 43431 0.0003 0.0000 995
				1 354518476560000 43434 16 43431 0.0003 0.0000 995
			</CALIB>

Ich hoffe mir kann da jemand behilflich sein, ich probier nun schon Stunden rum und es kommt nichts sinnvolles raus, weil ich echt ein Python Anfänger bin und mir jeden Befehl aus dem Web suchen muss.

Code: Alles auswählen

import sys,ftplib,os,string                                                     
infile = open("test.tst", "r")                                                  
zeilen = infile.readlines()                                                     
infile.close                                                                    

outfile = open("testneu.tst","w")                                               
for x in zeilen:                                                                

     #Tja was sollte da stehen? :)    

Wär echt total nett wenn sich jemand ein paar Minuten Zeit nehmen könnte, weil das System nach den Weihnachtstagen stehen soll, und ich doch schon arg in Zeitdruck bin.

Danke schonmal :)

Verfasst: Sonntag 26. Dezember 2004, 23:31
von Milan
Hi. Falsches Forum, gehöhrt unter Allgemeine Fragen... mal ein Versuch einer schnellen Lösung (quick and dirty):

Code: Alles auswählen

infile = file("test.tst", "r")
lines=iter(infile)
outfile = file("testneu.tst","w")
try:
    while True:
        line=lines.next()
        if "<CALIB" not in line:
            outfile.writeline(line)
            continue
        line1=lines.next()
        line2=lines.next()
        if "</CALIB>" not in line2:
            outfile.writelines([line,line1,line2,lines.next()])
            continue
        nums=[num for num in line1.split() if num!=""]
        nums[0]="1"
        nums[1]=str(long(nums[1])+22*10**(len(nums[1])-2))
        line11=" "*line1.find("0")+" ".join(nums)+"\n"
        outfile.writelines([line,line1,line11,line2])
except StopIteration:
    infile.close()
    outfile.close()
hth, Milan

Verfasst: Sonntag 26. Dezember 2004, 23:40
von Gast
Hey du bist ein Schatzi, danke :lol:

Selbst wenns net geht hab ich zumindest Ansätze, wie es zu lösen ist... :)

Verfasst: Sonntag 26. Dezember 2004, 23:52
von Dookie
Hi,

Code: Alles auswählen

def new_calib(line):
    """ Neue Zeile erzeugen """
    pos = line.find("0 ")
    repl = "1 " + str(int(line[pos+2:pos+4])+22)[:2]
    return line.replace(line[pos:pos+4], repl, 1)

infile = open("test.tst", "r")                                                 
outfile = open("testneu.tst","w")

chkflag = False
cline = ""                                       
for line in infile:
    if cline: # Zeile gemerkt?
        if line.find("</CALIB>") > -1: #schon Endtag?
            line = new_calib(cline) + line # neue Zeile davor einfuegen
        cline = "" # Zeile vergessen
    if chkflag:
        cline = line # Zeile Merken
    outfile.write(line)
    chkflag =  line.strip().startswith("<CALIB") # naechste merken!
    
outfile.close()
infile.close()
Gruß

Dookie

Verfasst: Sonntag 26. Dezember 2004, 23:53
von Gast
Mhm soweit ich das nun aber sehe, habt ihr beide den Fall vergessen, dass bereits 2 oder mehr Calibartionen vorhanden sind oder? Dann brauhct man ja nix anhängen.

Bei Milans Lösung blick ich immo noch net ganz durch *g*

Verfasst: Sonntag 26. Dezember 2004, 23:54
von Dookie
Meine Lösung ergänzt nur einzeilige Kallibrationen.


Gruß

Dookie

Verfasst: Montag 27. Dezember 2004, 00:00
von Dookie
Milans Lösung aber auch, is halt etwas kryptischer als meine ;)

Dookie

Verfasst: Montag 27. Dezember 2004, 00:05
von Gast
Ach mann ich bin ja so dumm *aufdenKopfschlag*

Dankeschonmal ihr beiden ich hoff der thread ist morgen noch da, muss vorher noch was anderes fertig machen

Verfasst: Montag 27. Dezember 2004, 01:14
von Gast
Traceback (innermost last):
File "xmlparser.py", line 12, in ?
chkflag = false
NameError: false

MHm ich find leider nix zu dem Thema, brauch ich evtl für Boolsche Variablen ne bestimmte Library oder so?

Verfasst: Montag 27. Dezember 2004, 01:48
von Dookie
Nö, du must nur Gross/Kleinschreibung beachten False statt false ;)

Dookie

Verfasst: Montag 27. Dezember 2004, 12:49
von Milan
Hi. Hatte trotzdem 2 Fehler drin: wenn Nachbesserungen notwendig waren hab ich die einleitende Zeile und die erste Messung zweimal in die Datei geschrieben und den Timestamp hatte ich jeweils nur um 1 statt 2 erhöht. War dann wohl doch ein wenig zu schnell :wink: . Dafür gehts jetzt :) .

@gast: ist das zufällig für ein Schulprojekt mit ner Sat-Schüssel? Ich hab da so nen kleinen Verdacht :roll: :lol: ... Und eine Frage noch: ich les gerade nochmal:
Nun erhält nicht jede XML-Datei 2 oder mehr Kalibartionen
Es können also auch mehr als 2 dastehen? Dann müsste ich nochmal nachlegen... bei Dookie hauts wegen dem chkflag hin :wink: . War halt nur "quick and dirty".

Verfasst: Montag 27. Dezember 2004, 13:43
von Milan
So, jetzt hab ich nachgelegt :wink: . Sieht natürlich nicht so schön aus wie die Forschleife von Dookie, aber funktioniert genauso. Man kann den Buffer caliblines natürlich noch beliebig weiter verändern, falls da noch mehr nötig sein sollte...

Code: Alles auswählen

infile = file("test.tst", "r")
lines=iter(infile)
outfile = file("testneu.tst","w")
try:
    while True:
        startline=lines.next()
        if "<CALIB" not in startline:
            outfile.writeline(startline)
            continue
        caliblines=[startline]
        for nextline in lines:
            caliblines.append(nextline)
            if "</CALIB>" in nextline:
                break
        else: #Ausnahmefall! Falls der letze Block kein Ende hat...
            outfile.writelines(caliblines)
            break
        if len(caliblines)>=4:
            outfile.writelines(caliblines)
            continue
        nodeline=caliblines[1]
        nums=[num for num in nodeline.split() if num!=""]
        nums[0]="1"
        nums[1]=str(long(nums[1])+22*10**(len(nums[1])-2))
        caliblines.insert(2,nodeline[:nodeline.find("0")]+" ".join(nums)+"\n")
        outfile.writelines(caliblines)
except StopIteration:
    pass
infile.close() 
outfile.close()

Verfasst: Montag 27. Dezember 2004, 16:19
von Gast
Dookie hat geschrieben:Nö, du must nur Gross/Kleinschreibung beachten False statt false ;)

Dookie
Sicher? Also das hat bei MIR keinen unterscheid gemacht.
Hab auch True / true probiert genau das selbe

Verfasst: Montag 27. Dezember 2004, 16:33
von Milan
Uiuiui... ist deine Pythonversion älter als 2.2? Ab da wurde True und False eingeführt. Eine einfache Belegung mit True=1 und False=0 würde helfen, aber ein Update ist empfehlenswerter. Mittlerweile gibt es Python 2.4 und das bringt ordentlich Speed up.

Verfasst: Montag 27. Dezember 2004, 16:36
von Gast
Suse Linux 6.2, Standardpackages und Realtimekernel.
Also ICH installier auf dem System nix neues, da darfst du gerne kommen und das nachholen :P

Verfasst: Montag 27. Dezember 2004, 16:39
von Dookie
Achtung, zu Python2.4 gibts aber noch nicht sehr viele Thirdpartymodule, das wird wohl noch etwas dauern, empfehlenswert ist Python2.3 zu nehmen. Falls das nicht geht, weil das script auf einem Server laufen soll zu dem du keinen Rootzugriff hast, verwende die Zuweisung Am Anfang Deines Scripts.

Code: Alles auswählen

try:
    True
except NameError:
    False, True = 0, 1

Gruß

Dookie

Verfasst: Montag 27. Dezember 2004, 16:43
von Dookie
Falls du doch mal nen aktuelleres Linux probieren/installieren willst, schau dir mal ubuntu an.


Gruß

Dookie

Verfasst: Montag 27. Dezember 2004, 16:44
von Gast

Code: Alles auswählen

  File "xmlparser.py", line 22
    nums=[num for num in nodeline.split() if num!=""]
                         ^
SyntaxError: invalid syntax
Mhm ich glaub ich muss was ganz ganz einfaches schreiben, ich versuch mir das jetzt selber aus den Finger zu saugen, egal wie quick&dirty es ist.

Also fangen wir mit den "Basics" an. Leider hab ich das Pythonbuch des Kollegen net hier, das würd mir sehr weiterhelfen.

Ich öffne ne Datei und mach
zeilen = infile.readlines()

Wie kann ich nun auf ein einzelne Zeile zugreifen? Klappt da zeile[index] oder ähnliches?
Und nun nehmen wir an, ich hab in habe in der zehnten Zeile 1 Calibartion möchte nun 1 Zeile adden wie ginge das?
Den rest denke ich könnt ich mir selber basteln, sprich Erkennungsmechanismus, etc

Verfasst: Montag 27. Dezember 2004, 16:46
von Gast
Ich werd mich nur hüten und an dem System IRGENDETWAS machen, was den Betrieb beinflussen könnte. Schon allein unser Sysadmin (ja und der kennt sich mit Linux aus) hat geschlagene 3 Stunden gebraucht um Samba zu installieren, leigt wohl an dem doofen Realtimekernel

Verfasst: Montag 27. Dezember 2004, 16:51
von Dookie

Code: Alles auswählen

nums=[num for num in nodeline.split() if num!=""]
ist eine Listcomprehension, die gibts erst seit Python 2.2 oder 2.3, also wohl auch nicht bei Deiner Pythonversion. Welche Version du hast bekommst du mit einem einfachen python in der Console raus.

Hier im Forum ist Python2.3 eigentlich schon voraussetzung, das viele Sachen laufen. Es gibt auch schon erste Posts mir Lösungen für Python2.4. Schmeiss suse runter und installier ein richiges Linux, dann geht das updaten von selber ;)


Gruß

Dookie