Kleine Auswertung

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
Beggabua
User
Beiträge: 2
Registriert: Sonntag 4. August 2024, 11:04

Hallo Zusammen,

ich habe erst vor kurzem mit Python begonnen und komme leider nicht mehr weiter.
Ich habe ein scrip erstellt das eine .csv einliest und sortiert. Das Funktionier auch soweit. Leider bekomme ich die Ausgabe als .pdf nicht so hin wie ich es gerne hätte.
Es sind vier Vereine die nach Verein und das Einzelergebniss absteigend sortiert werden. Nach den besten 8 im Verein soll eine Zwischensumme und wenn es mehr als 8 Teilnehmer im Verein sind eine Endsumme. Leider bekomme ich bei jedem Verein die selben Summen.
Auch bei den Logos hätte ich noch gerne etwas Abstand zum Text.
Hier mal der bisherige Code:

import pandas as pa
from datetime import datetime
from tkinter import filedialog
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.platypus import Image
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, PageBreak, Image

# Laden der csv Datei
file_path = filedialog.askopenfilename(title='Bitte die Datei auswählen')
df = pa.read_csv(file_path)

# Sortieren der Daten
# Daten nach Gesamt absteigend sortieren
gesamt = df.sort_values(by='Gesamt', ascending=False)

# Daten nach Teiler sortieren
teiler = df.sort_values(by=['Teiler'])

# Daten nach Verein gruppieren
gp_verein = df.groupby('Verein')

# Daten im Verein absteigend sortieren
so_verein = df.sort_values(by=['Verein', 'Gesamt'], ascending=[True, False])


# Ausgabe als PDF
# Ausgabe Gesamtliste
# Erstelle ein PDF-Dokument
pdf_filename = "ergebnisse.pdf"
doc = SimpleDocTemplate(pdf_filename, pagesize=A4)

# Elemente für das Dokument
elementgl = []

# Aktuelles Datum
heute = datetime.today().strftime('%d.%m.%Y')

# Stile für die Überschriften
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='CenteredHeading', parent=styles['Heading1'], alignment=TA_CENTER))

# Überschrift hinzufügen
heading = Paragraph(f"<b>Ergebnisse 4-Vereine-Pokal in xxx am {heute}</b>", styles['CenteredHeading'])
elementgl.append(heading)

# Pfade zu den Logo-Dateien
logo1_path = "Verein 1.png"
logo2_path = "Verein 2.png"
logo3_path = "Verein 3.png"
logo4_path = "Verein 4.png"

# Erstelle Image-Objekte für die Logos
logo1 = Image(logo1_path, width=75, height=75)
logo2 = Image(logo2_path, width=75, height=75)
logo3 = Image(logo3_path, width=75, height=75)
logo4 = Image(logo4_path, width=75, height=75)

# Erstelle eine Liste mit den Logos
logos = [logo1, logo2, logo3, logo4]

# Daten für die Tabelle mit zusätzlicher Spalte für Rangfolge
gesamttabelle = [['Rang', 'Name', 'Verein', 'S1', 'S2', 'S3', 'S4', 'Gesamt']]

for rank, row in enumerate(gesamt.itertuples(), start=1):
gesamttabelle.append([rank, row.Name, row.Verein, row.S1, row.S2, row.S3, row.S4, row.Gesamt])

# Erstelle eine Tabelle mit einer Zeile und füge die Logos hinzu
table_logos = Table([[logo1, logo2, logo3, logo4]], colWidths=75, rowHeights=75)

