Python Programm mit append erweitern

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.
Phobit
User
Beiträge: 71
Registriert: Freitag 4. Mai 2018, 18:13

Freitag 25. Mai 2018, 14:48

Hallo mal wieder,
man kann ja Datein öffnen, und auch Texte mit dem append-Befehl einfügen, z.B.:

Code: Alles auswählen

sdatei = open("Test.py")
l = sdatei.readlines()
sdatei.close()
l.append("#Das ist ein Test")
sdatei = open("Test.py", "w")
sdatei.write("".join(l))
sdatei.close()
Soweit ich weiß, macht man sowas eher mit txt datein. wie man aber hier sehen kann, versuche ich das ganze in ein Python Programm einzufügen. Blos da stellt sich mir die allgemeinere Frage, ist es möglich,
1. z.B. nach "das ist" und vor "ein Test" noch was einzufügen?
2. Einrückungen zu beachten? z.b. wenn in der Zeile drüber ein if steht...
Viele Grüße und danke im Vorraus!
Tholo
User
Beiträge: 80
Registriert: Sonntag 7. Januar 2018, 20:36

Freitag 25. Mai 2018, 14:56

Wozu sollte das nötig sein?Wieso willst du Code im Code einfügen?

Funktion und Klassen kann man importieren.

Code: Alles auswählen

import test
Falls du nicht weißt was gemeint ist. Schaue mal nach dem Import von Modulen
Benutzeravatar
ThomasL
User
Beiträge: 244
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Freitag 25. Mai 2018, 16:09

Der Sinn erschließt sich auch mir nicht, jedoch hier ein Snippet mit Beispiel für deine Frage 1.
kleine Optimierung; durch das with kann man sich das close() sparen

zu 2.
eventuell könnte man ja die führenden Leerzeichen einer Zeile zählen und diese Anzahl dann dem einzufügenden Text voranstellen.

ich hoffe dir ist klar, dass im Moment der Text ans Ende der Datei angehängt wird
und nicht irgendwo zwischen den Zeilen

Code: Alles auswählen

with open("Test.py") as rdatei:
    lines = rdatei.readlines()

text = "bestimmt"
zeile = f"#Das ist {text} ein Test\n"
lines.append(zeile)

with open("Test2.py", "w") as wdatei:
    wdatei.write("".join(lines))
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
Phobit
User
Beiträge: 71
Registriert: Freitag 4. Mai 2018, 18:13

Samstag 26. Mai 2018, 15:49

Tholo hat geschrieben:
Freitag 25. Mai 2018, 14:56
Wozu sollte das nötig sein?Wieso willst du Code im Code einfügen?

Der Sinn dahinter ist, dass ich vor habe in tkinter (anderes Forum, ich wollts erst hier probieren) ein Login Fenster mit "Registrieren" Befehl zu machen. Somit sollte der Code dann selbstständig den Nuttzernamen und das Passwort in "sich selbst" einfügen, z.B.in eine Zeile

Code: Alles auswählen

if passwd == "Test" and usr == "User" :
Also der neuen Daten sollen sich hinter den ":" einfügen. das war mein Ziel.
Sirius3
User
Beiträge: 8090
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 26. Mai 2018, 16:02

Üblicherweise ändert man das Programm nicht, sondern schreibt eine Konfigurationsdatei, die vom Programm gelesen wird. Das ist deutlich einfacher und nicht so fehleranfällig.
Benutzeravatar
ThomasL
User
Beiträge: 244
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Samstag 26. Mai 2018, 17:00

Und da wir nun die DGVSO haben, solltest du besser nicht Name und Passwort im Klartext speichern..... :lol: :lol: :lol:
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
Phobit
User
Beiträge: 71
Registriert: Freitag 4. Mai 2018, 18:13

Sonntag 27. Mai 2018, 12:07

Sirius3 hat geschrieben:
Samstag 26. Mai 2018, 16:02
Üblicherweise ändert man das Programm nicht, sondern schreibt eine Konfigurationsdatei, die vom Programm gelesen wird. Das ist deutlich einfacher und nicht so fehleranfällig.
Wie schreibt man so eine Konfigurationsdatei, also wie könnte sowas aussehen?
bin noch relativ neu, ich kenn mich da wenig aus ^^
nezzcarth
User
Beiträge: 522
Registriert: Samstag 16. April 2011, 12:47

Sonntag 27. Mai 2018, 12:15

Phobit hat geschrieben:
Sonntag 27. Mai 2018, 12:07
Wie schreibt man so eine Konfigurationsdatei, also wie könnte sowas aussehen?
bin noch relativ neu, ich kenn mich da wenig aus ^^
In der Regel, in dem man ein fertiges Modul nimmt, das so etwas für einen erledigt. Von selbst erfundenen Konfigurationsformaten sollte man möglichst Abstand nehmen. Beliebt sind zum Beispiel INI-Dateien (die hast du sicher schon mal gesehen) oder YAML. Für ersteres gibt es etwas in der Standardbibliothek von Python: https://docs.python.org/3/library/configparser.html . Für YAML braucht man ein externes Paket.

