Concepts / Debugging File and Directory Operations

Debugging File and Directory Operations

The return value from os.system provides a basic completion check: 0 indicates success, while a non-zero value indicates failure. The script can use this result to verify whether the backup operation completed.

  • Programming

From Clutter to Structure

A backup script can work correctly and still be difficult to maintain. If every backup is saved in one flat directory with a long timestamp-based filename, repeated use can produce dozens of similarly named files. Finding a backup from a particular day or checking whether a daily backup exists becomes harder. The maintenance improvement is to organize backups by date first and by time second.

backupmain directory20240115date directory143022.ziptime-stamped archive180500.ziptime-stamped archivecontainscontainscontains
What contains what when backups are organized by date and time?

The structure has three levels: a main backup directory, a date-based subdirectory, and a ZIP file whose name represents the backup time. For example, the date directory 20240115 represents January 15, 2024, while 143022.zip represents 2:30:22 PM. Multiple backups from the same day can therefore share one date directory while keeping separate time-stamped archive files.

Tracing the Directory Decision

Before an archive can be saved, the script must know whether the current date directory is already available. This creates a two-branch decision. If the directory exists, the script can use it. If it does not exist, the script creates it before continuing.

Date directorytarget pathos.path.existsdirectory present?Use directoryalready existsZIP archivecontinue backupos.mkdircreate missing directoryinspectyesnocontinuecontinue
What control flow occurs when the date directory exists versus when it must be created?
Code walkthrough
if not os.path.exists(date_directory):
    os.mkdir(date_directory)
  1. 1
    First, os.path.exists examines the directory path.
  2. 2
    The not condition selects the missing-directory case.
  3. 3
    os.mkdir creates the date directory only in that case.
  • The existence check tests whether the date-based directory is already present.
  • The directory is created only when the check shows that it is missing.

Turning Time into Names

The directory and file names are produced from formatted representations of the current date and time. Python's time.strftime function takes a format code and returns a string representation of the current date or time. In this backup design, the date format is %Y%m%d and the time format is %H%M%S.

Format codePurposeRole in the backup structure
%Y%m%dFormatted dateBecomes the date subdirectory name
%H%M%SFormatted timeBecomes the ZIP filename before the .zip extension

The two time.strftime formats used by the hierarchical backup approach.

python
Worked example

One Date, Two Backup Times

A backup runs on January 15, 2024 at 2:30:22 PM and then again at 6:05:00 PM. How does the hierarchical naming change?

  1. 1
    Format the date

    The date format %Y%m%d produces 20240115. Both backups occur on the same date, so both use the 20240115 subdirectory.

  2. 2
    Format the first time

    The first time produces 143022, so the first archive can be named 143022.zip.

  3. 3
    Format the second time

    The later time produces 180500, so the second archive can be named 180500.zip.

  4. 4
    Compare the paths

    The date portion remains the same while the time-based filename changes.

Result

The same date directory contains separate time-stamped files: 20240115/143022.zip and 20240115/180500.zip.

Current date%Y%m%d20240115date directory nameCurrent time%H%M%S143022ZIP file namestrftimestrftime
How does a date or time become formatted text used in a directory or file name?

From Paths to Archives

After the date directory is available and the time-based filename has been determined, the script constructs a system command. The command includes the full target path for the ZIP file and the source locations to be archived. The sources are joined into one space-separated string, and the resulting command is passed to os.system.

Target pathdate directory + time filezip -r commandconstructed stringos.systemexecute commandZIP archivetarget fileSource pathsspace-separatedinsertjoinpasscreate
How does information move from Python variables into the system command and then into the ZIP archive?
python

For example, if the target is /Users/swa/backup/20240115/143022.zip and the source is /Users/swa/notes, the constructed command is zip -r /Users/swa/backup/20240115/143022.zip /Users/swa/notes. os.system executes that command as an operating-system command.

Key point

The return value from os.system provides a basic completion check: 0 indicates success, while a non-zero value indicates failure. The script can use this result to verify whether the backup operation completed.

Debugging the Expected Path

Debugging this process means tracing each expected state in order. First identify the formatted date. Next confirm that the main backup directory and date directory form the intended location. Then identify the formatted time and append the .zip extension. Finally inspect the constructed command and the return value from os.system. This path-based trace makes it easier to determine whether a problem occurred during naming, directory preparation, command construction, or archive creation.

Worked example

Verifying a Daily Backup

Trace a backup intended for January 15, 2024 at 2:30:22 PM.

  1. 1
    Check the date value

    The date string should be 20240115, which identifies the date-based subdirectory.

  2. 2
    Check the directory decision

    Use os.path.exists to determine whether the 20240115 directory is already present. If it is missing, use os.mkdir to create it.

  3. 3
    Check the archive name

    The time string should be 143022, producing the filename 143022.zip.

  4. 4
    Check the complete target

    The target should combine the main backup directory, the 20240115 date directory, and the 143022.zip file.

  5. 5
    Check command completion

    After os.system executes the ZIP command, a return value of 0 indicates success; a non-zero value indicates failure.

Result

A successful trace ends with a time-stamped ZIP archive in the expected date-based directory and an os.system result of 0.

Format date20240115Check directoryexists or createFormat time143022Execute ZIPos.systemCheck result0 means successthenthenthenreturns
How can you trace the expected backup path and confirm that the directory and archive were created?

Mistakes to Catch

  • Common mistake

    Creating the date directory every time

    What it looks like

    Calling os.mkdir for the date directory without first checking whether it exists.

    Why it fails

    A repeated backup on the same day encounters a directory that has already been created.

    Do this instead

    Use os.path.exists first, and call os.mkdir only when the directory is missing.

  • Common mistake

    Putting the full timestamp into one flat filename

    What it looks like

    Saving every backup directly in the main directory with a long timestamp-based name.

    Why it fails

    Repeated daily backups create a cluttered flat list that is harder to search and verify.

    Do this instead

    Use the date as the subdirectory name and the time as the ZIP filename.

  • Common mistake

    Using the time value for the directory and the date value for the file

    What it looks like

    Reversing the roles of the %Y%m%d and %H%M%S strings.

    Why it fails

    The intended hierarchy is date-based directories containing time-stamped files.

    Do this instead

    Use %Y%m%d for the date directory and %H%M%S for the ZIP filename.

  • Common mistake

    Ignoring the os.system return value

    What it looks like

    Assuming the archive was created simply because the command was constructed.

    Why it fails

    Command construction and command success are separate stages.

    Do this instead

    Check whether os.system returned 0 or a non-zero value.

Practice the Trace

MEDIUM

Suppose the current date is January 15, 2024 and the backup runs at 6:05:00 PM. Describe the date directory, the ZIP filename, and the directory decision for a first backup of that day versus a later backup on the same day.

Hints
  • Apply %Y%m%d to the date.
  • Apply %H%M%S to the time.
  • For the first backup, decide what os.path.exists reports before os.mkdir runs.
  • For the later backup, decide whether os.mkdir should run again.

What do you think happens?

What happens when the backup runs again on January 15, 2024 at 6:05:00 PM after an earlier backup already created the date directory?

  • A new date directory is created

  • The existing date directory is reused and a different time-stamped ZIP file is selected

  • The earlier ZIP file is necessarily overwritten

  • The main backup directory is removed

Reveal answer
Answer:

The existing date directory is reused and a different time-stamped ZIP file is selected.

The date remains 20240115, while the later time produces 180500. The existence check prevents another creation attempt for the already existing date directory.

Key Takeaways

  1. 1
    A hierarchical backup uses a main directory, date-based subdirectories, and time-stamped ZIP files.
  2. 2
    os.path.exists checks whether the date directory is present, while os.mkdir creates it only when necessary.
  3. 3
    time.strftime('%Y%m%d') produces the date directory name, and time.strftime('%H%M%S') produces the time-based archive name.
  4. 4
    The ZIP command combines the target path with the source paths and is executed through os.system.
  5. 5
    An os.system return value of 0 indicates success; a non-zero value indicates failure.

At a glance

  • Organize backups hierarchically instead of keeping every archive in one flat directory.
  • Check for a date directory before creating it so repeated backups can use the same directory safely.
  • Use formatted date and time strings to create predictable names.
  • Construct the ZIP command from the target and source paths, then use the os.system result to verify completion.

More concepts starting with D