Liste asu Funktion in andere Funktion einbinden

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
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Hallo liebe Forumsgemeinde,
ich möchte eine Liste, welche ich in einer Funktion erzeuge in eine andere Funktion einbinden. Leider ohne Erfolg.
Könnt ihr mir weiterhelfen?

Code: Alles auswählen

# -*- coding: utf-8 -*-
import csv

def ueberschrift_name():
    ueberschrift_spalten = []
    with open("ueberschrift_export.csv", "r", encoding="utf-8") as input:
        entry_address = csv.reader(input, delimiter=";")
        for zeile in entry_address:
            ueberschrift_spalten = zeile


def ueberschrift_import():
    spalte_gesamt = 38 - 1
    zaehler = 0 - 1
    ueberschrift_spalten = ueberschrift_name()

    while zaehler <= spalte_gesamt:
        zaehler = zaehler + 1
        spalte = ueberschrift_spalten[zaehler]
        print(spalte)


print(ueberschrift_name())
print(ueberschrift_import())
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

tz_wuerzburg hat geschrieben: Montag 19. November 2018, 09:59 ich möchte eine Liste, welche ich in einer Funktion erzeuge in eine andere Funktion einbinden. Leider ohne Erfolg.
Die erzeugte Liste solltest du mittels return am Ende der Funktion zurückgeben. Dieser Rückgabewert kann dann in der anderen Funktion verwendet werden.
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Super, vielen Dank!

Code: Alles auswählen

# -*- coding: utf-8 -*-
import csv

def ueberschrift_name():
    with open("ueberschrift_export.csv", "r", encoding="utf-8") as input:
        entry_address = csv.reader(input, delimiter=";")
        for zeile in entry_address:
            ueberschrift_spalten = zeile
            return ueberschrift_spalten

def ueberschrift_import():
    spalte_gesamt = 38 - 1
    zaehler = 0 - 1
    ueberschrift = ueberschrift_name()

    for zaehler in range(zaehler, spalte_gesamt):
        zaehler = zaehler + 1
        spalte = [zaehler, ueberschrift[zaehler]]
        print(spalte)


print(ueberschrift_name())
print(ueberschrift_import())
Kurze Frage noch. Warum bekommen ich am Ende meiner Liste "spalte" ein None geliefert?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Zur Frage: Du gibst den Rückgabewert von ueberschrift_import aus, und der ist eben None.

Eine for-Schleife nur um die Überschrift (also die erste Zeile) zu bekommen ist verwirrend, da normalerweise ein Return in einem for-Block ein Fehler ist.
In der zweiten Funktion ist es quatsch, die Zählvariable zu verändern, da würde man gleich richtig zählen. Über einen Index zu gehen, sollte man vermeiden, weil man auch direkt über die Elemente einer Liste gehen kann. Wenn man dann noch einen Index braucht kann man enumerate benutzen:

Code: Alles auswählen

import csv

def ueberschrift_name():
    with open("ueberschrift_export.csv", "r", encoding="utf-8") as input:
        entry_address = csv.reader(input, delimiter=";")
        return next(entry_address) # first line is header

def ueberschrift_import():
    ueberschrift = ueberschrift_name()
    for spalte in enumerate(ueberschrift):
        print(spalte)

ueberschrift_import()
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Perfekt, Danke. Die Funktion next() kannte ich noch nicht.

Code: Alles auswählen

# -*- coding: utf-8 -*-
import csv
import sqlite3

conn = sqlite3.connect('1_Datenbank.db')
c = conn.cursor()

def ueberschrift_name():
    with open("ueberschrift_export.csv", "r", encoding="utf-8") as input:
        entry_address = csv.reader(input, delimiter=";")
        ueberschrift = next(entry_address)
        return ueberschrift


def ueberschrift_import():
    ueberschrift = ueberschrift_name()
    tabelle_string = ""
    for spalte in enumerate(ueberschrift):
        spalte = list(spalte)

        tabelle_string =  tabelle_string + ", " + str(spalte[1]) + " TEXT"

    t_string_1 = tabelle_string + ")''')"
    t_string_2 = "('''CREATE TABLE test5 (" + t_string_1
    t_string_3 =  t_string_2.replace("(, ", "(")
    return t_string_3

def tabelle_erstellen():
    tabelle_import = ueberschrift_import()
    print(tabelle_import)
    c.execute(tabelle_import)


tabelle_erstellen()


