Overview
Workflow tip on automating folder creation in the Mac Finder. We will be using the simplicity of the Python programming language to build a tiny program that will take care of generating a complete folder hierarchy for our projects, based on a predefined template.
Throughout, we will also cover some basics of Python programming and point to resources that can help you learn more about it.
Here is the final script we will be writing - for quick reference. If you already know what you are doing, just paste it into a new text file and save it with a .py
extension. You can then duplicate the createFolder
line while swapping the My New
folder names with your own folder names to create your own folder hierarchy template. Then, look at the Running Our Program section for how to run the script, or follow the step by step guide below to understand what's going on.
import os
def createFolder(folder):
try:
if not os.path.exists(folder):
os.makedirs(folder)
except OSError:
print('Error creating folder: ' + folder)
createFolder('My New Folder')
createFolder('My New Folder/My New Subfolder')
Note: You can find this example and additional ready to use project templates on our github page.
Getting Started
If you are not familiar with Python follow these steps first to check if its installed on your system:
- Open the Terminal App (from the Applications folder or search for it in Spotlight)
- Type
python3 --version
orpython3 -V
. Then pressenter
on your keyboard to get the version of python installed on your Mac. - If you get a message saying
command not found
, try the same command without the3
to check if an older version of python is installed. If you get a similar message, download the latest Python here: https://www.python.org/downloads
Note: MacOS from 10.2 (Jaguar) to 10.15 (Catalina) includes a system version of Python 2. MacOS after 10.15 (Catalina) will not include a default system Python. More info here: https://wiki.python.org/moin/BeginnersGuide/Download
If a version number appeared, you have Python installed.
Note: At the time of writing there are two Python versions available: Python 2 and Python 3. Python 3 is recommended but not essential for our program to work.
Here is a digestible description of what Python is, what it does, and where it's used: https://www.pythonforbeginners.com/learn-python/what-is-python/
Code Editor
Next, you need a code editor. If you don't have one already there are plenty of options that you can find online. But for the time being let's use the default one that comes with the Python installation: IDLE.
To open IDLE, launch the Terminal app. Then type idle
and hit enter
on your keyboard.
The IDLE editor should launch.
Select the open window. Now go to File -> New File. Or press Ctrl + N
for a new file. This new window is where we will write our program.
Note: You can quit IDLE like any other Mac app.
Writing the Program
The goal of our program is to create a hierarchy of folders in the Finder based on a template we provide.
OS Module
To allow Python to interact with the Finder, that is part of the Mac OS, we need to import the os
(operating system) module first.
We can import the module by writing:
import os
Next, we are going to create a new function. A function is simply a task that can be called anytime once its declared and it will run any commands we specified within it. We will use it to perform the task of creating a new folder with a specified name. We will then be able to call it to create however many folders we choose to specify.
Writing Our Main Function
To declare a function in Python we can write:
def createFolder(folder):
# More code here...
Notice a few things:
def
is the term used to define a function.createFolder
is the name of our function (you can name it whatever you want as long as you don't use any reserved words or characters, or whitespaces). To play it safe just use lower or UPPERCASE characters, and_
underscores or-
dashes.- The parenthesis are used to pass in arguments, defined when calling the function (will make sense later on).
- The colon
:
signifies the start of the function's content. - The content can then be written on a new line but needs to have a tabbed space before it, to define it as such.
- In our example the
#
defines a comment in Python. You can add this symbol before any line of code to have it ignored by the interpreter - it won't execute.
Handling Errors
Moving on, let's add a snippet of code for error handling. This is a best practice and is important for helping us find out if something is wrong with our program. It looks like this:
try:
code1
except:
# error encountered
code2
It tells the interpreter to try
running code1
. If an error is encountered, run code2
instead.
We can add this content in our function like this:
def createFolder(folder):
try:
# do something
except OSError:
# do something else
Notice how the OSError
has been added just after except
. This is known as an exception and it's used when you want to check for a specific kind of error. OSError
handles file errors, such as if a file fails to be read or written to. Since we are working with files we can use this exception.
Note: For a list of Python exceptions see https://docs.python.org/3.8/library/exceptions.html
Create a folder
In our try
block let's write our command to create a folder in Finder, and in our except
block let's output a message to notify us if there is an error, and what folder caused it.
The print
command outputs a readable message as specified in the parenthesis. The +
symbol is used to concatenate our error message and the current folder name.
def createFolder(folder):
try:
os.makedirs(folder)
except OSError:
print('Error creating folder: ' + folder)
The command for creating a folder in Finder is makedirs
(make directories), and we are passing the name of the folder that needs to be created in the parenthesis - this will become clear in the next subsection...
Since the command belongs to the os
module we specify it by calling the module first, followed by a period and the command. The period suggests that the command belongs to that module: module.command()
-> os.makedirs()
.
Calling Our Function
We are now ready to call the function so it can run the commands we specified.
Below the function and without tabbed spaces, we can write:
def createFolder(folder):
try:
os.makedirs(folder)
except OSError:
print ('Error creating folder: ' + folder)
createFolder('My New Folder')
This will call the function we declared earlier and we finally see what the folder
argument in the parenthesis stands for. In essence, when calling a function we can pass parameters to it (known as arguments). Those can then be used within that function.
Note: We can name the argument whatever we want, again with the limitation of avoiding reserved characters or words, or whitespaces. Essentially the argument name can only be used within that function. If used outside, an error would be thrown.
In the example we are calling the function and passing the name of the folder (in the parenthesis) with it. Notice the single quotes around 'My New Folder'
. Those are necessary and state that the sequence of characters or words specified are to be interpreted as a String. You can use single or double quotes but it's a good idea to stick to one or the other. More about Strings here: https://www.programiz.com/python-programming/string.
Once the folder is created, we can create a subfolder by specifying the parent folder name first, followed by a forward slash and the subfolder name:
createFolder('My New Folder')
createFolder('My New Folder/My New Subfolder')
Note: We do not need to specify the full folder path since those are relative to the working directory from which we launched the program (see the Running Our Program section below).
Error: Folder Already Created
If we were to run this program it should hopefully not throw any errors. But if we were to run it again, it would definitely throw an error, since it would try to create a folder that already exists - it will halt the program and prevent overwriting.
But we want the program to continue creating folders aside from the ones that already exist.
To do this we can use an if
statement to perform a check. An if
statement allows us to run a command based on whether the statement, once checked, results as True or False. In our case we will check if the folder already exists. If it does not, the program will proceed with the creation of the new folder. If it does, we will skip folder creation for that folder.
Ordinarily we could write something like this:
if os.path.exists(folder):
# True: folder exists
else:
# False: folder does not exist so create it
But we want to simplify our code! We can therefore invert the statement so it evaluates True if the folder does not exist, and we can omit the else
altogether. To invert the statement we can use the not
operator.
And we end up with:
if not os.path.exists(folder):
# True: folder does not exist
Save
Let's save the file by going to File -> Save. Or pressing Ctrl + S
on your keyboard (not Cmd + S
). Name it myProjectTemplate
or whatever you prefer. Choose a directory or just save it to the Desktop.
That's it we can now attempt to run the program and see what happens...
Running Our Program
Create a new folder in Finder (e.g. on your Desktop) and call it New Project
or whatever you want.
Open a new Terminal window.
Type cd
to change directory, then tap on the spacebar
. Now drag and drop the folder you previously created to the Terminal window. You should have something like this:
cd /Users/your_username/Desktop/New\ Project
Press enter
on your keyboard - you now changed the working directory to the New Project
folder.
Now type python
if you have Python 2 installed or python3
if you have Python 3 installed. Hit spacebar
once, then drag and drop your python script myProjectTemplate.py
to the Terminal window.
# python 2
python /Users/your_username/Desktop/myProjectTemplate.py
# python 3
python3 /Users/your_username/Desktop/myProjectTemplate.py
Hit enter
.
If you navigate to the New Project
folder in Finder, you should see the new created folders.
Additional Resources
Gfxhacks Gists on Github:
Download Python:
Hitchhiker's Guide to Python:
If you are new to Python, check out this introduction:
Code from your browser:
Another useful Finder automation tip: