Anfänger Frage zum Vergleich von zwei texten

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.
Antworten
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

Hi, ich bin neu hier im Forum und freue mich zu lernen und neue Bekanntschaften zu machen.
Bitte nicht so hart zu mir sein.

Mein Problem. Ich möchte den Text in zwei M3U Dateien mit einander vergleichen.
Ich lasse den Text1 von einer URL, in lines lesen.
Und den Text1 von einer M3U-Datei lokal auch in lines einlesen. Nun möchte ich diese mit einander Vergleichen. Da sich aber immer wieder etwas zwischen den Zeilen ändern kann. Weiß ich nicht genau wie ich das bewerkstelligen kann. Mein bisheriger Versuch. Wie kann ich jetzt vergleichen?

Code: Alles auswählen

file = open(m3u_path,"r")
req = urllib2.Request(url)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
response = urllib2.urlopen(req)
test1 = response.readlines()
test2 = file.readlines()
file.close

if test1 == test2:
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LRK: Als allererstes: Installiere ein aktuelles Python 3. Python 2 ist am Ende seiner Lebenszeit angekommen, damit will man keine neuen Programme starten: https://pythonclock.org/

Dateien die man öffnet, sollte man auch wieder schliessen. Du musst `close()` auch *aufrufen*. Das passiert nicht automatisch wenn man die Methode ermittelt, sondern man muss die dann auch explizit aufrufen in dem man Klammern dahinter schreibt.

Besser wäre es aber die ``with``-Anweisung zu verwenden.

Wenn man Textdateien öffnet, sollte man immer eine explizite Kodierung angeben.

Man sollte Namen nicht abkürzen, also nicht `req` schreiben wenn man `request` meint. `test1` und `test2` sind keine guten Namen. Ein Name sollte dem Leser vermitteln was der Wert dahinter im Kontext des Programms bedeutet. Es handelt sich aber nicht um Tests.

Das lesen der beiden Quellen ist auch eigenartig vermischt.

Wie man die beiden Listen vergleicht hast Du da ja selbst schon hingeschrieben. Der ``if``-Zweig wird ausgeführt, wenn beide Listen den gleichen Inhalt haben. Wo ist also das Problem‽

Oder suchst Du eher so etwas wie `difflib` aus der Standardbibliothek?
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

Hi, danke.

Werde mich mit Python 3 auseinander setzen.

Ja das mit der Klammer hab ich total Übersehen.

Mit "with" werde es noch abändern. Danke

Wie kann ich das verstehen bzgl. Codierung?

Wegen lesen, vermischt. Meinst du weil ich zuerst die Datei öffnen und anschließend die url?

Das mit dem "If Zweig" , dafür müssen die Listen ja komplett übereinstimmen. Ich hatte mich auch schon an 'difflib' versucht aber habe es nicht verstanden.

Meine Denkweise ist so..
Ich lese beide Listen in lines und möchte anschließend jede Zeile der url mit den Zeilen der datei vergleichen. Leider sind es ca. 1000 Zeilen.
Quasi jedes einzeln vergleichen.

Ich hoffe .an kann verstehen was ich möchte.

PS. Scheinst sehr angesehen zu sein hier im Forum, von dir kann man viel lernen. Danke im vorraus.
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LRK: Genau das meinte ich mit vermischen. Du öffnest erst beide ”Dateien”, liest dann beide, und schliesst dann beide – äh nee – nur eine. Statt erst die eine Quelle und dann die andere zu behandeln. Wenn man das mal etwas anders organisieren möchte, also zum Beispiel in Funktionen heraus ziehen, dann kann man nicht einfach den Block an zusammengehörenden Code heraus ziehen, sondern muss sich die Zeilen aus dem Code heraus picken die zusammen gehören.

So wirklich klar ist mir nicht was Du eigentlich willst. Du willst vergleichen. Aber was Du exakt vergleichen willst, und wie das Ergebnis aussehen soll, ist mir nicht klar. Vielleicht möchtest Du Dir auch mal den `set()`-Datentyp und dessen Operationen anschauen‽

