Größter Wert aus Spalte ausgeben

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.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

BlackJack hat geschrieben:@Nobuddy: Das wäre eine Funktion die keine Datenstrukturen verwendet, die nicht als Argument herein gekommen sind, ja. Allerdings ist der Name irreführend, denn bei `get_*` erwartet man einen Rückgabewert.
Ok `get_*` ist hier nicht angebracht, evtl. dann 'now_write'.
Oder wie würdest Du diese Funktion benennen?
BlackJack

@Nobuddy: `write_csv()` vielleicht.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

BlackJack hat geschrieben:@Nobuddy: `write_csv()` vielleicht.
Danke, das werde ich so übernehmen!
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

bords0 hat geschrieben:Ungetesteter Versuch mit groupby, unter der Annahme, dass alle Untergruppen einer Gruppe direkt hintereinander kommen:

Code: Alles auswählen

from itertools import groupby, itemgetter

with open(uigruppen_path, 'r') as f:
    reader = csv.reader(f, delimiter="\t")
    table = ((int(l[0]), int(l[2])) for l in reader if l[0] != '---')
    groups = (g for k, g in groupby(table, key=itemgetter(0)))
    result = dict(max(g, key=itemgetter(1)) for g in groups)

print(result)
#oder:
print(sorted(result.items()))
(Gibt deine Lösung auch bei mehrstelligen Zahlen das richtige Ergebnis? Stringsortierung und numerische Sortierung sind ja verschieden.)
So, versuche Deinen Vorschlag umzusetzen.
Möchte folgendes noch dazu erwähnen.
Bei Spalte_1 (hier l[0]), steht bei Werten kleiner 10 eine Null davor.
Beispiel: 1 = 01

Jetzt weiß ich nicht, ob Dein Konstrukt so noch funktioniert?

Ich habe eine Fehlermeldung beim Testen erhalten:
ImportError: cannot import name itemgetter
Ist itemgetter in itertools nicht(mehr) enthalten, bzw. was ich kann ich da machen?

Grüße Nobuddy
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Für die import-Fehlermeldung, habe ich beim Goggeln eine Lösung gefunden

Code: Alles auswählen

from operator import itemgetter
from itertools import groupby
Hoffe, das ist richtig, zumindest kommt diesbezüglich keine Fehlermeldung mehr.

Allerdings funktioniert es noch nicht so, wie ich mir das vorstelle.
Könnte mir vorstellen, daß es mit dem zusammenhängt:
Bei Spalte_1 (hier l[0]), steht bei Werten kleiner 10 eine Null davor.
Beispiel: 1 = 01
Gibt es da Vorschläge von Euch dazu?
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Nobuddy hat geschrieben: Allerdings funktioniert es noch nicht so, wie ich mir das vorstelle.
Bitte detailiertere Fehlermeldung: Welchen Code benutzt, welchen Input, welchen Output erhalten, welchen erwartet, sonstige Schwierigkeiten? :K
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Konnte es selbst lösen! :D


Zuvor sieht der Inhalt der Datei subgroupindex_path so aus:
01 FARBBÄNDER ---
01 FARBBÄNDER-FÜR-KASSEN ---
01 FARBBÄNDER-FÜR-MATRIXDRUCKER ---
02 ADRESS-ETIKETTEN ---
02 BEWERBUNGSMAPPEN ---
02 BRIEFUMSCHLÄGE ---
02 BUCH-ETIKETTEN ---
02 CD/DVD-BESCHRIFTUNGS-SETS ---
18 ATEMSCHUTZ ---
18 BEWEGUNGSMELDER ---
18 BINDEVLIESE ---
18 BLUTDRUCKMESSGERÄTE ---
18 DOKUMENTEN-KASSETTEN ---
18 FAHRRADSCHLÖSSER ---
18 FEUERLÖSCHER&LÖSCHDECKEN ---
20 ADVENTSKRÄNZE&ZUBEHÖR ---
20 ADVENTSTELLER ---
20 BASTELBÜCHER ---
20 BASTELKARTON ---
20 BASTELN-MIT-HOLZ ---
20 DEKORATIONEN ---
20 GESCHENKBÄNDER&SCHLEIFEN ---
20 GESCHENKPAPIER ---
20 GESCHENKPAPIER-ROLLENWARE ---
20 GESCHENKTÜTEN ---
20 GUTSCHEINKARTEN ---
20 KARTEN&UMSCHLÄGE ---
20 LICHTERKETTEN ---
20 MODELLIERMASSE&ZUBEHÖR ---
20 MOTIVLOCHER ---
20 SERVIETTEN&TISCHDECKEN ---
20 STICKER ---
20 TRANSPARENTPAPIERE ---
40 DISPLAYS ---
40 POS-MATERIAL ---
40 REGALWÄNDE&BESTÜCKUNG ---
Nun möchte ich die erste Spalte Gruppieren und der dritten Spalte mit den '---' eine fortlaufende Nummer verpassen.

