(Anfänger) Python Ordnerstruktur anlegen Problem

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
pateng
User
Beiträge: 4
Registriert: Sonntag 18. Juli 2021, 14:28

Hallo zusammen,
ich habe mit einer FiSi Umschulung angefangen, und da wir da auch Python nutzen, dachte ich mir, dass ich da schonmal etwas für lerne.
Bin jetzt seit ca. einer Woche dabei, und nach unzähligen Rechnern und Hello World-Programmen, habe ich mit meinem eigenen, kleinen Projekt begonnen.

Hintergrund des "Projekts": In der Ausbildung sollten wir eine Ordnerstruktur anlegen (händisch, ohne Python o.Ä.), und das wollte ich mit einem kleinen Programm umsetzen.

Klappt auch soweit, außer dass, sobald für einen Oberordner kein Unterordner angegeben wird, jener Oberordner nicht erstellt wird.
Aber wenn Unterordner mit angegeben werden, wirds angelegt.
Ich habe heute morgen mit dem Programm angefangen und seit bestimmt zwei Stunden hänge ich an diesem Problem. Mir fällt da einfach nichts ein.

Vlt. hat da jemand eine Idee?
Oder habe ich mich da als Anfänger übernommen?

Code: Alles auswählen

import os


def basispfad_eingabe():  # Speichert den Basispfad
    global basepath
    basepath = input("Basisverzeichnis angeben (zB. C:/): ")
    if "/" in basepath[-1]:
        print("Dein Basisverzeichnis lautet: ", basepath)
    else:
        basepath = basepath + "/"
        print("Dein Basisverzeichnis lautet: ", basepath)


def ordner_einlesen():  # Ordner einlesen und erstellen
    oberordner = [input("Geb hier deine Ordner, getrennt mit einem Leerzeichen, ein, "
                        "welche in deinem Pfad angelegt werden sollen: ")]
    for ordner in oberordner:  # Erstellt eine Iterierbare Liste der Oberordner
        ordnerliste = ordner.split(sep=' ')
    print("Deine Ordner lauten: ", *ordnerliste)  # Gibt die Ordnerliste aus
    unterordner_frage = input("Möchtest du in die bereits eingefügten Ordner noch Unterordner einfügen? (j/n): ")
    if unterordner_frage == 'j' or 'ja' or 'yes':  # Falls Unterordner eingefügt werden sollen, gehts in die For-Schleife
        for i in ordnerliste: 
            print("Gib deine Unterordner für {} ein: ".format(i)) 
            unterordner = list(map(str, input().split()))  # Eingabe der Iterierbaren Liste der Unterordner für jeden Oberordner (aus "i" der For-Schleife)
            for u in unterordner: 
                i = i + '/'  # zB. C:/Oberordner/
                comb = i + u  # Kombination, zB. C:/Oberordner/Unterordner
                os.makedirs(os.path.join(basepath, comb))  # Legt die Ordner an
	else: 
		print("noch nichts")


basispfad_eingabe()
ordner_einlesen()

pateng
User
Beiträge: 4
Registriert: Sonntag 18. Juli 2021, 14:28

Kaum hatte ich den Thread erstellt, eine Pause gemacht und wieder auf den Code geschaut, wusste ich wie ich es mache.
Hat leider bisschen gedauert bis der Thread freigeschalten wurde.
Hab das ganze jetzt bisschen geändert, jetzt klappt auch alles.

Schaut jetzt so aus:

Code: Alles auswählen

import os


def basispfad_eingabe():  # Speichert den Basispfad
    red = '\33[91m'
    blue = '\33[34m'
    global basepath
    print(blue + "Basisverzeichnis angeben (zB. C:/): ")
    basepath = input()
    if "/" in basepath[-1]:
        print("Dein Basisverzeichnis lautet: ", basepath)
    else:
        basepath = basepath + "/"
        print("Dein Basisverzeichnis lautet: ", basepath)


