\documentclass[../../book.tex]{subfiles}
\graphicspath{{\subfix{.}}}
\begin{document}

\chapter{Pathlib}
\label{pathlib}
\setcounter{section}{-1}  % Start subsections from 0

Needing to open, create, and modify files and folders on a computer is a common enough task that several libraries exit to handle these operations.  In this book, we recommend using the library, \lstinline{pathlib}. Specifically, we suggest using the \lstinline{Path} class. 

Of course, the first question to address is: why do we need a library? Since files and folders and paths to them can be represented by \cite{string}s, then can't we always just supply a string when we are referring to files and folders? The answer is that we \textit{can}; however, there are several functionalities that are missing from that approach. Learning to use \lstinline{Path} will make code more general and will make handling files and folders more straightforward. A few examples of this are:
\begin{itemize}
    \item The strings needed for Windows and Mac/Unix/Linux are different.  In Windows, one separates folders and files with a backslash (\textbackslash). In Mac/Unix/Linux, it is a forward slash (/).  Thus, if we had a folder containing a file (file.fl), in Windows it is represented by "folder{\textbackslash}file.fl" while on Mac/Unix/Linux, it is represented by "folder/file.fl". What this means is that, if you write a code that uses strings for paths and might be used on different operating systems, then you will need to handle switching between these two representations.  However, if you use \lstinline{Path}, then this is handled automatically.
    \item When we look at a path to a file, we automatically break it down into components. For instance, when looking at "folder/file.fl" we can see there is a folder and a file and a file extension.  It is common to call the folder the "parent". If you use strings to give file paths, then the string has no idea about these components. However, if you use \lstinline{Path}, then you will have an object that includes ideas like parent and extension.  Below, we will see how to access these components and how they can simplify file handling. 
\end{itemize}

\section{Creating a \texttt{Path} object}
There are two ways to generate a \lstinline{Path} object, both involve the function \lstinline{Path()}:
\begin{enumerate}
    \item Supplying a string representing a path to a file or folder to the function \lstinline{Path()}. The string can be formatted using Windows or Mac/Unix/Linux conventions. 
    \item Supplying any number of strings separated by commas. The \lstinline{Path()} function will treat each of these as a component of the path, with them occuring in the order that they are supplied. 
\end{enumerate}

This creation of a path object requires a string be provided that contains the information for the path to the object.  You can get this string by typing in the information, copying and pasting from your computer, or using native file dialogs, as introduced in Chapter \ref{01OnePlot}.  However, there is one other way: using Pathlibs \lstinline{glob()} function. This function will look inside of a specified folder and return all the files within it. You can supply an argument that is a string specifying a pattern that filenames must match to be returned and this can contain wildcards.  for instance, \lstinline{glob("*.csv")} will return all filenames that end in '.csv'---in other words all csv files, since the `*' character acts as a \cite{wildcard}. 

And there is a variant of this function, which will recursively glob---that is, it will pull all files from the current folder and within any folders contained within that folder, and so on. This function is \lstinline{rglob()}


\section{Accessing components of \texttt{Path} objects}
There is other functionality that you might find useful. For instance, using \ul{attributes} of existing Path \cite{object}:
\begin{itemize}
    

    \item \textbf{Access a filename}. If all you want is the filename (including the extension), you can use \lstinline{<path object>.name}

    \item \textbf{Access the filename without the extension}. If you want the filename, but not the extension, you can use \lstinline{<path object>.stem}

    \item \textbf{Access the extension only}. If you only want to know the file extension (for instance, to know what kind of file it is), you can use \lstinline{<path object>.suffix}

    \item \textbf{Access the path to the parent folder}. To find the folder that contains the file (the parent folder) you can use \lstinline{<path object>.parent}

    \item \textbf{Access any folder in the path}. To get just a folder in the path, you can use \lstinline{<path object>.parents[n]}, where the \lstinline{parents} method returns an \cite{slicable} \cite{object} containing the folders in the path, ordered from the folder containing the object to the root folder, and \lstinline{[n]} selects the n$^{th}$ folder in this list. In this instance, counting starts at the parent folder (which contains the file) and goes until you get to the root directory (where the path starts). So, if you only want the parent folder you can use \lstinline{<path object>.parents[0]}, while the root folder is obtained using \lstinline{<path object>.parents[-1]} 
\end{itemize}

\section{Modifying existing \texttt{Path} objects}

\begin{itemize}
    \item \textbf{Adding to an existing path}\\
    This is done using the "/" operator.
    For instance, one might have a folder with several files (file1.fl, file2.fl, etc.) and you want to create a Path object for each. You could supply the full path to each, or you can create a path to the folder, and then extend this for each file. If the folder is in a path such as folder1/folder2/folder3, then we can do the following:
    \begin{lstlisting}
    from pathlib import Path
    folder = Path("folder1/folder2/folder3")
    f1 = folder/"file1.fl"
    f2 = folder/"file2.fl"
    \end{lstlisting}
    In this example, folder, \lstinline{f1}, and \lstinline{f2} are all path objects.  The folder object leads to the folder containing the files, and the \lstinline{f1} and \lstinline{f2} lead to their respective files.

    In constructing paths in this way, the variable that precedes the \lstinline{\} character \textit{must} hold a Path object. The object that follows the \lstinline{\} character can be a Path object or a \cite{string}. 

    \item  \textbf{Changing the extension}.  To change the extension, you can use the \lstinline{with_suffix()} method of the object.  When you supply an extension, you must still use the dot, and the extension must be a string data type.  So changing the extension of a file to be csv would use \lstinline{<path object>.with_suffix(".csv"})

    \item \textbf{Renaming the file}
\end{itemize}

To change the name of the file you can use the \lstinline{rename()} method of the Path object.  When you do that, you need to supply the path to where you want to have the renamed file.  So you use \lstinline{<path object>.rename("<new_file_path>")}

\end{document}