conn.commit()
conn.close()
Habe das ganze jetzt zusammengebaut und erweitert. Nur leider bekomme ich bei der Funktion tabellen_erstellen() die Fehlermeldung "sqlite3.OperationalError: near "(": syntax error".
Verstehen tue ich es nicht. Gebe ich den string "tabelle_import" manuell ein schreib er mir die Tabelle... Warum?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum machst Du aus dem Tuple (Index, Spaltenname) erst eine Liste, um dann doch nur das Element Spaltennamen zu benutzen? Statt `replace` setzt man eine Liste per ', '.join zusammen. Die Variablennamen t_string_123 sind schlecht, weil die Nummern nichts aussagen.

Code: Alles auswählen

def ueberschrift_import():
    ueberschrift = ueberschrift_name()
    return "('''CREATE TABLE test5 ({})''')".format(
        ", ".join(map("{} TEXT".format, ueberschrift))
    )
Hast Du Dir schonmal den erzeugten String angeschaut? Was sollen die '''?

Variablen sollten nicht aus dem nichts kommen, wie `c`, was zudem ein einbuchstabiger Variablennamen ist, der nichts aussagt und außerdem ein Cursor ist, der sowieso nur kurzzeitig existieren sollte. Alles was eine Funktion braucht, sollte sie über ihre Argumente bekommen.
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Ich bekomme es einfach nicht zum laufen...

Code: Alles auswählen

# -*- coding: utf-8 -*-
import csv
import sqlite3

dateiname = "ueberschrift_export.csv"



def ueberschrift_name():
    with open(dateiname, "r", encoding="utf-8") as input:
        entry_address = csv.reader(input, delimiter=";")
        ueberschrift = next(entry_address)
        return ueberschrift


def ueberschrift_import():
    ueberschrift = ueberschrift_name()
    return "('''CREATE TABLE test5 ({})''')".format(
        ", ".join(map("{} TEXT".format, ueberschrift))
    )


def tabelle_erstellen():
    conn = sqlite3.connect('1_Datenbank.db')
    zeiger = conn.cursor()

    tabelle_import = ueberschrift_import()
    print(tabelle_import)
    zeiger.execute(tabelle_import)

    conn.commit()
    conn.close()


tabelle_erstellen()
So sieht mein String aus:
('''CREATE TABLE test5 (NAME1 TEXT, NAME2 TEXT, NAME3 TEXT)''')

Der Fehler lautet wieder:
sqlite3.OperationalError: near "(": syntax error
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tz_wuerzburg: Warum soll der String denn so aussehen? Wo hast Du den Deine SQL-Kenntnisse her? Was in der SQLite-Dokumentation lässt Dich vermuten, dass das *so* aussehen darf?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Guten Morgen,
ich habe die Infos hier her:
https://docs.python.org/3.6/library/sqlite3.html

Code: Alles auswählen

# Create table
c.execute('''CREATE TABLE stocks
             (date text, trans text, symbol text, qty real, price real)''')
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@tz_wuerzburg: und wenn Du die beiden SQL-Befehle vergleichst, was ist der Unterschied?
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tz_wuerzburg: Du musst Dir klar machen was davon Python-Syntax ist und was der tatsächliche Inhalt der Zeichenkette.

Und es könnte auch helfen sich mit SQL und SQLite zu beschäftigen und zum Beispiel dort in der Dokumentation nachlesen wie ein CREATE aufgebaut ist und funktioniert. Das `sqlite3`-Modul in der Standardbibliothek ist ja nur eine Anbindung an SQLite, was an sich ja ein eigenständiges ”Produkt” ist, das man von vielen Programmiersprachen aus verwenden kann, und das eine standardisierte Abfragesprache für relationale Datenbanken verwendet, die auch viele andere Datenbanksysteme verwenden: SQL.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Ein Stück bin ich weiter gekommen, dass anlegen einer neuen Tabelle läuft nun durch.
Jetzt komme ich aber beim füllen der Tabelle kein Stück weiter.

Code: Alles auswählen

# -*- coding: utf-8 -*-
import csv
import sqlite3

dateiname = "aaa.txt"



def ueberschrift_name(dateiname):
    with open(dateiname, "r", encoding="utf-8") as input:
        entry_address = csv.reader(input, delimiter="\t")
        ueberschrift = next(entry_address)
        return ueberschrift


def ueberschrift_import(dateiname):
    t_name = dateiname.split(".")
    t_name_split = t_name[0]
    print(t_name)
    ueberschrift = ueberschrift_name(dateiname)
    return "CREATE TABLE " + t_name_split + "({})".format(", ".join(map("{} TEXT".format, ueberschrift)))


def tabelle_erstellen():
    conn = sqlite3.connect('1_Datenbank.db')
    zeiger = conn.cursor()

    tabelle_import = ueberschrift_import(dateiname)
    print(tabelle_import)
    zeiger.execute(tabelle_import)

    conn.commit()
    conn.close()


def daten_import(dateiname):
    conn = sqlite3.connect('1_Datenbank.db')
    zeiger = conn.cursor()
    with open(dateiname, "r", encoding="utf-8") as input:
        entry_address = csv.reader(input, delimiter="\t")
        ueberschrift = next(entry_address)
        ueberschrift_l = len(ueberschrift)
        ueberschrift = list("?" * ueberschrift_l)
        t_name = dateiname.split(".")
        t_name_split = t_name[0]

        insert_string = "INSERT INTO " + t_name_split + " VALUES ""({})".format(",".join(map("{}".format, ueberschrift))) + ", daten"

        for zeile in entry_address:
            daten = [tuple(zeile)]
            zeiger.executemany(insert_string)

    conn.commit()
    conn.close()


tabelle_erstellen()
daten_import(dateiname)
Im Endeffekt ein ähnliches Problem wie beim erstellen der Tabellen. Gebe ich einen String weiter kommt ein Fehler, wird der String manuell eingegeben
wird die Tabelle gefüllt.
Der Fehler lautet:
TypeError: function takes exactly 2 arguments (1 given)

Vielen Dank Euch!
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Hast Du Dir das INSERT-SQL-Statement angeschaut? Woher soll SQLite wissen, was Du mit `daten` meinst? Das muß ein Parameter zu execute sein. `executemany` macht hier keinen Sinn, wenn Du ihm eine Liste mit exakt einem Element übergibst.
"{}".format macht keinen Sinn, weil das das selbe ist wie `str`, was bei `ueberschrift` aber überflüssig ist, weil es sich schon um Strings handelt.

`tabelle_erstellen` bekommt `dateiname` aus dem nichts, das sollte auch in Parameter sein. Du prüfst nicht, ob die Tabelle in `daten_import` überhaupt zu den importierten Daten passt. Das ist eine potentielle Fehlerquelle. Das solltest Du prüfen. Generell halte ich wenig, Tabellen dynamisch aus csv-Dateien zu erzeugen. Die Tabelle (samt Namen) sollte vorgegeben sein, und die Inputdaten dagegen validiert werden.
Antworten