def ordner_einlesen():  # Ordner einlesen und erstellen
    red = '\33[91m'
    blue = '\33[34m'
    oberordner = [input(blue + "Geb hier deine Ordner, getrennt mit einem Leerzeichen, ein, "
                        "welche in deinem Pfad angelegt werden sollen: ")]
    for ordner in oberordner:  # Erstellt eine Iterierbare Liste der Oberordner
        ordnerliste = ordner.split(sep=' ')
    print("Deine Ordner lauten: ", *ordnerliste)
    unterordner_frage = input("Möchtest du in die bereits eingefügten Ordner noch Unterordner einfügen? (j/n): ")
    if unterordner_frage == 'j':
        for i in ordnerliste:
            i += "/"
            print("Gib deine Unterordner für {} ein: ".format(basepath+i))
            unterordner = list(map(str, input().split()))
            if not unterordner:
                os.makedirs(os.path.join(basepath, i))
                print("{} wurde ohne Unterordner erstellt.".format(basepath + i))
            else:
                for u in unterordner:
                    os.makedirs(os.path.join(basepath, i, u))
                    print("{} wurde erstellt.".format(basepath + i + u))
    else:
        for i in ordnerliste:
            os.makedirs(os.path.join(basepath, i))
            print("{} wurde erstellt".format(i))


basispfad_eingabe()
ordner_einlesen()
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Funktionen sind keine Sprungmarken. Funktionen sind in sich abgeschlossene Einheiten, die Informationen über ihre Argumente bekommen und Ergebnisse per return zurückgeben.
Vergiss gleich wieder, dass es `global` überhaupt gibt.
Pfade sind nicht einfach Strings, da stückelt man keine "/" dran, sondern benutzt os.path.join
i und u sind schlechte Variablennamen für Ordner. split liefert schon Strings, das man und list sind also überflüssig.
pateng
User
Beiträge: 4
Registriert: Sonntag 18. Juli 2021, 14:28

Danke für die Rückmeldung.
Ich denke spätestens morgen würde mir der Lehrer das gleiche sagen, falls ich es ihm zeige.

Da ich null Erfahrungen mit Funktionen hatte, dachte ich, bevor ich mit dem Programm angefangen habe, ich probiere es mal mit.
Werde ich komplett entfernen.

Bzg. dem Pfad...der Nutzer gibt ja sein Standardverzeichnis ein (C:/Arbeit/) zB., das "/" wird nur dran gehängt, wenn der Nutzer das letzte / vergisst. In dem Moment, bis einschließlich jetzt, wusste ich keine bessere Lösung.
Map und List hab ich entfernt, weiss selbst nicht mehr was ich mir dabei gedacht habe.

Grüße und danke.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@pateng: es ist egal, ob der Nutzer ein abschließendes / anhängt oder nicht, die Funktionen zum Verarbeiten von Pfaden können mit beidem umgehen.

`red` und `blue` sollten als Konstanten einmal definiert werden.
Die Funktion `ordner_einlesen` läßt vom Namen her etwas anderes erwarten. Ich denke, das Erzeugen ist die wesentliche Funktion der Funktion.
`oberordner` ist eine Liste mit exakt einem Eintrag, also eine unnötige Liste. Damit ist auch die for-Schleife unnötig.
Der Seperator ist unnötig, ohne wird auch an mehr als einem Leerzeichen, an Tabs usw. gesplittet, was ja in diesem Fall erwünscht ist.

Code: Alles auswählen

import os

RED = '\33[91m'
BLUE = '\33[34m'

def basispfad_eingabe():  # Speichert den Basispfad
    print(f"{BLUE}Basisverzeichnis angeben (zB. C:/): ")
    basepath = input()
    print("Dein Basisverzeichnis lautet:", basepath)
    return basepath


