Es gibt viele Möglichkeiten, dies zu tun. Persönlich würde ich vermeiden, Regex dafür zu verwenden, weil es wahrscheinlich nicht effizienter sein wird und der Ausdruck umständlich und unflexibel wird. Hier ist etwas, was ich kam mit:
class Entry:
def __init__(self):
self.time = None
self.animal = None
self.bird = None
self.fish = None
def __repr__(self):
fmt = "{0} {1} {2} {3}".format(
"Time: {time: <{width}}",
"Animal: {animal: <{width}}",
"Bird: {bird: <{width}}",
"Fish: {fish: <{width}}")
return fmt.format(
time=self.time, animal=self.animal,
bird=self.bird, fish=self.fish,
width=12)
def __radd__(self, other):
return self.__add__(other)
def __add__(self, other):
if type(other) == dict:
for i in [self.animal, self.bird, self.fish]:
if i in other: other[i] += 1
else: other[i] = 1
return other
elif type(other) == Entry:
return self.__add__({}) + other
else:
return self.__add__({})
def parse_log(path):
def extract(line):
start = line.find(':') + 1
return line[start:].strip()
entries = []
entry = None
with open(path, 'r') as f:
for line in f.readlines():
if line.startswith('-----'):
if entry: entries.append(entry)
entry = Entry()
elif line.startswith('Time'):
entry.time = extract(line)
elif line.startswith('Animal'):
entry.animal = extract(line)
elif line.startswith('Bird'):
entry.bird = extract(line)
elif line.startswith('Fish'):
entry.fish = extract(line)
if entry: entries.append(entry)
return entries
def print_output_1(entries):
for entry in entries:
print entry
def print_output_2(entries, time):
animals = sum([e for e in entries if e.time == time])
print "Time: {0}".format(time)
print "Name: Count:"
for animal, count in animals.items():
print "{animal: <{width}} {count}".format(
animal=animal, count=count, width=12)
logPath = 'log.log'
time = '2016-07-12 09:15:00'
entries = parse_log(logPath)
print_output_1(entries)
print ""
print_output_2(entries, time)
Der Ausgang (vorausgesetzt, dass log.log
wird die Eingangs Sie gab) ist:
Time: 2016-07-12 09:00:00 Animal: Brown Bear Bird: White Owl Fish: Salmon
Time: 2016-07-12 09:00:00 Animal: Brown Bear Bird: Parrot Fish: Tuna
Time: 2016-07-12 09:00:00 Animal: Lion Bird: White Owl Fish: Sword Fish
Time: 2016-07-12 09:15:00 Animal: Lion Bird: White Owl Fish: Sword Fish
Time: 2016-07-12 09:15:00
Name: Count:
White Owl 1
Sword Fish 1
Lion 1
Die Art und Weise dieser Code funktioniert, ist die objektorientierte Programmierung zu unserem Vorteil zu nutzen Um die Aufgaben zu vereinfachen, die wir tun müssen: Protokolleinträge speichern, Protokolleinträge in einem bestimmten Format darstellen und Protokolleinträge gemäß einer bestimmten Eigenschaft kombinieren.
Beachten Sie zunächst, dass das Entry
Objekt und seine Eigenschaften (self.time
, self.animal
, self.bird
, self.fish
) im Protokoll einen Eintrag darstellt. Unter der Annahme, dass die in den Eigenschaften gespeicherten Informationen korrekt sind, kann eine Methode erstellt werden, um diese Informationen als formatierte Zeichenfolge darzustellen. Die Methode __repr__()
wird aufgerufen, wenn Python die Zeichenfolgendarstellung eines Objekts wünscht, also schien es ein guter Platz, um diesen Code zu platzieren. In dieser Methode wird die format
-Funktion häufig verwendet, aber es sollte klar sein, wie sie nach dem Durchsuchen der Python-Dokumentation unter format
funktioniert.
Es wird eine Methode zum Kombinieren dieser Eintragsobjekte benötigt, um die von Ihnen angegebene zweite Ausgabe zu erhalten. Dies kann auf viele Arten geschehen und die Art und Weise, wie ich es gemacht habe, ist nicht unbedingt das Beste. Ich habe die Methoden __radd__()
und __add__()
verwendet, die aufgerufen werden, wenn der Operator +
für ein Objekt verwendet wird. Auf diese Weise kann der Code entry1 + entry2
oder sum([entry1, entry2])
verwendet werden, um die Summe der Tiere in beiden Einträgen zu erhalten. Die Klasse Entry
kann jedoch nicht zum Speichern des Ergebnisses der Summe verwendet werden, da sie keine beliebigen Informationen enthalten kann. Stattdessen wählte ich ein Objekt dict
, um das Ergebnis der Summierung zwei Entry
Objekte zu sein. Um mehr als zwei Entry
Objekte zu summieren, muss Entry
auch in der Lage sein, mit einem dict
Objekt zu summieren, weil Entry + Entry + Entry
dict + Entry
ergibt.
Die Funktion __add__()
prüft, ob das Objekt, zu dem es hinzugefügt wird, ein Objekt dict
ist. Wenn dies der Fall ist, prüft es, ob jedes der Tiere in dem Eintrag bereits in der dict
existiert. Wenn nicht, wird das Tier als Schlüssel hinzugefügt. Andernfalls wird der Wert dieses Schlüssels erhöht. __radd__()
ist ähnlich wie __add__()
, außer dass es unter bestimmten Umständen verwendet wird. Weitere Informationen finden Sie in der Python-Dokumentation.
Für den Fall, dass das Objekt ein Entry
, Code geschrieben worden sein könnte von jedem Entry
Objekt alle Tiere zu sammeln und ein dict
aus dieser Information erstellen, aber da gibt es bereits Code ist ein Entry
mit einem dict
hinzufügen Es ist einfacher, zuerst ein Objekt zu einem leeren dict
hinzuzufügen und dann das resultierende dict
mit dem anderen Entry
Objekt hinzuzufügen.
Für alle anderen Objekte, Entry
wird einfach die dict
Beschreibung von sich selbst zurückgeben, oder sich selbst mit einem leeren dict
hinzugefügt.
Jetzt sind alle Tools vorhanden, um die oben aufgeführten Ziele zu erreichen. Um eine Zeichenfolgendarstellung von Entry
zu erhalten, die mit der gewünschten Ausgabe 1 übereinstimmt, ist nur print entry
oder strrepr = str(entry)
erforderlich. Um die gewünschte Ausgabe 2 zu erhalten, ist ein wenig mehr Arbeit erforderlich, aber es werden einfach alle Einträge summiert, die die gleiche self.time
-Eigenschaft haben, und dann wird das resultierende Diktat angezeigt.
Der letzte Teil des Codes, der nicht behandelt wird, ist das Parsen des Protokolls, um eine Liste von Entry
Objekten zu erstellen. Der Code läuft zeilenweise durch das Protokoll und füllt eine Entry
mit den Informationen. Ich habe das Gefühl, dass das ziemlich einfach ist, aber Sie können gerne Fragen stellen, wenn es keinen Sinn ergibt.
Was haben Sie bisher versucht? Mit welchen Schwierigkeiten sind Sie in Ihrer aktuellen Implementierung konfrontiert? Können Sie bitte einen [mcve] Ihres letzten Codeversuchs bereitstellen? – idjaw
Kannst du die Datei irgendwie lesen? – depperm
zeigt Ihnen die erwartete Ausgabe oder soll das im Datenformat gespiegelt werden? – patrick