Teilweise werden auch einfach Pythondateien als Konfigurationsdateien verwenden (s. z.B. Django); das ist aber auch nicht unbedingt unumstritten... XML und JSON (für beides gibt es Module in der Standardbibliothek) werden ebenfalls manchmal für diesen Zweck verwendet, sind m.M.n. aber nicht so bequem von Hand zu editieren. Änderungen in das Skript selbst zu schreiben, wie du es vorschlägst, ist, vorsichtig gesagt, sehr unkonventionell ;)
Phobit
User
Beiträge: 71
Registriert: Freitag 4. Mai 2018, 18:13

Sonntag 27. Mai 2018, 13:01

puh, da werd ich einiges zum lesen haben bis ich das mit den Konfigurationsdatein drauf hab :)
Eine einfachere Einsteigerfreundliche Methode gibts nicht??? XD ;)

trotzdem schonmal danke!
nezzcarth
User
Beiträge: 522
Registriert: Samstag 16. April 2011, 12:47

Sonntag 27. Mai 2018, 14:49

So kompliziert ist das nicht. Wenn du Python auf dem Level beherrschst, wie es im mitgelieferten Tutorial vermittelt wird, sollte es kein Problem sein, das configparser-Modul zu verwenden. Gerade dieses Modul versucht ja einfache Interfaces anzubieten. Schau dir mal die ersten paar Abschnitte der Seite, die ich verlinkt habe an, so schwierig ist das nicht :) Falls da Lücken bestehen, solltest du diese m.M.n. schließen, ansonsten wird auch die Beschäftigung mit tkinter eher frustrierend, das noch mal deutlich mehr Vorkenntnisse erfordert.
Tholo
User
Beiträge: 80
Registriert: Sonntag 7. Januar 2018, 20:36

Sonntag 27. Mai 2018, 17:31

Ich bin auch neu in der Programmierwelt. Aber das Configparser Modul und die Einarbeitung darin, ist alles andere als "unnötig". Weil du das dann in jedem Code anwenden kannst.Du findest auch deutsche Anleitungen dazu. Es lohnt sich!
Benutzeravatar
Kebap
User
Beiträge: 398
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Donnerstag 7. Juni 2018, 10:41

Phobit hat geschrieben:
Samstag 26. Mai 2018, 15:49
Der Sinn dahinter ist, dass ich vor habe in tkinter (anderes Forum, ich wollts erst hier probieren) ein Login Fenster mit "Registrieren" Befehl zu machen. Somit sollte der Code dann selbstständig den Nuttzernamen und das Passwort in "sich selbst" einfügen, z.B.in eine Zeile

Code: Alles auswählen

if passwd == "Test" and usr == "User" :
Ich habe das immer noch nicht ganz verstanden.

Also es gibt ein Login Fenster mit "Registrieren" und da gibt man Username und Passwort ein.

Das willst du dir irgendwo wegspeichern und merken?

Vermutlich, damit man dann später wiederkommen kann und sich mit den registrierten Daten anmelden kann?

Also man gibt dann in einem Login Fenster die Username und Passwort ein, und das Programm prüft, ob es diese Kombination schon so in der weggespeicherten Datei gibt? Wenn ja, kommt man rein, wenn nein, dann muss man sich erstmal registrieren?

Habe ich das soweit verstanden?

Dann scheint mir eine Konfigurationsdatei nicht mein erster Weg zum Ziel.
Üblicherweise erstellt man sich eine Datenbank von registrierten Benutzern samt Passwort und weiteren Daten zum Account.
Natürlich kannst du statt Datenbank auch eine Textdatei nehmen, wenn dir das leichter scheint?!

Jedenfalls gar nicht solltest du die Daten in den Code aufnehmen, z.B. als feste Parameter im "if" Befehl wie von dir oben vorgeschlagen.
Sondern der if Befehl sammelt sich seine Daten immer aus der Datenbank/Datei und prüft dann einfach alle nacheinander durch.

Hoffe es wurde dadurch einsteigerfreundlicher und verständlich :mrgreen:
MorgenGrauen: 1 Welt, >12 Gilden, >85 Abenteuer, >1000 Waffen und Rüstungen,
>2500 NPC, >16000 Räume, >170 freiwillige Programmierer, einfach Text, seit 1992.
Benutzeravatar
__blackjack__
User
Beiträge: 757
Registriert: Samstag 2. Juni 2018, 10:21

Donnerstag 7. Juni 2018, 11:20

Egal wo gespeichert wird: Das Passwort sollte auch nicht im Klartext gespeichert werden, sondern wie üblich ”gesalzen” und gehasht werden. Vorzugsweise mit einer Hashfunktion die speziell für diesen Zweck entwickelt wurde.
Global warming is caused by the sun.
Phobit
User
Beiträge: 71
Registriert: Freitag 4. Mai 2018, 18:13