Bei M3U-Dateien sollte man ausserdem noch beachten, dass nicht jede Zeile ein Dateiname/Pfad sein muss, da können auch noch zusätzliche Infos in ``#EXTINF``-Zeilen vorhanden sein.

Bezüglich der Kodierung muss man noch sagen, dass es da keine feste gibt, also wie bei ganz normalen Textdateien muss man die Kodierung wissen. Die ist weder festgelegt, noch als Information in der Datei gespeichert.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
from urllib.request import Request, urlopen

M3U_ENCODING = 'cp1252'
M3U_PATH = '/path/to/playlist.m3u'
URL = 'http://example.com/playlist.m3u'


def main():
    with open(M3U_PATH, 'r', encoding=M3U_ENCODING) as file:
        local_lines = list(file)
    
    request = Request(URL)
    request.add_header(
        'User-Agent',
        'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3)'
        ' Gecko/2008092417 Firefox/3.0.3'
    )
    with urlopen(request) as response:
        remote_lines = [line.decode(M3U_ENCODING) for line in response]
    

if __name__ == '__main__':
    main()
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

Ö_Ö
Wow damit hab ich nicht gerechnet, vielen dank. Sieht auf den ersten Blick viel komplizierter und größer aus als mein Code. Aber ich erkenne die Bausteine wieder. :D

Ja ich gebe zu, mein Code war nicht gerade ordentlich organisiert. Werde es in Zukunft versuchen besser zu machen. Zu dem schließen, ich vermute Mal das ich "respons" hätte auch schließen müssen?

Mein Vorhaben besteht eigentlich nur darin zu schauen ob sich die M3U(online) verändert hat im Vergleich zu der lokalen M3U. Quasi ob ich meine Lokale Datei Aktualisieren muss.
Hat sich die M3U(Online) verändert?
Wenn ja dann Aktualisieren.
Wenn nein dann nicht.

Werde mir den Set() Datentyp auch noch anschauen.

Da ``#EXTINF``-Zeilen angesprochen wurden, ja solche sind bei mir auch vorhanden.

Werde Mal schauen was mir Google so ausspuckt bezüglich Codierung.

Ein einem Weiteren Schritt möchte ich der M3U(lokal) Logos hinzufügen.

In etwas so...

Aus...
#EXTINF:-1 tvg-name="MeinKanal" group-title="DE",MeinKanal
http://xyz/MeinKanal.ts
Soll...
#EXTINF:-1 tvg-name="MeinKanal" tvg-logo = "MeinKanal.png" group-title="DE",MeinKanal
http://xyz/MeinKanal.ts

Stelle mir das in etwa so vor..
Dateien aus Ordner mit Logos, im "MeinKanal.png" Format, in eine Liste einlesen. (soweit bin ich Aktuell)

sieht dann so aus...
MeinKanal.png
MeinKanal2.png
MeinKanal3.png
Nun möchte ich das in meiner Lokalen M3U nach dem ungefährem namen des Logos gesucht wird.
Ich stelle mir das ungefähr so vor.
Suche (tvg-name=("MeinKanal")) in M3U
wenn gefunden dann (tvg-name="MeinKanal" tvg-logo = "MeinKanal.png") schreiben.
Nächste Zeile aus Logo Liste suchen.


Ich wollte nur nicht alles auf einmal Fragen. habe mir gedacht das ist sonst zu viel und ich versuche es erstmal selbst.
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LRK: Ja, das `Response`-Objekt hat auch eine `close()`-Methode beziehungsweise ist auch ein Kontextmanager den man mit ``with`` verwenden kann. Das habe ich ja gemacht.

Okay, Du hast also nicht nur ``#EXTINF``-Zeilen wie sie das gute alte Winamp versteht, sondern offenbar das Format mit Attributlisten das in RFC8216 beschrieben wird. Das ist es allerdings auch nicht, denn die Attributnamen in Deinem Beispiel verstossen dagegen (Kleinbuchstaben) und ``#EXTINF`` hat dort keine zusätzlichen Attribute. Wenn ich nach den Attributnamen suche, lande ich zum Beispiel hier: https://ss-iptv.com/en/users/documents/m3u

