Seite 1 von 1

Python eleganter? Perl-Programm konvertieren

Verfasst: Donnerstag 12. September 2002, 09:14
von w1se
Hallo zusammen. :D

Bisher programmiere ich in PHP und Perl. Jetzt bin ich auf Python gestossen und finde besonders den Ansatz ohne { } zu arbeiten echt klasse. :-)

Doch um mich zu ueberzeugen, das Python ein Ersatz fuer Perl ist, der ebenso elegant (oder eleganter) ist, brauche ich eure Hilfe. Bitte helft mir, dieses Perl-Programm zu übertragen:

Code: Alles auswählen

#!d:\perl\bin\perl.exe -w
use strict;

my $datei = "server.txt";
my $zeilennr = 0;
my $titel = "Pruefe Serverliste";
my @spalten;
my $i = 0;

print "+" . "-" x (length($titel)+2) . "+\n";
print "| " . $titel . " +\n";
print "+" . "-" x (length($titel)+2) . "+\n";

open(DATEI, $datei);
while (<DATEI>){
	$zeilennr++;
	if (/^#!/){
		$_ =~ s/^...//;
		@spalten = split( / \| /, $_);
	}
	s/#.*//;			# Kommentarzeilen leeren
	next if /^\s*$/;	            # leere Zeilen ueberspringen
	@_ = split(/ \| /, $_);
	if (@_ < @spalten){
		print "Fehler in Zeile " . $zeilennr . ":\n";
		print $_ . "\n";
	}
}
print "\n" . $zeilennr . " Zeilen gesamt\n";
close(DATEI);
Das Programm liest eine Datei Zeile für Zeile ein, ignoriert dabei die Kommentarzeilen mit # am Anfang. Ausnahme ist die Zeile mit #! am Anfang, danach kommen die Spaltenüberschriften für die Felder.
Die Zeilen bestehen aus Spaltenwerten, die mit <SPACE>|<SPACE> getrennt sind.
Das Programm sucht Zeilen, die weniger Spalten als die Referenzspalte (die mit #!) haben.

Kriegt man das eleganter hin?

Danke
w1se

Re: Python eleganter? Perl-Programm konvertieren

Verfasst: Donnerstag 12. September 2002, 10:23
von Voges
Hallo!

Ich glaub', der Perlcode ließe sich auch noch eleganter gestalten. Einige der doch recht "teuren" RegExps ließen sich sicherlich vermeiden.

Mein Python-Vorschlag (lauffähig ab Version 2.2):

Code: Alles auswählen

import re,string

file = open("foo.dat")

counter = 0
for line in file:
	counter += 1
	
	if re.match(r"^\s*#[^!]",line):
		continue
	elif line.find("#!") == 0:
		anzSoll = line.count("|")
	else:
		anzIst = line.count("|")
		if(anzIst < anzSoll):
			print "Fehler in Zeile %d"%counter
    
file.close()
Geht vielleicht hier und da kürzer (mit map() und filter()), aber soll ja erstmal lesbar sein.

Jan

Re: Python eleganter? Perl-Programm konvertieren

Verfasst: Donnerstag 12. September 2002, 11:09
von joerg
Ich habe noch eine leicht abgewandelte Alternative zum Code von "Voges", allerdings ohne reguläre Ausdrücke.

Die Schleife würde dann so aussehen, leicht zusammengefaßt:

Code: Alles auswählen

for line in file: 
   counter += 1 
   line = line.lstrip()
   if line.startswith('#!'):
      anzSoll = line.count("|")
      continue
   if line[0] != '#' and line.count("|") < anzSoll: 
      print "Fehler in Zeile %d" %counter
Statt line.startswith('#!') würde auch line[:2] == '#!' gehen. Wie mein Code geschwindigkeitsmäßig ist, weiß ich allerdings nicht.

Aber ich finde es wirklich beeindruckend wie viel klarer und 'menschlicher' der Python-Code aussieht verglichen mit Perl. :lol:

Re: Python eleganter? Perl-Programm konvertieren

Verfasst: Donnerstag 12. September 2002, 12:42
von joerg
joerg hat geschrieben:

Code: Alles auswählen

   ...
   if line[0] != '#' and line.count("|") < anzSoll: 
   ...
Sorry, war noch ein Fehler drin: Wenn man stattdessen schreibt:

Code: Alles auswählen

   if line and line[0] != '#' and line.count("|") < anzSoll:
geht er auch schnell und problemlos über leere Zeilen drüber.

Danke | Python-Bücher

Verfasst: Freitag 13. September 2002, 10:36
von w1se
Hallo zusammen.


Danke euch für die schnellen Antworten :-)

Welche Python-Bücher empfiehlt ihr? Kennt ihr das Python-Buch aus dem Galileoverlag? Die PHP-Bücher und das Perl-Einsteigerbuch finde ich gut gemacht.

Gruß
w1se

Re: Danke | Python-Bücher

Verfasst: Freitag 13. September 2002, 13:18
von Voges
Hallo!

Zur Zeit dürfte noch kein deutsches Buch (wohl auch nicht das Galileo-Buch) die Neuerungen der Version 2.2 beschreiben, was ich schon als nachteilig ansehe.

Wenn Englisch kein Problem für Dich ist, wäre das folgende Buch vielleicht geeignet (ich kenne es allerdings nicht, soll aber gut sein):

Hetland, Magnus Lie
Practical Python
http://www.apress.com/book/bookDisplay.html?bID=93

