@Luca: Den Sternchenimport hast Du ja schon selbst angemerkt.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Namen von Konstanten schreibt man KOMPLETT_GROSS.
Wenn man das Hauptprogramm in eine Funktion steckt, fällt auf das `gen()` auf Sachen zugreift die keine Konstanten sind aber auch nicht als Argument übergeben werden. Funktionen und Methoden sollten aber alles was sie ausser Konstanten benötigen als Argument(e) übergeben bekommen. Da braucht man dann entweder Closures oder objektoerientierte Programmierung.
Namen sollten dem Leser verraten was der Wert dahinter bedeutet. Die sollten also sorgfältig gewählt werden und nicht nur aus einem Buchstaben oder kryptischen Abkürzungen bestehen, und auch nicht nummeriert sein.
`a` und `l` sollten `anzahl` und `laenge` heissen. Und das was jetzt bereits `anzahl` und `laenge` heisst, sind gar nicht diese Werte sondern Eingabeelemente für diese Werte.
Das `a` dann noch einmal für etwas anderes verwendet wird in der gleichen Funktion ist verwirrend. Wobei der Wert davon dann ja gar nicht verwendet wird. Für solche Fälle ist es Konvention `_` als Namen zu verwenden.
Man muss nicht jedes Zwischenergebnis an einen Namen binden. `x` bringt da nicht wirklich etwas.
Zeichenketten durch immer wieder ”addieren” eines weiteren Teils aufzubauen ist ineffizient weil Zeichenketten nicht veränderbar sind. Idiomatischerweise sammelt man Teile in einer Liste und setzt die dann am Ende mit `join()` zusammen. Beziehungsweise kann man statt einer Liste hier auch einen Generatorausdruck verwenden.
Code und Daten sollte man nicht wiederholen. Das macht Änderungen nur unnötig aufwändig und fehleranfällig. Die 50 steht beispielsweise einmal im Vergleich und einmal in der Fehlerausgabe. Wenn man diese grenze mal ändern möchte, muss man das an zwei Stellen anpassen. Wenn man den Wert als Konstante definiert, muss man ihn nur an dieser einen Stelle ändern.
Das ist nicht wirklich ein `grid()`-Layout wenn man nur eine Spalte verwendet.
Das `className` nicht der richtige Weg ist um den Fenstertitel zu setzen hätte man vielleicht schon an dem Hack erkennen können den man da machen muss damit der erste Buchstabe nicht als Kleinbuchstabe angezeigt wird.
Code: Alles auswählen
#!/usr/bin/env python3
import string
import tkinter as tk
from functools import partial
from random import choice
LETTERS = string.ascii_letters + string.digits + '?!'
MAX_PASSWORD_LENGTH = 50
def generate_passwords(output, anzahl_entry, laenge_entry):
output.delete(1.0, tk.END)
anzahl = int(anzahl_entry.get())
laenge = int(laenge_entry.get())
if laenge > MAX_PASSWORD_LENGTH:
output.insert(
tk.END,
f'Das Passwort darf maximal {MAX_PASSWORD_LENGTH} Zeichen lang'
f' sein!'
)
else:
for _ in range(anzahl):
output.insert(
tk.END, ''.join(choice(LETTERS) for _ in range(laenge)) + '\n'
)
def main():
root = tk.Tk()
root.title('Passwort-Generator')
tk.Label(root, text='Anzahl der Passwörter: ').pack(anchor=tk.W)
anzahl_entry = tk.Entry(root)
anzahl_entry.pack(anchor=tk.W)
tk.Label(root, text='Länge der Passwörter: ').pack(anchor=tk.W)
laenge_entry = tk.Entry(root)
laenge_entry.pack(anchor=tk.W)
button = tk.Button(root, text='generieren')
button.pack(anchor=tk.W)
output = tk.Text(root, height=10, width=50)
output.pack(anchor=tk.W)
button['command'] = partial(
generate_passwords, output, anzahl_entry, laenge_entry
)
root.mainloop()
if __name__ == '__main__':
main()