Seite 1 von 1

Kleiner Tip...

Verfasst: Mittwoch 16. August 2006, 19:26
von rethus
Hallo,
ich habe mit Hilfe dieses Forums bereits ein tolles Script zusammengebaut, das mit einiges an Arbeit abnimmt.
Nun benötige ich nochmal kurz einen kleinen Tip....

Folgende Funktion funktionierte bisher einwandfrei:

Code: Alles auswählen

def is_headline(line):
    """Tests if line is a headline."""
    return line.upper() == line
Die Funktion stellte Fest, ob in einer Zeile ein ausschließlich groß geschriebenes Wort vorgekommen ist... wenn ja, hat es diese als headline definiert....

Nun haben sich die Rahmenbedingungen geändert....
Es kann nun sein, das das Wort nicht ausschließlich groß geschrieben ist, sondern dass auch kleinbuchstaben darin vorkommen.

Aber ein merkmal, das diese eingelesene Zeile von anderen unterscheidet ist, das kein ; im Text vorkommt.

Wie kann ich nun die Abfrage gestalten, das nur 1 Wort (mit beliebig vielen Zeichen) in einer Zeile steht, und KEIN doppelpunkt (:) darin enthalten ist?

Sorry wenn ich sowas einfaches hier frage... aber ich stehe irgendwie gedanklich auf dem Schlauch :roll:

Das ganze Script gibts hier: http://www.python-forum.de/topic-6805.html?highlight=

Verfasst: Mittwoch 16. August 2006, 19:54
von Python 47
Also ich würde es so in etwa machen:

Code: Alles auswählen

from string import letters

def is_headline(line, y=0):

   for x in line:
      if x==':' or x not in letters:
         y=y+1

   if y>0:
      print 'This is not a Headline!'
   
   else:
      print 'This is a Headline!'

Re: Kleiner Tip...

Verfasst: Mittwoch 16. August 2006, 21:18
von BlackJack
rethus hat geschrieben:Wie kann ich nun die Abfrage gestalten, das nur 1 Wort (mit beliebig vielen Zeichen) in einer Zeile steht, und KEIN doppelpunkt (:) darin enthalten ist?
Ein Wort bedeutet keine Leerzeichen. Also kannst Du testen ob kein Leerzeichen und kein Doppelpunkt in der Zeile sind:

Code: Alles auswählen

def is_headline(line):
    return ' ' not in line and ':' not in line
@Python Master 47: Warum zählst Du `y` hoch, wenn schon beim ersten "Treffer" das Ergebnis der Funktion feststeht?

Verfasst: Mittwoch 16. August 2006, 21:28
von Python 47
BlackJack: Ja ich könnte auch mit break aus der for schleife springen wäre einfacher und kürzer.

Code: Alles auswählen

def is_headline(line):
   for x in line:
      if x==':' or x==' ':
         print 'This is not a Headline!'
         break

Verfasst: Mittwoch 16. August 2006, 21:46
von birkenfeld
Warum sollte eine explizite Schleife kürzer sein als ein "return Ausdruck"?

Verfasst: Mittwoch 16. August 2006, 22:22
von Python 47
Nein da hast du was falsch verstanden. BlackJack hat mich darauf hingewiesen, dass mein 1.Code nicht wirklich gut ist(weil ich y inkremmentiere usw.) und das weiß ich auch, da ich ihn schnell in 2 min zusammengebastelt habe, weil ich fort musste und wenigstens eine Lösung anbieten wollte. Und da habe ich ihm recht gegeben und gesagt das mein Code(so wie ich ihn für gut halte(da mir solche Codes wie BlackJack ihn angeboten hat nicht gefallen(ist auch egal warum)) auch noch kürzer geht(2.Code von mir) und nicht gemeint das mein Code kürzer geht ist als BlackJacks Code. :lol:

Verfasst: Mittwoch 16. August 2006, 22:27
von birkenfeld
Überzeugt. :)

Verfasst: Donnerstag 17. August 2006, 13:08
von rethus
Vielen Dank schon mal... ich probiers gerad mal aus....

Verfasst: Donnerstag 17. August 2006, 14:09
von rethus
Also die Version von BlackJack haut leider nicht hin...

Ich bekomme nun folgende Fehlermeldung:
Traceback (most recent call last):
File "./con1.py", line 125, in ?
main()
File "./con1.py", line 118, in main
create_Index(out_file)
File "./con1.py", line 107, in create_Index
index+="<td><a href='#%s'>%s</a></td></tr>\t\t\n" % (inhalt,inhalt)
IndexError: list index out of range