Der Einführungsteil wird nicht so ausführlich sein wie bei einem ausgesprochenen Einsteigerbuch, dafür beinhaltet das Buch aber auch weiterführende Themen und zudem eine Sprachreferenz. Ich denke, wenn man bereits mit Scriptsprachen wie Perl oder PHP vertraut ist, wäre das Buch eine gute Wahl.

Ansonsten vielleicht sich erstmal mit dem Python-Tutorial über Wasser halten oder bei Ebay ein älteres Buch ersteigern und auf dt. Neuerscheinungen warten.

Jan

Python Bücher

Verfasst: Freitag 13. September 2002, 18:29
von Gast
Das Galileo Buch 'Einstieg in Python ist recht gut, es behandelt alle wesentlichen Grundlagen von Python und enthält darüber hinaus auch noch Einführungen zu dem Applicationserver Zope sowie ein Kapitel zum Umgang mit Datenbanken am Beispiel Mysql.
Für etwas ausführlichere Information zu Python ist mein Favorit bei den deutschsprachigen Büchern 'Python 2' von Martin von Löwis und Nils Fischbeck.
Während Einstieg in Python seinem Anspruch als Buch für Anfänger und Umsteiger sicherlich gerecht wird, ist Python 2 wohl mehr für etwas fortgeschrittene Anwender geschrieben.
Eine gute Übersicht zu deutschsprachigen Pythonbüchern befindet sich auf Peter Gerlach's Pythonseiten unter http://www.way2python.de/Kontakt/buecher.html.
Gruß
Jochim

Re: Python Bücher

Verfasst: Mittwoch 5. April 2023, 19:41
von Merkator
Gast hat geschrieben: Freitag 13. September 2002, 18:29 Das Galileo Buch 'Einstieg in Python ist recht gut, es behandelt alle wesentlichen Grundlagen von Python und enthält darüber hinaus auch noch Einführungen zu dem Applicationserver Zope sowie ein Kapitel zum Umgang mit Datenbanken am Beispiel Mysql.
Für etwas ausführlichere Information zu Python ist mein Favorit bei den deutschsprachigen Büchern 'Python 2' von Martin von Löwis und Nils Fischbeck.
Während Einstieg in Python seinem Anspruch als Buch für Anfänger und Umsteiger sicherlich gerecht wird, ist Python 2 wohl mehr für etwas fortgeschrittene Anwender geschrieben.
Eine gute Übersicht zu deutschsprachigen Pythonbüchern befindet sich auf Peter Gerlach's Pythonseiten unter http://www.way2python.de/Kontakt/buecher.html.
Gruß
Jochim
Sehr hilfreich xd

Re: Python eleganter? Perl-Programm konvertieren

Verfasst: Donnerstag 6. April 2023, 06:08
von bwbg
Leichenfledderer! :mrgreen:

Re: Python eleganter? Perl-Programm konvertieren

Verfasst: Donnerstag 6. April 2023, 11:31
von __blackjack__
Wenn das nun schon mal aus der Vergangenheit aufgetaucht ist, und da Python 2.2 schon seehr lange her ist, hier mal ein Ansatz in Python 3 (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3

FILENAME = "server.txt"
DELIMITER = "|"


def print_boxed_text(text):
    length = len(text) + 2
    horizontal_border = "+" + "-" * length + "+"
    print(horizontal_border)
    print("|", text, "|")
    print(horizontal_border)


def main():
    print_boxed_text("Prüfe Serverliste")
    with open(FILENAME, encoding="utf-8") as lines:
        expected_delimiter_count = 0
        line_number = 0
        for line_number, line in enumerate(lines, 1):
            if line.startswith("#!"):
                expected_delimiter_count = line.count(DELIMITER)
            elif (
                not line.lstrip().startswith("#")
                and line.count(DELIMITER) < expected_delimiter_count
            ):
                print(f"Fehler in Zeile {line_number}:\n{line}")

        print(f"\n{line_number} Zeilen gesamt")


if __name__ == "__main__":
    main()
Das Programm geht davon aus, das Kommentare nur alleine in Zeilen stehen können, und nicht in Datenzeilen. Denn dort könnte im vorliegenden Programm ein Kommentar mit Begrenzungszeichen im Kommentarteil das Ergebnis verfälschen. Falls das ein Problem darstellt, müsste man Kommentare tatsächlich entfernen:

Code: Alles auswählen

#!/usr/bin/env python3

FILENAME = "server.txt"
DELIMITER = "|"


def print_boxed_text(text):
    length = len(text) + 2
    horizontal_border = "+" + "-" * length + "+"
    print(horizontal_border)
    print("|", text, "|")
    print(horizontal_border)


def main():
    print_boxed_text("Prüfe Serverliste")
    with open(FILENAME, encoding="utf-8") as lines:
        expected_delimiter_count = 0
        line_number = 0
        for line_number, line in enumerate(lines, 1):
            if line.startswith("#!"):
                expected_delimiter_count = line.count(DELIMITER)
            else:
                line_without_comment, _, _ = line.partition("#")
                if line_without_comment.strip() and (
                    line_without_comment.count(DELIMITER)
                    < expected_delimiter_count
                ):
                    print(f"Fehler in Zeile {line_number}:\n{line}")

        print(f"\n{line_number} Zeilen gesamt")


if __name__ == "__main__":
    main()
Und man könnte eventuell noch testen ob vor der ersten Datenzeile auch tatsächlich eine "#!"-Zeile kam, und eventuell auch ob da nur *eine* solche Zeile in den Daten enthalten ist. Für den Fall, dass es in dem Dateiformat nur eine Headerzeile geben darf, und eine weitere einen Fehler darstellt.