OHwei, wer kann mir helfen? Bitte

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.
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 :)
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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
Zuletzt geändert von Milan am Montag 27. Dezember 2004, 12:43, insgesamt 2-mal geändert.
Gast

Hey du bist ein Schatzi, danke :lol:

Selbst wenns net geht hab ich zumindest Ansätze, wie es zu lösen ist... :)
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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
[code]#!/usr/bin/env python
import this[/code]
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*
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Meine Lösung ergänzt nur einzeilige Kallibrationen.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Milans Lösung aber auch, is halt etwas kryptischer als meine ;)

Dookie
[code]#!/usr/bin/env python
import this[/code]
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
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?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Nö, du must nur Gross/Kleinschreibung beachten False statt false ;)

Dookie
[code]#!/usr/bin/env python
import this[/code]
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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".
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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()
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
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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.
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
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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
[code]#!/usr/bin/env python
import this[/code]
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Falls du doch mal nen aktuelleres Linux probieren/installieren willst, schau dir mal ubuntu an.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
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
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
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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
[code]#!/usr/bin/env python
import this[/code]
Antworten