Liste bearbeiten

Du hast eine Idee für ein Projekt?
Antworten
steveO_O
User
Beiträge: 22
Registriert: Montag 23. März 2020, 20:08

Hallo zusammen,

ich hatte vor drei Wochen irgendwie Lust mal was Sinnvolles zu machen und Python zu lernen. Mein erstes kleines Projekt soll als kleine Hilfe für ein gemeinnütziges Projekt dienen. Und ich möchte es hier kurz vorstellen. Habe mir einiges zusammengegoogelt und damit rumgespielt. Leider noch nicht alles 100% verstanden, was da in meinem Code passiert^^. Naja … bin aber natürlich offen für Verbesserungsvorschläge 😊

Ziel: Liste von Mailadressen erstellen.
Ich habe folgende Liste kopiert
https://wiki.kif.rocks/wiki/Liste_unserer_Fachschaften
und in eine Excel-Tabelle eingefügt, die ich wiederum als .txt abgespeichert habe. Dann habe ich die Liste mit Python „bereinigt“, um ausschließlich die Mailadresse zu haben und wieder eine csv. Draus gemacht.

Coronafreie Grüße
Stefan

PS: Nein, ich plane kein Spam-Projekt 😉
PSS: Die Liste ist noch nicht zu 100% bereiningt. Es fehlen an vereinzelten Stellen noch korrekte @-Zeichen, welche ich per Hand korrigieren muss.

Code: Alles auswählen

with open("D:\Python\Projekt Mailliste Fachschaften\mappe1.txt", "r") as infile, open ('bereinigt.txt', "w") as outfile:
    checkwords = ["ät", "(at)", "( at )", "@"]
    replwords = ["@"]
    for line in infile:
        for check, repl in zip(checkwords, replwords):
            if any(word in line for word in checkwords):
                line = line.replace(check, repl)
                line = line.replace(" ", "")
                line = line.replace("(", "")
                line = line.replace(")", "")
                line = line.replace("punkt", ".")
                line = line.replace("strich", "-")
                outfile.write(line[2:]) #löscht die ersten 2 Zeichen

import csv
with open('bereinigt.txt', 'r') as in_file:
    stripped = (line.strip() for line in in_file)
    lines = (line.split(",") for line in stripped)
    with open('bereinigt.csv', 'w') as out_file:
        writer = csv.writer(out_file)
        writer.writerows(lines)
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mir fehlt jetzt ein bisschen die Frage. Wenn du auf der Suche nach konstruktiver Kritik bist:

- importe gehoeren an den Anfang.
- auf modul-Ebene gehoert kein Code, da stehen nur importe, Funktions-Definitionen und Konstanten. Und ganz am Ende ein Aufruf von einer Funktion, meistens main, und geschuetzt durch einen if __name__ == "__main__"-Guard.
- so eine lange Liste von replaces coded man nicht, man definiert eine Liste von Tupeln und arbeitet die dann durch. Das macht das abaendern der Ersetzungen einfacher.

Code: Alles auswählen

REPLACEMENTS = [
    (" ", ""),
    ("(", ""),
...]

for needle, hammer in REPLACEMENTS:
     line = line.replace(needl, hammer)
- die beiden Schritte gehoeren in Funktionen, und deren Parameter wie Dateinamen nicht hart-codiert, sondern als Argumente uebergeben
- die dateinamen sollten per Kommandozeilen-Argument uebergeben werden.
- die zwischendatei "bereinigt.txt" ist unnoetig, einfach gleich die CSV-Datei erstellen.
- die Bereinigungs-Funktion sollte nichts selbst schreiben, sondern eine Liste der lines zurueck geben.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Freundlicherweise wird ja jede Email-Adresse mit einem e-Mail-Symbol eingeleitet.
Da ist das finden per regulärem Ausdruck ganz einfach.

Code: Alles auswählen

import re
from urllib.requests import urlopen

with urlopen('https://wiki.kif.rocks/wiki/Liste_unserer_Fachschaften') as response:
    text = response.read().decode()

for email in re.findall(u'\U0001f4e7\s*(\S+)\s*(@|\([aä]t\))\s*([^<]*)', text):
    print(f"{email[0]}@{email[2]}")
steveO_O
User
Beiträge: 22
Registriert: Montag 23. März 2020, 20:08

Vielen Dank für deine Rückmeldung!
__deets__ hat geschrieben: Sonntag 29. März 2020, 14:41 Mir fehlt jetzt ein bisschen die Frage. Wenn du auf der Suche nach konstruktiver Kritik bist:
Genau das :-)
__deets__ hat geschrieben: Sonntag 29. März 2020, 14:41 - importe gehoeren an den Anfang.
- auf modul-Ebene gehoert kein Code, da stehen nur importe, Funktions-Definitionen und Konstanten. Und ganz am Ende ein Aufruf von einer Funktion, meistens main, und geschuetzt durch einen if __name__ == "__main__"-Guard.
- so eine lange Liste von replaces coded man nicht, man definiert eine Liste von Tupeln und arbeitet die dann durch. Das macht das abaendern der Ersetzungen einfacher.

...