Der Inhalt der Datei subgroupindex_path sieht so aus, wenn die Daten bearbeitet wurden (Auszug):
01 FARBBÄNDER 1
01 FARBBÄNDER-FÜR-KASSEN 2
01 FARBBÄNDER-FÜR-MATRIXDRUCKER 3
02 ADRESS-ETIKETTEN 1
02 BEWERBUNGSMAPPEN 2
02 BRIEFUMSCHLÄGE 3
02 BUCH-ETIKETTEN 4
02 CD/DVD-BESCHRIFTUNGS-SETS 5
18 ATEMSCHUTZ 1
18 BEWEGUNGSMELDER 2
18 BINDEVLIESE 3
18 BLUTDRUCKMESSGERÄTE 4
18 DOKUMENTEN-KASSETTEN 5
18 FAHRRADSCHLÖSSER 6
18 FEUERLÖSCHER&LÖSCHDECKEN 7
20 ADVENTSKRÄNZE&ZUBEHÖR 1
20 ADVENTSTELLER 2
20 BASTELBÜCHER 3
20 BASTELKARTON 4
20 BASTELN-MIT-HOLZ 5
20 DEKORATIONEN 6
20 GESCHENKBÄNDER&SCHLEIFEN 7
20 GESCHENKPAPIER 8
20 GESCHENKPAPIER-ROLLENWARE 9
20 GESCHENKTÜTEN 10
20 GUTSCHEINKARTEN 11
20 KARTEN&UMSCHLÄGE 12
20 LICHTERKETTEN 13
20 MODELLIERMASSE&ZUBEHÖR 14
20 MOTIVLOCHER 15
20 SERVIETTEN&TISCHDECKEN 16
20 STICKER 17
20 TRANSPARENTPAPIERE 18
40 DISPLAYS 1
40 POS-MATERIAL 2
40 REGALWÄNDE&BESTÜCKUNG 3
Nun kann es passieren, daß Zeilen aus der Datei entfallen und Andere dafür hinzukommen (Beispiel):
20 ADVENTSKRÄNZE&ZUBEHÖR 1
20 ADVENTSTELLER 2
20 BASTELBÜCHER 3
20 BASTELKARTON 4
20 BASTELN-MIT-HOLZ 5
20 DEKORATIONEN 6
20 GESCHENKBÄNDER&SCHLEIFEN 7
20 GESCHENKPAPIER 8
20 GESCHENKPAPIER-ROLLENWARE 9
20 GESCHENKTÜTEN 10
20 GUTSCHEINKARTEN 11
20 NEUEZEILE ---
20 LICHTERKETTEN 13
20 NEUEZEILE ---
20 MOTIVLOCHER 15
20 SERVIETTEN&TISCHDECKEN 16
20 STICKER 17
20 TRANSPARENTPAPIERE 18
40 DISPLAYS 1
40 NEUEZEILE ---
40 REGALWÄNDE&BESTÜCKUNG 3
Diese neuen Zeilen, sollen wenn möglich nicht die alten frei geworden Nummer aus der Gruppe bekommen.
Dies ist mir momentan nicht ganz gelungen, da z.B. bei der letzten Zahl einer Gruppe, der Wert wieder der neuen Zeile vergeben wird.

Mein Konstrukt dazu:

Code: Alles auswählen

###-2-## Basis-Untergruppen-Index mit Untergruppenzähler erstellen
# untergruppenindex.txt

table = {}
vergleich = {}
ergebnis = []
def get_num(filename):
    with codecs.open(filename, 'r') as infile:
        reader = csv.reader(infile, delimiter="\t", quotechar="^")
        for item in reader:
            if item[0] != '---' and item[2] == '---':
                table[item[0]] = item[0]

    basisdaten = []
    with codecs.open(filename, 'r') as infile:
        reader = csv.reader(infile, delimiter="\t", quotechar="^")
        for item in reader:
            if item[2] != '---' and table.get(item[0]):
                zeile = (item[0], item[2])
                basisdaten.append(zeile)

                
    basisdaten = sorted(set(basisdaten))

    x = 1
    p = 0
    for item in basisdaten:
        try:
            if num == '':
                num = item[0]
        except UnboundLocalError:
            num = item[0]
            pass

        if item[0] == num:
            p = item[1]
            wertneu = (num, p)
        else:
            ergebnis.append(wertneu)
            while item[0] != num:
                num = item[0]
                x = int(num)
                p = 0
    try:
        ergebnis.append(wertneu)
    except UnboundLocalError:
        pass

    for items in ergebnis:
        vergleich[items[0]] = items[1]