# Setze den Abstand zwischen den Logos
table_logos.setStyle(TableStyle([('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('LEFTPADDING', (0, 0), (-1, -1), 35)]))

# Füge die Tabelle mit den Logos zum Dokument hinzu
elementgl.append(table_logos)

# Tabellenstruktur
table_gesamt = Table(gesamttabelle)
table_gesamt.setStyle(TableStyle([('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('INNERGRID', (0, 0), (-1, -1,), 0.25, colors.black),
('BOX', (0, 0), (-1, -1), 0.5, colors.black)]))

# Fügt die Tabelle zum Dokument hinzu
elementsg = [table_gesamt]
doc.build([table_logos, heading, table_gesamt])


# Ausgabe Teiler
# Erstelle ein PDF-Dokument
pdf_filename = "teilerliste.pdf"
doc = SimpleDocTemplate(pdf_filename, pagesize=A4)

# Daten für die Tabelle mit zusätzlicher Spalte für Rangfolge
teilertabelle = [['Rang', 'Name', 'Verein', 'Teiler']]

for rank, row in enumerate(teiler.itertuples(), start=1):
teilertabelle.append([rank, row.Name, row.Verein, row.Teiler])

# Tabellenstruktur
table_teiler = Table(teilertabelle)
table_teiler.setStyle(TableStyle([('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('INNERGRID', (0, 0), (-1, -1,), 0.25, colors.black),
('BOX', (0, 0), (-1, -1), 0.5, colors.black)]))

# Fügt die Tabelle zum Dokument hinzu
elementst = [table_teiler]
doc.build(elementst)





# Ausgabe Vereine
# Erstelle ein PDF-Dokument
pdf_filename = "vereinsliste.pdf"
doc = SimpleDocTemplate(pdf_filename, pagesize=A4)

# Elemente für das Dokument
elementsv = []

# Aktuelles Datum
heute = datetime.today().strftime('%d.%m.%Y')

# Stile für die Überschriften
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='CenteredHeading', parent=styles['Heading1'], alignment=TA_CENTER))

# Überschrift hinzufügen
heading = Paragraph(f"<b>Ergebnisse 4-Vereine-Pokal in xxx am {heute}</b>", styles['CenteredHeading'])
elementsv.append(heading)

# Tabellen für jeden Verein erstellen und Seitenumbrüche hinzufügen
for verein, group in gp_verein:
# Überschrift hinzufügen
heading = Paragraph(f"<b>{verein}</b>", styles['CenteredHeading'])
elementsv.append(heading)

# Logo hinzufügen
logo_path = f'{verein}.png'
logo = Image(logo_path, width=50, height=50)
elementsv.append(logo)

# Tabelle erstellen
vereinstabelle = [['Rang', 'Name', 'S1', 'S2', 'S3', 'S4', 'Gesamt', 'Teiler']]
for verein, group in gp_verein:
group = group.sort_values(by='Gesamt', ascending=False)
for rank, row in enumerate(group.itertuples(), start=1):
vereinstabelle.append([rank, row.Name, row.S1, row.S2, row.S3, row.S4, row.Gesamt, row.Teiler])

# Berechne die Zwischensumme nach 8 Teilnehmern
if rank == 8 and len(so_verein) >= 8:
zwischensumme = so_verein['Gesamt'].iloc[:8].sum()
vereinstabelle.append(['', 'Zwischensumme', '', '', '', '', zwischensumme, ''])

# Berechne die Endsumme für alle Teilnehmer
endsumme = sum(row.Gesamt for row in group.itertuples())
vereinstabelle.append(['', 'Endsumme', '', '', '', '', endsumme, ''])

table_verein = Table(vereinstabelle)
table_verein.setStyle(TableStyle([('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('INNERGRID', (0, 0), (-1, -1,), 0.25, colors.black),
('BOX', (0, 0), (-1, -1), 0.5, colors.black)]))

elementsv.append(table_verein)
elementsv.append(PageBreak())

# Erstelle das PDF-Dokument
doc.build(elementsv)


Schon mal danke für die Hilfe.
Sven_TKLOOP
User
Beiträge: 10
Registriert: Freitag 16. August 2024, 14:10

Hi,

In deinem Code wird die Berechnung außerhalb der Schleife zur Generierung der Tabellen gemacht und nicht richtig gruppiert / sortiert. Daher auch die falschen Berechnungen.

Code: Alles auswählen

if rank == 8
funktioniert nicht da 'rank' außerhalb der Schleife zur Generierung der Tabelle nicht richtig gesetzt ist.

Code: Alles auswählen

# Berechne die Zwischensumme nach 8 Teilnehmern
if rank == 8 and len(so_verein) >= 8:
    zwischensumme = so_verein['Gesamt'].iloc[:8].sum()
    vereinstabelle.append(['', 'Zwischensumme', '', '', '', '', zwischensumme, ''])

# Berechne die Endsumme für alle Teilnehmer
endsumme = sum(row.Gesamt for row in group.itertuples())
vereinstabelle.append(['', 'Endsumme', '', '', '', '', endsumme, ''])
Wenn du die Berechnung in die Schleife integrierst sollte es funktionieren:

Code: Alles auswählen

# Berechnung der Zwischensumme und Endsumme innerhalb der Schleife
for verein, group in gp_verein:
    group_sorted = group.sort_values(by='Gesamt', ascending=False)
    
    for rank, row in enumerate(group_sorted.itertuples(), start=1):
        vereinstabelle.append([rank, row.Name, row.S1, row.S2, row.S3, row.S4, row.Gesamt, row.Teiler])
    
    if len(group_sorted) > 8:
        zwischensumme = group_sorted['Gesamt'].iloc[:8].sum()
        vereinstabelle.append(['', 'Zwischensumme', '', '', '', '', zwischensumme, ''])

    endsumme = group_sorted['Gesamt'].sum()
    vereinstabelle.append(['', 'Endsumme', '', '', '', '', endsumme, ''])
Ebenfalls ist dein Padding-Wert von 35 wahrscheinlich etwas zu gering, um den entsprechenden Abstand zu geben.
Das könntest du auf ähnliche Art und Weise wie hier anpassen:

Code: Alles auswählen

table_logos.setStyle(TableStyle([
    ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ('LEFTPADDING', (0, 0), (-1, -1), 20),
    ('RIGHTPADDING', (0, 0), (-1, -1), 20),
    ('TOPPADDING', (0, 0), (-1, -1), 10),
    ('BOTTOMPADDING', (0, 0), (-1, -1), 10)
]))
Was deine Tabellen angeht sieht es so aus als wenn die Tabellen vielleicht mehrmals erstellt werden wegen doppelten schleifen und redundanten code

Code: Alles auswählen

for verein, group in gp_verein:
    group_sorted = group.sort_values(by='Gesamt', ascending=False)
    vereinstabelle = [['Rang', 'Name', 'S1', 'S2', 'S3', 'S4', 'Gesamt', 'Teiler']]
    
    for rank, row in enumerate(group_sorted.itertuples(), start=1):
        vereinstabelle.append([rank, row.Name, row.S1, row.S2, row.S3, row.S4, row.Gesamt, row.Teiler])
    
    if len(group_sorted) > 8:
        zwischensumme = group_sorted['Gesamt'].iloc[:8].sum()
        vereinstabelle.append(['', 'Zwischensumme', '', '', '', '', zwischensumme, ''])

    endsumme = group_sorted['Gesamt'].sum()
    vereinstabelle.append(['', 'Endsumme', '', '', '', '', endsumme, ''])
Ich hoffe damit kannst du weiterarbeiten.
Beggabua
User
Beiträge: 2
Registriert: Sonntag 4. August 2024, 11:04

Danke für die Hilfe. Jetzt läuft das Programm wie gewünscht.
Antworten