- die beiden Schritte gehoeren in Funktionen, und deren Parameter wie Dateinamen nicht hart-codiert, sondern als Argumente uebergeben
- die dateinamen sollten per Kommandozeilen-Argument uebergeben werden.
- die zwischendatei "bereinigt.txt" ist unnoetig, einfach gleich die CSV-Datei erstellen.
- die Bereinigungs-Funktion sollte nichts selbst schreiben, sondern eine Liste der lines zurueck geben.
Habe jetzt noch nicht alles verstanden was du da geschrieben hast. Habe das ganze etwas umgeschrieben und es schaut tatsächlich professioneller aus als vorher. Was den Aufbau eines Projekts betrifft werd ich mich nicht aktiv einlesen sondern wenn ich im Netz immer mal wieder auf Projekte stoße genauer drauf achten. Momentan bin ich noch auf Verständnis der Syntax/ Befehle fokussiert :-). Deine Kommentare habe ich aber gespeichert und werde sie mir immer wieder mal durchlesen und schauen ob ich schon verstehe was du meinst.

Code: Alles auswählen

import csv

with open(".\mappe1.txt", "r") as infile, open ('bereinigt.csv', "w") as outfile:
    REPLACEMENTS = [
        ("ät", "@"),
        ("(at)", "@"),
        ("( at )", "@"),
        ("@", "@"),
        (" ", ""),
        ("(", ""),
        (")", ""),
        ("punkt", "."),
        ("strich", "-")
        ]
    for line in infile:
        for seek, destroy in REPLACEMENTS:
            line = line.replace(seek, destroy)
        if "@" in line:
            outfile.write(line[2:])
Sirius3 hat geschrieben: Sonntag 29. März 2020, 15:31 Freundlicherweise wird ja jede Email-Adresse mit einem e-Mail-Symbol eingeleitet.
Da ist das finden per regulärem Ausdruck ganz einfach.
....
Das war mir schon klar, aber dann hätte ich ja längst nicht soviel gelernt ;-)
Danke!
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Diese Ersetzung habe ich nicht wirklich verstanden: ("@", "@"). Das macht keinen Sinn.

Das ".\" in dem einen Dateinamen ist a) überflüssig und b) keine gute Idee weil "m" zufällig *keine* besondere Bedeutung hat, aber das gilt ja nicht für jedes Zeichen nach einem "\".

Bei Textdateien sollte man immer die Kodierung explizit angeben, damit das überall gleich ist.

Auf Modulebene gehört nur Code… wurde ja schon gesagt. Fang damit *jetzt* an. Syntax ist nur ein sehr kleiner Teil. Python hat da relativ wenig von. Konventionen und idiomatische Verwendung der Sprache muss man letztlich auch lernen, und es ist besser gleich von Anfang an darauf zu achten.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
steveO_O
User
Beiträge: 22
Registriert: Montag 23. März 2020, 20:08

__blackjack__ hat geschrieben: Sonntag 29. März 2020, 21:58 Diese Ersetzung habe ich nicht wirklich verstanden: ("@", "@"). Das macht keinen Sinn.
Das hatte ich ursprünglich mal drin, um die Zeilen auszufiltern, die kein @ enthalten. Aber du hast recht, das ist jetzt überflüssig.
__blackjack__ hat geschrieben: Sonntag 29. März 2020, 21:58 Das ".\" in dem einen Dateinamen ist a) überflüssig und b) keine gute Idee weil "m" zufällig *keine* besondere Bedeutung hat, aber das gilt ja nicht für jedes Zeichen nach einem "\".

Bei Textdateien sollte man immer die Kodierung explizit angeben, damit das überall gleich ist.

Auf Modulebene gehört nur Code… wurde ja schon gesagt. Fang damit *jetzt* an. Syntax ist nur ein sehr kleiner Teil. Python hat da relativ wenig von. Konventionen und idiomatische Verwendung der Sprache muss man letztlich auch lernen, und es ist besser gleich von Anfang an darauf zu achten.
Ok
__blackjack__ hat geschrieben: Sonntag 29. März 2020, 21:58 Bei Textdateien sollte man immer die Kodierung explizit angeben, damit das überall gleich ist.
Da verstehe ich gerade nicht was du meinst :-)

Danke für die Rückmeldung!
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@steveO_O: `open()` hat ein `encoding`-Argument, das sollte man immer auf den passenden Wert setzen wenn man eine Textdatei öffnet. Wenn man den Wert selbst in der Hand hat, bietet sich eigentlich immer "UTF-8" an, weil man damit jedes Unicode-Zeichen kodieren kann.

Wenn man dieses Argument nicht übergibt, dann ”rät” Python die bevorzugte Kodierung auf dem System auf dem es gerade läuft. Was zwei Probleme mit sich bringt a) es kann sein das man nicht alle Unicode-Zeichen speichern kann, und b) das das auf einem System zwar funktioniert, wenn man Programm und Daten auf ein anderes System kopiert, es dort dann aber nicht mehr funktioniert.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
steveO_O
User
Beiträge: 22
Registriert: Montag 23. März 2020, 20:08

Jetzt verstanden, Danke!
Antworten