Ich Grüße Euch
noisefloor hat geschrieben:
* ìmport Statement gehören an den Anfang, nicht in die Funktion
Ok, also quasi genau wie bei c das #include?
noisefloor hat geschrieben:* Kommentare sollen den Quelltext _zusätzlich_ dokumentieren. Etliche Kommentare beschreiben einfach, was danach so wie so offensichtlich ist und sind damit überflüssig.
Ok, also ein wenig Zuviel des Ganzen. Ist es denn strategisch besser, sich anzugewöhnen längere Kommentare zu machen und kurze Bezeichner oder eher aussagekräftige Bezeichner und wenig Kommentar?
noisefloor hat geschrieben:* Ein nacktes `try... except` fängt stumpf alle Fehler ab, dass will man in der Regel nie. Du solltest im `except`nur die Ausnahme behandeln, die dich wirklich interessiert.
So wie in dem Beispiel von Blackjack?
noisefloor hat geschrieben:* SQL-Statement formatiert man nicht mit den String-Methoden, weil das dann anfällig gegen SQL-Injections ist. Die Python DB API 2.0 macht das über Platzhalter, die dann mit Werten aus einen Tupel befüllt werden und die Werte werden vorher escaped. Wie das genau bei dem von dir gewählten DB-Modul ist, müsstest du in der Doku nachlesen. Für SQLite ist es in der Python Doku beschrieben.
Ich werde wohl erst einmal zu SQLite gehen. Deine Argumente sind für mich einleuchtend. Zudem habe ich gestern festgestellt, dass Calibre auch eine SQLite benutzt. Wenn ich nun ein Programm auf einem Server (SSH) aufrufe, muss ich mir dann Gedanken um Injections machen? Der Serverbetreiber könnte doch eh meine Passwörter einsehen in den Datenbanken, oder?
noisefloor hat geschrieben:
Und ob du wirklich MySQL nehmen möchtest... Auch, wenn man das in vielen Beispielen findet, muss man ja permanent ein Fragezeichen hinter die Zukunft von MySQL machen. IMHO ist PostgreSQL das "bessere" RDBMS - aber das ist ein andere Thema.
Du hast recht, ich kam nur darauf, weil es in den Lehrbüchern steht, die ich habe. Am liebsten sind mir generell GNU und Ähnliche.
noisefloor hat geschrieben:* `basis_menue = - 1; while basis_menue != 0:;`ist so zu umständlich, zumal du nie den Wert von Basismenü änderst. Schreib' einfach `while True:`
Ok, habe mir das mit dem "-1" angewöhnt, weil es so im Buch beschrieben wurde. True ist in diesem Fall alles außer 0?
noisefloor hat geschrieben:* statt Menüs selber zu basteln kann man das `cmd-Modul nutzen. Macht dann Sinn, wenn es mehr als eine handvoll Menüpunkte gibt.
Ok, werde ich mich mit befassen.
noisefloor hat geschrieben:* `exit(0)`ist so nicht der korrekte Weg (und AFAIK auch nicht dokumentiert). Du solltest das exit aus dem sys-Modul nehmen.
Über sys Stand auch im Buch. Ich kam auf das "normale" exit, da man in meiner IDE auch so ein exit angezeigt bekommt und das beim Probieren funktioniert hat.
BlackJack hat geschrieben:Das mit dem einsetzen von Werten in SQL-Anweisungen das noisefloor erwähnte gilt allerdings tatsächlich nur für SQL-Werte. Datenbank- und Tabellennamen gehören da nicht dazu, die muss man dann tatsächlich in die Zeichenkette hinein formatieren. Wobei das oft ein „code smell“ ist wenn man variable SQL-Namen hat. Ein allgemeines Werkzeug zum anlegen von Datenbanken wäre da eine Ausnahme.
Das mit Platzhaltern hatte ich probiert, es ging aber nicht. Also wäre der von mir gewählte Weg der einzig richtige?
Was bedeutet "code smell"?
BlackJack hat geschrieben:Zusätzlich zu der Behandlung von Ausnahmen die man *erwartet* würde ich auch keine Funktion die etwas macht was sich ausserhalb des Hauptprogramms befindet, das Programm komplett abbrechen lassen. Das nimmt dem Aufrufer die Möglichkeit *anders* mit Fehler- oder Ausnahmesituationen umzugehen und die Funktion einfach wieder zu verwenden und/oder zu testen.
Ok, try -> except also nur im def main()?
BlackJack hat geschrieben:Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst und nur dann aufgerufen wird, wenn das Modul als Programm ausgeführt wird, aber *nicht* wenn es nur importiert wird.
Ich habe das ein paar Mal so gemacht, das Ich eine def Main() (naja bei mir def basis()
angelegt hat, da Ich davor schon ein wenig c geübt hatte. Habe das dann aber verworfen, da es mir komisch vorkam, diese Funktion dann mit basis() aufzurufen.
Also, sofern Ich das nicht übersprungen habe, wird in dem Hauptbuch was Ich lese, das mit Main() nicht erwähnt. Im Index des Buches steht auch nichts. Im Buch werden quasi die Funktionen immer direkt ohne extra main() aufgerufen.
BlackJack hat geschrieben:Der `basis_`-Präfix bei den Namen im Hauptprogramm erscheint mir auch überflüssig, weil der keinen Mehrwert an Information bietet.
Bei einer Funktion `serverlogin()` würde man vom Namen her erwarten, das die eine Anmeldung am Server vornimmt und nicht nur die Anmeldedaten vom Benutzer erfragt.
Ingesamt dachte ich mir, dass es einen längeren Code so übersichtlicher macht. War wie gesagt alles wohl etwas zu viel des Ganzen und wird geändert.
BlackJack hat geschrieben:Bei einer Funktion `serverlogin()` würde man vom Namen her erwarten, das die eine Anmeldung am Server vornimmt und nicht nur die Anmeldedaten vom Benutzer erfragt.
Auf den Namen kam ich, wegen der der Codestelle im Buch, dass keine Serververbindung möglich ist. Siehe Code am Ende.
BlackJack hat geschrieben:Der Style Guide for Python Code sagt, das um Zuweisungen bei Schlüsselwortargumenten keine Leerzeichen gesetzt werden.
Ok, damit meinst Du in diesem falle z. B.: "host=server"? Wenn ja, ist das in meinem Buch auch anders (Siehe Code am Ende). Meine IDE hat mir dort aber einen PEP8 Fehler angezeigt und die IDE wollte es zusammenschreiben.
BlackJack hat geschrieben:Datenbank-Cursor habe ich in deutsch noch nie als „Zeiger“ übersetzt gesehen. Zumal die Cursor-Objekte von der DB-API V2 auch nicht wirklich wie Cursor in SQL verwendet werden und selbst wenn das verwendete DBMS SQL-Cursor kennt, diese nicht verwenden müssen.
Ich würde sowieso keine deutschen Namen verwenden. Das bringt schnell Probleme mit der Konvention das Exemplare von Containerdatentypen mit der Mehrzahl des Namens eines Elementes aus dem Container benannt werden. Weil es im deutschen wesentlich mehr Worte gibt, bei denen Einzahl und Mehrzahl sich nicht unterscheiden, während das im englischen fast immer der Fall ist, und diese Unterscheiden fast immer das Mehrzahl-”s” ist
Ok, vollkommen logisch. Ich werde mir versuchen anzugewöhnen, nur noch Englisch zu benutzen.
BlackJack hat geschrieben:Ein `commit()` macht nur bei DML-SQL-Anweisungen Sinn, also bei solchen die Daten in Tabellen betreffen (inklusive Anweisungen die Daten nur abfragen und nicht verändern), aber nicht beim Anlegen von Datenbanken oder Tabellen. Das kann sowieso nicht zurück gerollt werden.
Das commit habe ich ebenfalls in diesem Beispiel aus dem Buch. Siehe Code am ende.
@BlackJack
Danke für den Code. Das ist für mich sehr aufschlussreich. Ich habe nun noch 2 Fragen zu dem Code:
BlackJack hat geschrieben:
from contextlib import closing
from getpass import getpass
Warum das "from" vor dem import. Was ist der Vorteil, als wenn ich nur über import aufrufe?
BlackJack hat geschrieben:if __name__ == '__main__':
was genau macht diese zeile? Es wäre also falsch, main() ohne oben genannte Zeile aufzurufen?
@Sirius3
Ich antworte nur auf einiges an Dich, da ich das meiste von dem, was Du schreibst, schon beantwortet habe. Ich hoffe, Du nimmst es mir nicht böse und liest dort gegebenenfalls mit.
Sirius3 hat geschrieben:Zur Beruhigung: solange man noch lernt, kann man eigentlich nicht die falsche Wahl treffen. Es gibt ja auch nicht die eine Datenbank, die immer passt. Wenn Du mit einem Datenbanksystem anfängst und es kennen lernst und dann merkst, dass etwas nicht geht, dann hast Du viel gelernt: Du kennst die Grenzen und kannst das nächste mal besser abschätzen, ob die Datenbank geeignet ist; Du merkst, wie sehr Dein Code abhängig von einem externen System ist und wie Du das nächste mal solche Abhängigkeiten möglichst an einer Stelle bündelst.
Du hast recht. Wollte eben nur nicht mit SQLite anfangen, weil ich eben wegen dem Lite dachte ...
Sirius3 hat geschrieben:Funktionen sind die Dinger, die man aufrufen kann. Das Wort funktion braucht nicht im Namen vorkommen, oder hast Du irgendeine Funktion aus der Standardbibliothek gefunden, die auf diese Art benannt wurde? Funktionen werden häufig nach Tätigkeiten benannt (weil sie ja auch was machen), sieht man schön an »datenbank_anlegen«
Ich weiß, manchmal habe ich das Problem, das ich es mir viel umständlicher mache, als es sein müsste.
Sirius3 hat geschrieben:Der Name »serverlogin« ist dagegen falsch, da nur Login-Parameter abgefragt werden.
Das habe ich leider auch so aus dem Buch übernommen. Siehe Code am Ende.
Sirius3 hat geschrieben: Leerzeilen in Funktionen sind selten nötig, nur dann, wenn man in sich abgeschlossene Blöcke trennen will, und dann sollte man sich fragen, ob diese Blöcke nicht besser eigene Funktionen wären.
Werde ich mir merken.
@all
Ich Poste hier mal den Originalcode aus dem Buch:
Code: Alles auswählen
# Connector importieren
import sys, mysql.connector
# Verbindung zum Datenbankserver erstellen
try:
connection = mysql.connector.connect \
(host = "localhost", user = "root", passwd = "")
except:
print("Keine Verbindung zum Server")
sys.exit(0)
# Execution-Objekt erzeugen
cursor = connection.cursor()
# Datenbank erzeugen
cursor.execute("CREATE DATABASE IF NOT EXISTS firma")
connection.commit()
# Execution-Objekt schliessen
cursor.close();
# Verbindung schliessen
connection.close()
Noch mal ein Großes danke an Euch
. Ich habe gemerkt, dass es wirklich wichtig ist, auch mit Leuten über seinen Anfängercode zu schreiben. Etliches scheint wohl nicht wie in Büchern zu sein. Ist das nun oftmals eine Optimierung des Codes oder wäre vieles einfach schlicht falsch (trotzdem ausführbar)?
Da ich es furchtbar schwer habe durch lesen zu lernen, sondern eher durchs Machen, ist es vermutlich das Beste, die Codes dann auch immer hier zu Posten um zu lesen, was verbessert werden sollte. Oder macht das zu viel Aufwand, und ich sollte nur bei Problemen schreiben?
Habe schon bei C das Problem, dass z. B. ein Autor schreibt, man soll das benutzen und das andere der schlechtere Weg sein und das andere Buch schreibt, genau das Gegenteil.
Zu Datenbanken:
Sagen wir mal, ich möchte einige Tausend Zitate abrufbar machen. Eventuell über Web (öffentlich ohne Login). Maximal 100 Leute (vermutlich eher selten), die zur gleichen Zeit darauf zugreifen. Reicht da SQLite (später gegebenfalls Postgre)?
Wer in der Wildnis lebt, muss zum Wolf werden, oder als Schaf sterben.
(Syrisches Sprichwort)