Zumindest sind sich beide Spezifikationen einig, das die Kodierung UTF-8 ist.

Für die erste Aufgabe ist also erst einmal die Frage was denn ”gleich” oder ”verändert” bedeutet. Reicht es die URIs herauszufiltern und zu vergleichen ob die in beiden Playlisten gleich sind? Oder sind auch die Metadaten in den ``#EXTINF``-Zeilen interessant? Also beispielsweise wenn die URI gleich geblieben ist, aber sich der Name in der ``#EXTINF`` geändert hat.

Bei der zweiten Aufgabe machst Du es IMHO falsch herum. Statt zu testen ob ein Dateiname von einem Logo zu einem `tvg-name`-Attribut passt, würde ich eher die `tvg-name`-Attribute mit den vorhandenen Dateinamen für Logos abgleichen.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

Das mit der Codierung ist immer noch bisl neu für mich. Sry. Wenn ich das richtig verstanden habe, ist mit Codierung der komplette Aufbau und die damit enthaltenen Bedingungen gemeint.

Ja im Prinzip würde es reichen, die URIs zu vergleichen. Möchte schließlich nur wissen ob sich etwas geändert hat. Um sie geg.neu zu laden.

Was die zweite Aufgabe betrifft. Ich teste ob ein Dateiname von einem Logo zu einem `tvg-name`-Attribut passt, weil die M3U sich ja hin und wieder ändert und damit auch die `tvg-name`-Attribute.
Es würde auch umgekehrt funktionieren.
Allerdings sind manche `tvg-name`-Attribute Nähe zu identisch.

Z.b.
tvg-name="Mein Kanal (1)"
Und
tvg-name="Mein Kanal (2)"

Aber beide sollen das gleiche Logo erhalten.
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LRK: Ein wichtiger Punkt beim Programmieren ist das aufteilen von Problemen in kleinere Teilprobleme, die man dann entweder wieder in Teilprobleme zerlegen, oder mit einer Funktion in ein paar Zeilen Code lösen kann. Hier hast Du ja jetzt auf jeden Fall schon mal zwei Teilprobleme die unabhängig voneinander sind, und die man in getrennten Funktionen lösen und testen kann.

Beim Vergleichen könnte man also die URIs rausfiltern, sortieren, und dann einfach die sortierten Ergebnisse vergleichen. Laut Spezifikation (RFC) gibt es drei Sorten von Zeilen: Leerzeilen, solche die mit ``#`` anfangen, und URIs. Die URIs zu filtern ist also kein grosses Problem: Alles was keine Leerzeile ist und nicht mit ``#`` anfängt.

Beim zweiten Problem ist die Frage nach einer Funktion die einen ”Abstand” zwischen zwei Zeichenketten berechnet und welcher ”Abstand” klein genug ist, damit ein Logo-Name auf einen `tvg-name`-Wert passt. Bei Zeichenketten und ”Abstand” ist wahrscheinlich der Klassiker „Levenshtein Distance“ – ist die Frage ob der hier zum Problem passt oder ob es eine bessere Abstandsfunktion gibt.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

Was das Sortieren und vergleichen betrifft habe ich das gefunden
viewtopic.php?t=40207
Aber ich werde aus dem Modul "itemgetter"
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LRK: Irgendwie schein der Satz mittendrin aufzuhören. :-) Ich sehe nicht so recht was `itemgetter()` mit dem vorliegenden Problem zu tun hat.

Oh, und für das sortieren stellt sich noch die Frage ob gleiche URIs aber in anderer Reihenfolge eine Änderung darstellen oder nicht.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

LRK hat geschrieben: Mittwoch 19. Juni 2019, 18:12 Was das Sortieren und vergleichen betrifft habe ich das gefunden
viewtopic.php?t=40207
Aber ich werde aus dem Modul "`itemgetter()`"
nicht schlau.