Samstag 9. Juni 2018, 16:11

Kebap hat geschrieben:
Donnerstag 7. Juni 2018, 10:41
Phobit hat geschrieben:
Samstag 26. Mai 2018, 15:49
Der Sinn dahinter ist, dass ich vor habe in tkinter (anderes Forum, ich wollts erst hier probieren) ein Login Fenster mit "Registrieren" Befehl zu machen. Somit sollte der Code dann selbstständig den Nuttzernamen und das Passwort in "sich selbst" einfügen, z.B.in eine Zeile

Code: Alles auswählen

if passwd == "Test" and usr == "User" :
Ich habe das immer noch nicht ganz verstanden.

Also es gibt ein Login Fenster mit "Registrieren" und da gibt man Username und Passwort ein.

Das willst du dir irgendwo wegspeichern und merken?

Vermutlich, damit man dann später wiederkommen kann und sich mit den registrierten Daten anmelden kann?

Also man gibt dann in einem Login Fenster die Username und Passwort ein, und das Programm prüft, ob es diese Kombination schon so in der weggespeicherten Datei gibt? Wenn ja, kommt man rein, wenn nein, dann muss man sich erstmal registrieren?

Habe ich das soweit verstanden?
Der eigentliche Sinn war, geht ja scheinbar nicht, dass sich der User registriert, mit einem uSrname und einem passwd. dann zieht das Programm mit Eingabefeld.get() den Username und das passw und fügt in in sich selbst, also in das Programm, ein.
Dann scheint mir eine Konfigurationsdatei nicht mein erster Weg zum Ziel.
Üblicherweise erstellt man sich eine Datenbank von registrierten Benutzern samt Passwort und weiteren Daten zum Account.
Natürlich kannst du statt Datenbank auch eine Textdatei nehmen, wenn dir das leichter scheint?!

Jedenfalls gar nicht solltest du die Daten in den Code aufnehmen, z.B. als feste Parameter im "if" Befehl wie von dir oben vorgeschlagen.
Hoffe es wurde dadurch einsteigerfreundlicher und verständlich :mrgreen:
Und wie sähe dann so ne Datenbank/txt aus?
bzw Wie gelangen dann Username und Passwd da rein?
kann man das vom Programm aus richtigen reinschreiben lassen, oder muss ich das selbst machen (genau das würd ich ja vermeiden wollen!)
Sondern der if Befehl sammelt sich seine Daten immer aus der Datenbank/Datei und prüft dann einfach alle nacheinander durch.
Und wie sähe dass dann ungefähr aus? da komm ich grade überhaupt nicht mit... :K

Trotzdem Danke schonmal!
Sirius3
User
Beiträge: 8090
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 9. Juni 2018, 16:47

Am besten läßt man das Programm so eine Passwort-Datei schreiben, den Passwort-Hash muß es sowieso berechnen. Um das einigermaßen sicher zu machen, benutzt man am besten schon vorhandene Funktionen. Trotzdem läßt sich noch so einiges suboptimal lösen, z.B. feste Parameter zu verwenden, die sich später nicht mehr ändern lassen.

Hier mal eine kleine Lösung, wo sich die Passwörter in einer JSON-Datei speichern lassen:

Code: Alles auswählen

import hashlib
import binascii
import os
import json

PASSFILE = "passwords.json"
HASH_NAME = 'sha256'
SALT_LENGTH = 32
ITERATIONS = 1000000
DUMMY_HASH = ':'.join([HASH_NAME, "1"*64, "12"*SALT_LENGTH, str(ITERATIONS)])

def generate_hash(password):
    salt = os.urandom(SALT_LENGTH)
    key = hashlib.pbkdf2_hmac(HASH_NAME, password.encode('utf8'), salt, ITERATIONS)
    return ':'.join([HASH_NAME, 
        binascii.hexlify(salt).decode('ascii'),
        binascii.hexlify(key).decode('ascii'),
        str(ITERATIONS)])

def check_hash(hash, password):
    hash_name, salt, hash, iterations = hash.split(':')
    key = hashlib.pbkdf2_hmac(hash_name, password.encode('utf8'), binascii.unhexlify(salt), int(iterations))
    return key == binascii.unhexlify(hash)

def load_passwords():
    if not os.path.exists(PASSFILE):
        return {}
    with open(PASSFILE) as passfile:
        return json.load(passfile)

def register(user, password):
    passwords = load_passwords()
    if user in passwords:
        raise AssertionError("user already exists")
    passwords[user] = generate_hash(password)
    with open(PASSFILE, 'w') as passfile:
        json.dump(passwords, passfile)

def login(user, password):
    passwords = load_passwords()
    hash = passwords.get(user, DUMMY_HASH)
    if not check_hash(hash, password):
        raise AssertionError("login failed")
Bei vielen Nutzern würde man auf jeden Fall eine Datenbank nehmen.
Antworten