Diese Meldung bekomme ich nicht, wenn ich die Zeile wieder lösche.... kann es sein, das da die Syntax irgendwo fehlerhaft ist?
Bzw. ist mir nicht ganz klar, was da von der Zeile zurückgegeben wird?

Müsste das nicht irgendwie so aussehen:

Code: Alles auswählen

def is_headline(line):
    if ' ' not in line and ':' not in line
    return line

Verfasst: Donnerstag 17. August 2006, 14:36
von rethus
Hier mal zum besseren Verfolgen der Sache beide Scripte:

Befehlszeile für den Start
./convert.py text1.txt text2.txt INI INI
convert.py

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso8859-1 -*-

from sys import argv, exit
from os import getcwd
import re
import os

if len(argv) < 4:
    print '\nBitte geben Sie die Namen der Ein- und Ausgabedateien in dem Format "convert.py text1.txt text2.txt" ein,\n gefolgt von dem Tabellennamen (TNLxxx); Abbruch.\n'
    exit(1)

f=file(getcwd()+"/"+argv[1],"r")
a=f.readlines()
f.close()

c=""

for i in a:

#    if i.find("Einschränkung Wertebereich") != -1:
#        i += "</td></tr></table><table><tr><td>\n"
    c += i 
    
# Umbrueche innerhalb eines beschreibenden Textes rausziehen.
c=c.replace("\n\t\t","")
# verbleibende Tabulatoren entfernen
c=c.replace("\t","")
# Fehlerhafte einrueckung der Zeile Attribut korrigieren
c=c.replace("Attribut "+argv[3],"Attribut:"+argv[3])



f=file(getcwd()+"/"+argv[2],"w")
f.write(c)
f.close()

# Tabellenkonstrukt erstellen# externe python-Datei:
os.system("./con1.py "+argv[3])
print '\n\nEnde des Scriptes\n\n Der Text wurde in die Datei text3.txt geschrieben.'
con1.py

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso8859-1 -*-
from __future__ import division
from sys import argv
import sys

def is_headline(line):
    """Tests if line is a headline."""
    return line.upper() == line

class BlockIterator(object):
    """Iterator over blocks delimited by headlines.
   
    Returned items are tuples with headline and iterator over lines of the body
    until the next headline.
   
    lines : iterator over strings
        Lines with headlines and body lines.
    headline : string
        The current headline.
    stop : bool
        Flag that indicates that this iterator is exhausted.
    """
    def __init__(self, lines):
        self.lines = iter(lines)
        self.headline = self.lines.next()
        assert is_headline(self.headline)   # First line is headline?
        self.stop = False
   
    def __iter__(self):
        return self
   
    def next(self):
        def iter_body():
            while True:
                try:
                    line = self.lines.next()
                except StopIteration:
                    self.stop = True
                    raise
                if is_headline(line):
                    self.headline = line
                    break
                else:
                    yield line

        if self.stop:
            raise StopIteration()
        else:
            return (self.headline, iter_body())


def iter_description(lines):
    """Iterates over lines and returns iterable over key, value tuples.
   
    Lines are splitted at colons into keys and values.  If a line doesn't
    contain a colon the entire line will be added to the last value.
    """
    key, value = None, None
    for line in lines:
	splitted = line.split(':', 1)
        if len(splitted) == 1:
            value += line
        else:
            if key is not None:
                yield key, value
            key, value = splitted
    if key is not None:
        yield key, value


def write_table(blocks, out_file):
    global inhalt
    global beschreibung
    inhalt=[]
    beschreibung=""
    for headline, body in blocks:
        # Headline zwischenspeichern fürs Inhaltsverzeichnis
	inhalt.append(headline.replace("\n",""))
	# Tabellen-Grundgerüst erstellen
	beschreibung += '<a name="%s"></a><br><table class="table" border="0">\n<col width="128*"><col width="400*">\n' % headline
	beschreibung += '<tr>\n<th colspan="2">%s</th>\n</tr>' % headline
	#out_file.write('<br><table class="table" border="0"><a name="%s"></a> <col width="128*"> <col width="400*">' % headline)
        #out_file.write('<tr><th colspan="2">%s</th></tr>' % headline)
        # Inhaltliche Zeilen parsen
	for key, value in iter_description(body):
            beschreibung+='<tr>\n<td>%s</td>\n<td>%s</td>\n</tr>' % (key, value)
	    #out_file.write('<tr><td>%s</td><td>%s</td></tr>' % (key, value))
        # Schließen des Tabellen-Grundgerüstes
	beschreibung+='</table><p align="right"><a href="#top">nach oben</a></p>\n\n'
	#out_file.write('</table><p align="right"><a href="#top">nach oben</a></p>')