def ordner_erstellen(basepath):  # Ordner einlesen und erstellen
    oberordner = input(f"{BLUE}Geb hier deine Ordner, getrennt mit einem Leerzeichen, ein, "
                        "welche in deinem Pfad angelegt werden sollen: ")
    ordnerliste = oberordner.split()
    print("Deine Ordner lauten: ", *ordnerliste)
    unterordner_frage = input("Möchtest du in die bereits eingefügten Ordner noch Unterordner einfügen? (j/n): ")
    if unterordner_frage == 'j':
        for ordner in ordnerliste:
            ordner = os.path.join(basepath, ordner)
            alle_unterordner = input(f"Gib deine Unterordner für {ordner} ein: ").split()
            if not alle_unterordner:
                os.makedirs(ordner)
                print(f"{ordner} wurde ohne Unterordner erstellt.")
            else:
                for unterordner in alle_unterordner:
                    unterordner = os.path.join(ordner, unterordner)
                    os.makedirs(unterordner)
                    print(f"{unterordner} wurde erstellt.")
    else:
        for ordner in ordnerliste:
            os.makedirs(os.path.join(basepath, ordner))
            print(f"{ordner} wurde erstellt")


def main():
    basepath = basispfad_eingabe()
    ordner_erstellen(basepath)


if __name__ == "__main__":
    main()
Benutzeravatar
DeaD_EyE
User
Beiträge: 1016
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Erweiterung durch pathlib:

Code: Alles auswählen

from pathlib import Path


RED = "\33[91m"
BLUE = "\33[34m"


def basispfad_eingabe():
    """
    Speichert den Basispfad
    """
    print(f"{BLUE}Basisverzeichnis angeben (zB. C:/): ")
    basepath = input()
    print("Dein Basisverzeichnis lautet:", basepath)
    return Path(basepath)


def ordner_erstellen(basepath):
    """
    Ordner einlesen und erstellen
    """
    ordnerliste = input(
        f"{BLUE}Geb hier deine Ordner, getrennt mit einem Leerzeichen, ein, "
        "welche in deinem Pfad angelegt werden sollen: "
    ).split()
    print("Deine Ordner lauten: ", *ordnerliste)
    unterordner_frage = input(
        "Möchtest du in die bereits eingefügten Ordner noch Unterordner einfügen? (j/n): "
    )
    if unterordner_frage == "j":
        for ordner in ordnerliste:
            ordner = basepath / ordner
            alle_unterordner = input(
                f"Gib deine Unterordner für {ordner} ein: "
            ).split()
            if not alle_unterordner:
                ordner.mkdir(parents=True, exist_ok=True)
                print(f"{ordner} wurde ohne Unterordner erstellt.")
            else:
                for unterordner in alle_unterordner:
                    unterordner = ordner / unterordner
                    unterordner.mkdir(parents=True, exist_ok=True)
                    print(f"{unterordner} wurde erstellt.")
    else:
        for ordner in ordnerliste:
            ordner = basepath / ordner
            ordner.mkdir(parents=True, exist_ok=True)
            print(f"{ordner} wurde erstellt")


def main():
    basepath = basispfad_eingabe()
    ordner_erstellen(basepath)


if __name__ == "__main__":
    main()

Auffällig sind solche Konstruktionen:

Code: Alles auswählen

unterordner = ordner / unterordner
Dort wird aus Ordner und Unterordner ein neues Objekt erstellt (join) und unterordner zugewiesen.
Besser wäre vielleicht unterunterordner
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
pateng
User
Beiträge: 4
Registriert: Sonntag 18. Juli 2021, 14:28

Irgendwie habe ich alles falsch gemacht, was man falsch machen kann. Und ich war stolz wie Bolle dass das Programm überhaupt funktioniert.
Danke euch, werde das ganze überarbeiten.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Es ist nicht alles falsch, aber man kann immer alles besser machen. Wie soll man sonst lernen, wenn man nicht auch Fehler machen darf?
Antworten