get_num(subgroupindex_path)


gruppenzaehler = {}
daten = []
try:
    with codecs.open(subgroupindex_path, "r") as infile:
        reader = csv.reader(infile, delimiter="\t", quotechar="^")
        for item in reader:
            try:
                gruppenzaehler[item[0], item[1]] = item[2]
                a = (item[0], item[1], item[2])
                daten.append(a)
            except IndexError:
                pass
except IOError:
    pass

daten = sorted(set(daten))



neuedaten = []
x = 1
p = 1
for item in daten:
    if vergleich != {}:
        w = vergleich.get(item[0], item[2])
    else:
        w = ''
    if w == '' and item[0] != '---' and item[2] == '---':
        # Führende Nullen entfernen
        a = item[0]
        if a != '':
            if a[0] == '0':
                num = '0{}'.format(str(x))
            else:
                num = '{}'.format(str(x))

        if item[0] == num:
            zeile = (item[0], item[1], p)
            neuedaten.append(zeile)
            p = p + 1
        else:
            while item[0] != num:
                num = item[0]
                x = int(num)
                p = 1
                zeile = (item[0], item[1], p)
                neuedaten.append(zeile)
            p = p + 1
    else:
        zeile = (item[0], item[1], item[2])
        neuedaten.append(zeile)

neuedaten = sorted(set(neuedaten))

write_csv(subgroupindex_path, neuedaten)

daten = neuedaten

del neuedaten


###-3-## Neue Datenzeilen  mit Untergruppenzähler aktualisieren
# untergruppenindex.txt
daten = []
neuedaten = []
with codecs.open(subgroupindex_path, "r") as infile:
    reader = csv.reader(infile, delimiter="\t", quotechar="^")

    for item in reader:
        if vergleich.get(item[0]) and item[2] == '---':
            zeile = (item[0], item[1], item[2])
            daten.append(zeile)
        else:
            zeile = (item[0], item[1], item[2])
            neuedaten.append(zeile)

daten = sorted(set(daten))

if vergleich != {}:
    for item in daten:
        if vergleich.get(item[0]):
            get_num(subgroupindex_path)
            p = vergleich.get(item[0], item[2])
            p = int(p) + 1
            zeile = (item[0], item[1], p)
            neuedaten.append(zeile)

        neuedaten = sorted(set(neuedaten))

        try:
            if neuedaten[0] != '':
                write_csv(subgroupindex_path, neuedaten)
        except IndexError:
            pass
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Nobuddy hat geschrieben:Diese neuen Zeilen, sollen wenn möglich nicht die alten frei geworden Nummer aus der Gruppe bekommen.
Dies ist mir momentan nicht ganz gelungen, da z.B. bei der letzten Zahl einer Gruppe, der Wert wieder der neuen Zeile vergeben wird.
Deine Versuche, dich irgendwie um die Verwendung einer echten relationalen Datenbank herumzuwinden in allen Ehren, aber auf Dauer machst du dir damit deutlich mehr Arbeit als wenn du einmalig den Umgang mit Datenbanken erlernst.

Wenn die Nummer auch nach dem Entfernen der Daten noch wichtig ist, dann ist es ein Fehler den Datensatz überhaupt physisch zu löschen. In dem Fall würde man eher ein Flag verwenden, das den Eintrag als aktiv oder inaktiv kennzeichnet.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich denke auch, dass die Zeit langsam mal reif dafür ist. Davon abgesehen sind die Grenzen von CSV irgend wann einfach mal erreicht. Da böten sich wenn schon andere, einfacher strukturierbare Serialisierungsformate an.

Alleine schon, dass auf "magische" Art neue Zeilen hinzukommen können - da werkeln doch im Hintergrund noch die alten Bash-Scripte rum möchte ich wetten. Anstatt auf einer abstrakten Datenbasis zu arbeiten wird da alles noch auf Dateiebene abgehandelt und das vermutlich von zig Scripts. Das führt auf Dauer nur zu Chaos ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Gebt mir noch ein wenig Zeit, das mit der relationalen Datenbank kommt dann auch bestimmt! :wink:
Nobuddy hat geschrieben:Wenn die Nummer auch nach dem Entfernen der Daten noch wichtig ist, dann ist es ein Fehler den Datensatz überhaupt physisch zu löschen. In dem Fall würde man eher ein Flag verwenden, das den Eintrag als aktiv oder inaktiv kennzeichnet.
Das würde mich brennend interessieren, wie funktioniert das?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Nobuddy hat geschrieben: Das würde mich brennend interessieren, wie funktioniert das?
Indem Du einfach eine Datenspalte dazu packst, in der eben zwei Werte enthalgten sein können; der eine steht für aktiv, der andere für inaktiv. Wie Du das abbildest sei Dir überlassen ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten