Seite 1 von 1

Verständniss Frage if Schleife

Verfasst: Montag 18. August 2014, 09:10
von taake
Moin, ich wollte ein script was ich im Netz gefunden habe etwas umschreiben, zur Zeit splitet es Dateien (nach Anzahl) in subdirs.
Ich wollte es jetzt etwas umbiegen das es mir die Daten anhand der Dateigröße in subdirs splittet, da ich gelegentlich größere Datenmengen für die offlinefraktion auf CD Brennen darf.

Allerdings benutzt der Author eine If kondition die ich nicht verstehe, daher hoffe ich das mir das hier jemand erklären kann was das genau bedeutet.

Code: Alles auswählen

i = 0
curr_subdir = None
N = 20
for f in files:
    # create new subdir if necessary
        if i % N == 0:
            subdir_name = os.path.join(abs_dirname, '{0:03d}'.format(i / N + 1))
            os.mkdir(subdir_name)
            curr_subdir = subdir_name

        # move file to current dir
        f_base = os.path.basename(f)
        try:
            shutil.move(f, os.path.join(subdir_name, f_base))
        except:
            pass
        i += 1

hier nur die relevante Funktion, verstehe nicht was das genau das % in der If-Schleife bedeutet,
N gibt im übrigen an wie viele Dateien in einen Ordner sollen (soll abgeändert werden das er vorher die Größe der Dateien berechnet und daran fest macht, was auch nicht das Problem ist)
Verstehe nur nicht was das % hier bedeutet und auch die (i / N + 1) Rechnung in
subdir_name = os.path.join(abs_dirname, '{0:03d}'.format(i / N + 1))
Erschließt sich mir nicht ganz was aber ggf. daran liegt das ich die Bedeutung des % nicht kenne.

Hoffe hier kann Jemand kurz Licht ins Dunkel bringen.

Danke im Vorraus

Re: Verständniss Frage if Schleife

Verfasst: Montag 18. August 2014, 09:27
von Hyperion
taake hat geschrieben: ...verstehe nicht was das genau das % in der If-Schleife bedeutet,
Dazu gleich erstmal der obligatorische Link: if-schleife ;-)
taake hat geschrieben: Verstehe nur nicht was das % hier bedeutet ...
Das ist der Modulo-Operator. Er berechnet also den (ganzzahligen) Rest einer Division.

Das kannst Du einfach in einer Python-Shell ausprobieren:

Code: Alles auswählen

 3 % 1
> 0

 3 % 2
> 1

 3 % 3
> 0

 3 % 4
> 3

 3 % 5
> 3

Re: Verständniss Frage if Schleife

Verfasst: Montag 18. August 2014, 09:30
von taake
Danke für den Link :mrgreen:

Und danke für die Erklärung ;)

Re: Verständniss Frage if Schleife

Verfasst: Montag 18. August 2014, 10:10
von BlackJack
@taake: Noch ein paar Anmerkungen zu dem Quelltext:

`curr_subdir` wird nirgends verwendet und wäre auch redundant weil der Name (nahezu) immer an den selben Wert gebunden ist wie `subdir_name`.

Statt `i` manuell vor der Schleife zu initialisieren und in/am Ende der Schleife hochzuzählen würde sich die `enumerate()`-Funktion anbieten.

Die Namen könnten besser sein. `N` und `f` sind sehr nichtssagend. Bei `file_count_per_folder` und `source_path` weiss der Leser wesentlich schneller was die Werte dahinter bedeuten.

Beim dividieren würde ich den ``//``-Operator benutzen um deutlich zu machen, dass hier nur der ganzzahlige Anteil der Division interessiert, und damit der Code nicht kaputt geht wenn man ``from __future__ import division`` verwendet, und damit der Code leichter nach Python 3 portierbar ist.

Die Ausnahme sollte man nicht so einfach komplett verschlucken. Man sollte wenigstens die möglichkeit Vorsehen sich die Ausnahme plus Traceback auf Wunsch anzeigen zu lassen. Das `logging`-Modul bietet sich an der Stelle an.

Code: Alles auswählen

def move_files(target_base_path, source_paths, count_per_folder=20):
    for i, source_path in enumerate(source_paths):
        if i % count_per_folder == 0:
            target_path = os.path.join(
                target_base_path, '{0:03d}'.format(i // count_per_folder + 1)
            )
            os.mkdir(target_path)
        try:
            shutil.move(
                source_path,
                os.path.join(target_path, os.path.basename(source_path))
            )
        except:
            pass  # TODO At least log the exception somewhere.

Re: Verständniss Frage if Schleife

Verfasst: Montag 18. August 2014, 14:08
von snafu
Ein nacktes `except` ist fast immer schlecht. Wenn man bestimmte Fehlerfälle ignorieren möchte, dann sollte man diese im Code benennen. Beim vorliegenden Beispiel bietet sich innerhalb der Schleife etwas in dieser Art an:

Code: Alles auswählen

try:
    # etwas Code
except (IOError, OSError) as error:
    if not error_handler:
        raise
    error_handler(i, source_path, error)