def create_Index(out_file):
	global inhalt
	index="<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n<html><head>\n<title>"+argv[1]+": Beschreibung der Spalten</title><meta name='AUTHOR' content='Suther Kommunikationsdesign (www.suther.de)'><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'><link rel='stylesheet' type='text/css' href='./CSS/style.css'></head>"
	index+="<body><a name='top'></a><h1>"+argv[1]+": Beschreibung der Spalten</h1><p>Um direkt zu einer Spaltenbeschreibung zu gelangen, klicken Sie einfach auf eine der folgenden Spaltenbezeichnungen:</p>"	
	index+="<table class='table'>\n<tr><th colspan='5'>Übersicht der Spaltenbeschreibungen von "+argv[1]+"</th></tr>\t\n"
	# Inhalt des Arrays auf 3 Spalten aufteilen
	i=0
	#print len(inhalt)
	while i < len(inhalt):
		index+="<tr><td><a href='#%s'>%s</a></td>\t\t\n" % (inhalt[i],inhalt[i])
		i= i+1
		index+="<td><a href='#%s'>%s</a></td>\t\t\n" % (inhalt[i],inhalt[i])
		i= i+1
		index+="<td><a href='#%s'>%s</a></td></tr>\t\t\n" % (inhalt[i],inhalt[i])
		i= i+1
	index+="</table>\n\n</body></html>"
	out_file.write('%s' % index)
	#print index
	
def main():
    in_file = open('text2.txt')
    out_file = open('text3.txt', "wt")
    write_table(BlockIterator(in_file), out_file)
    out_file.seek(0)
    create_Index(out_file)
    out_file.write('%s' %beschreibung)
    in_file.close()
    out_file.close()


if __name__ == '__main__':
    main()

Ort der Scriptänderung ist in der 2. Datei Zeile 10

Verfasst: Donnerstag 17. August 2006, 17:41
von Python 47
Und was passt dir an meinem 2. Code nicht? :shock:

Verfasst: Samstag 19. August 2006, 09:37
von BlackJack
rethus hat geschrieben:Also die Version von BlackJack haut leider nicht hin...

Ich bekomme nun folgende Fehlermeldung:
Traceback (most recent call last):
File "./con1.py", line 125, in ?
main()
File "./con1.py", line 118, in main
create_Index(out_file)
File "./con1.py", line 107, in create_Index
index+="<td><a href='#%s'>%s</a></td></tr>\t\t\n" % (inhalt,inhalt)
IndexError: list index out of range


Diese Meldung bekomme ich nicht, wenn ich die Zeile wieder lösche.... kann es sein, das da die Syntax irgendwo fehlerhaft ist?
Bzw. ist mir nicht ganz klar, was da von der Zeile zurückgegeben wird?


Das hat mit `is_headline()` nichts zu tun. Es ist auch kein Syntaxfehler. Du versuchst dort auf ein Listenelement zuzugreifen das es nicht gibt. `create_Index()` ist fehlerhaft. Wenn Du die `is_headline()` änderst, so dass sie keine Überschriften mehr erkennt, dann wird der Rumpf der ``while`` Schleife nicht ausgeführt und der `IndexError` tritt nicht auf.

Verfasst: Samstag 19. August 2006, 09:45
von BlackJack
rethus hat geschrieben:

Code: Alles auswählen

def create_Index(out_file):
	global inhalt
        # [...]
	# Inhalt des Arrays auf 3 Spalten aufteilen
	i=0
	#print len(inhalt)
	while i < len(inhalt):
		index+="<tr><td><a href='#%s'>%s</a></td>\t\t\n" % (inhalt[i],inhalt[i])
		i= i+1
		index+="<td><a href='#%s'>%s</a></td>\t\t\n" % (inhalt[i],inhalt[i])
		i= i+1
		index+="<td><a href='#%s'>%s</a></td></tr>\t\t\n" % (inhalt[i],inhalt[i])
		i= i+1
Hier ist der Fehler. Wenn `len(inhalt)` nicht durch drei teilbar ist, dann versuchst Du auf ein nicht vorhandenes Element in `inhalt` zuzugreifen.

Randbemerkung, man kann `inhalt` auch als Argument übergeben um das ``global`` loszuwerden.

Verfasst: Montag 4. September 2006, 13:32
von rethus
jups das wars.

Danke