Sry für die Unvollständigkeit wurde abgehalten.

Habe nach einer Möglichkeit gesucht die Uris zu sortieren. Dabei bin ich auf den Post gestoßen.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

@__blackjack__
Kennen Sie evtl. ein gutes Tutorial für Anfänger zu dem Sie mir nen Link geben könnten?

Für einen Vergleich weiß ich nicht ob es eine Veränderung darstellt.

Stelle mir das so vor mit dem Vergleich.

Uris aus der Online M3U filtern. (Dann habe ich eine Liste mit Uris von der Online M3U)
Uris aus der Lokalen M3U filtern. (Liste mit Uris Lokal)
Wenn Zeile "startwith" http.. dann write in Liste.txt

Beide Listen Zeile für Zeile vergleichen.
Find Zeile1 (Online Uri Liste) in "Liste lokal Uris"
Find Zeile2 (Online Uri Liste) in "Liste lokal Uris"
...mit einer "for Schleife". Wenn nicht gefunden dann...nicht gleich.

Bin fast nur am Android Handy und kann auch nur am Handy Testen. :)
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LRK: In der Python-Dokumentation gibt es Tutorial das man IMHO mal durchgearbeitet haben sollte.

Was bei dem Vergleich eine Veränderung darstellt oder nicht ist etwas was der Programmierer wissen/festlegen muss. Die Frage ist ob die gleichen URIs, aber in einer anderen Reihenfolge eine Änderung darstellen sollen und man die neue Reihenfolge übernehmen will, oder ob das keine Änderung darstellen soll und man die alte Playliste behalten will. Das kann man so oder so entscheiden und muss dann entsprechende Schritte (nicht) unternehmen beim Vergleich.

Listen Zeile für Zeile vergleichen, oder allgemeiner Element für Element, ob die beiden Listen die gleichen Elemente enthalten, geht einfach mit ``liste_a == liste_b`` – da braucht man keine Schleife für.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

Vielen Dank, werde die Python-Dokumentation suchen und durcharbeiten. ;)

Also die Reihenfolge der Uris sollte keine Veränderung darstellt, wichtig ist nur ob alle Uris vorhanden sind.

Dann war das vergleichen in meinem ersten Post oben wenigstens richtig. :lol:
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LRK: Wenn eine veränderte Reihenfolge keine Veränderung darstellen soll, dann muss man beide URI-Listen sortieren vor dem Vergleichen, denn sonst würde eine Veränderung in der Reihenfolge beim Vergleich der Listen ja `False` ergeben.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

Stimmt, aber wie oder besser nach was kann ich die Listen sortieren lassen, also nach welchem Anhaltspunkt?

Evtl. Nach dem Ende der Uris? Endwith?
Http.....\12.ts
Http.....\234.ts
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LRK: Einfach sortieren, nach keinem speziellen Anhaltspunkt. Verglichen wird ja danach auch nicht nur ein bestimmter Teil pro URI.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
LRK
User
Beiträge: 38
Registriert: Sonntag 16. Juni 2019, 21:00

Hi, ich lasse meine beiden M3U vergleichen und wenn ein Unterschied besteht lasse ich die die lokale M3U mit der Online M3U Überschreiben.

Würde sagen das jetzt alles so funktioniert wie ich es wollte. Vielen Dank nochmals.

Würde jetzt gerne daran arbeiten die Logos in die M3U zu bekommen. Hat jemand eine Idee wie ich das anstellen kann? Ich habe eine Liste (txt-Datei) in der alle Logonamen stehen, jedes Logo hat eine eigene Zeile. Würde gerne die Lokale M3U nach jeder Logo Zeile durchsuchen lassen, und mir anschließend den Text der Zeile ausgeben lassen, das ich ihn bearbeiten kann.

Oder

Nach dem "tvg-name="Mein Kanal" in meinen Lagos suchen lassen. Natürlich nur nach "Mein Kanal" und dann die Zeile bearbeiten.

Bin für andere Ideen natürlich offen.
Antworten