A simple app you can create to speed up your workflow.
Intro to Python for Curious VFX Artists
A simple app you can create to speed up your workflow.

If you work in visual effects, you’ve probably noticed that some of your peers use the power of code to automate repetitive tasks that distract from more interesting work. 

You may have been handed a script from a friend, looked under the hood and thought “Wow, that’s really complicated. I could never come up with something like that.” Conversely, you may have looked at an introductory Python tutorial and thought, “Yeah, I don’t really want to spend months writing worthless ‘Hello World’ type programs.”

So what’s the most basic program you can write that is simple enough for a beginner to create, but might also have actual, real-world use for your work?

At the beginning of the pandemic shutdown, I lost my job, bought a copy of “Learn Python the Hard Way” and a few weeks later, wrote a sixty-line app that creates a folder structure for new projects that I take on as a freelancer. Inside that folder structure, another Python script is generated that creates dated folders for all my render output. This is something you could just do by hand if you wanted, but my script saves enough clicks to make it worth it.

If you follow along with this guide, you’ll create the same simple script that I use for setting up my freelance projects, but you’ll be able to customize it for your own preferences as well. At the end, you’ll see that it’s not too hard to write little scripts that automate your workflow. 

You’ll need to download two programs to start: Python 3 (surprise!) and VS Code, the most popular code editor. You can actually use any code editor you want, but VS Code has the most plugins and functionality, so you’ll probably end up using it eventually even if you start with something else. For both apps, just download the latest stable version listed on their websites.

This next part is optional, but highly recommended. In order to make VS Code a more powerful coding environment, you might want to enable the following extensions: Python — which enables intelligent autocomplete suggestions while you code, Prettier — which formats your code to be more readable and standardized and One Dark Pro — my preferred color scheme, which makes long coding sessions easier on your eyes.

Once you have your environment set up, open VS Code and hit CTRL-N to start a fresh script. Click on “Select a language” and choose COBOL — just kidding — choose Python. Hit CTRL-S to save your script in your projects folder and name it “Make_New_Project.py”.

When writing code, similarly to comping a shot, there’s no point in re-inventing the wheel. In Python we use “modules” which are just Python scripts someone else wrote that have functionality we want to use in our own scripts. Anyone can write a module, and all the most popular ones can be installed for free from the internet. For this particular script, we only need modules that already come pre-installed with Python.

As each code block comes up in this tutorial, type it into your script in VS Code.

import os, tkinter as tk
from tkinter import simpledialog

What does this all mean? The first line tells Python to import os, the module that allows it to use your operating system’s folder functionality and tkinter, Python’s pre-installed GUI module. It lets you create simple user interfaces. Adding “as tk” lets you refer to tkinter as “tk” instead of typing out “tkinter” every time you need to reference it, shaving a precious milliseconds of coding time off your life. Wow!

The second line tells Python to import a specific function called “simpledialog” from tkinter. Importing it this way allows you to call the simpledialog function in your code without referring to the tkinter module every time. 

root = tk.Tk()

The first line declares “root” as a variable. Variables are created and assigned various types of data to be used over and over. You can use them to store numbers, text, groups of numbers and text, etc.

In this instance, we are assigning the variable “root” to an instance of the Tk function inside of tkinter and calling the function which contains the code that drives our (extremely simple) user interface. When a function is associated with a specific object, in our case “tk”, it is called a method.

The second line calls the withdraw() method associated with our root object, which will get rid of some extra tkinter UI that we don’t want. 

new_project = simpledialog.askstring(title=" ", prompt="New Project Name:")
new_project = new_project.replace(" ", "_")
new_project = new_project.upper()

Now that we have activated the code that drives our UI, we can create a small popup dialog box that, upon launching the script, asks the user to name their new project. The first line creates a new_project variable and assigns it to tkinter’s “simpledialog” function. When it pops up, it has the prompt “New Project Name:” and gives the user an input box to type their choice.

My personal preference for project folder names is that they have no spaces and are uppercase. The second line takes the user’s input, which is saved as a string and replaces any spaces with underscores. The third line calls the “upper” function which you may have guessed transforms all lowercase letters to uppercase.

path = os.path.dirname(__file__)
prj_dir = path + "\\" + new_project

Now that we’ve created our project folder, let’s create our main category folders to organize our project. We will declare a variable called “main_directories” and create a list assigned to it. A list stores a group of objects, and in our case, we are storing the names of the folders we want to create. Lists can store numbers, text (called “strings”) and other object types as well. Our list will contain the names (stored as “strings”) of the folders we want to create.

main_directories = [

Let’s also create the sub directories that will further organize our project. We declare the variable “sub_directories” and assign a list to it with all of the names of our proposed sub folders. Depending on your own needs you can modify this later, but follow along with this same code for now.

sub_directories = [
    ["01_COMP", "02_3D", "03_TRACK", "04_EDIT"],
    ["01_REVIEW", "02_POSTING", "03_DELIVERY"],

As you can see, the “sub_directories” list consists of five elements, which are also lists.

Now let’s create all the folders using a loop. I love loops because they are the simplest way to make computers perform the same action over and over, while I eat snacks and watch more tutorials.

In the loop below, I am asking the computer to perform two functions: len() and range(). Applied to the list “sub_directories” these functions will first return with the length of the list (5) and then return a range spanning the length of the list, beginning with 0… so 0 to 4. Now we can loop across each element in the list and refer to each elements specific index. In a for loop, we assign a variable — in our case, x — and use it later to refer to the index of the element we want to use. 

Everything indented under the for loop is an instruction that will be performed for each cycle in the loop. The first instruction “os.mkdir(os.path.join(prj_dir, main_directories[x]))” will create a new folder inside the main project director with the name specified in the main_directories list. Since we are using the index value, it will use the string of the element of the specific index (0,1,2,3,4) each time we loop through the code.

The second instruction is… another loop! That’s right. You can nest loops inside of loops. Again, we are using a “for” loop and assigning a random variable “y” to stand in for the index of the “sub directories” list. For each subdirectory “y” we are creating it and placing it inside the main directory “x”. Keep this in mind if you decide to change the number or order of directories for yourself. 

for x in range(len(sub_directories)):
    os.mkdir(os.path.join(prj_dir, main_directories[x]))
    for y in range(len(sub_directories[x])):

Alright, now we have a new project folder with project name specified, main area folders and sub folders that further organize our project. We could stop here, but let’s go one step further.

As we are rendering our files for internal review, posting and delivery, I’d like to keep them organized by date. It would be great to have an easy way to create folders with the date for each date that we have new renders instead of making them by hand. Let’s do that.

We will use another “for” loop and assign it the variable “z” so we can loop across all the sub folders inside of the “Output” folder. Each time we loop, we will create a variable containing the name of a new file called “Make_Date_Folder.py” with the entire file path attached.

This new python file will be inside each of the three folders so you can click on it each day you are working and instantly create a new date folder. It would be great if these folders were automated to create the date folder without us having to actually click another script each time, but… we’re not Python Jedis…yet.

We will declare a new variable “f” as in “file” and instruct it to open a new file using the file name we specified. With our new file opened we will write six lines of code inside of it, while using “\n” to signify when we want to write code on a new line.

The first line imports the “os” module so we can use the file system. The next line imports the date function from the datetime module. We then declare the variable “today” and assign to it the today function from date. We will create the variable “datetime” and assign to it today’s date using today. The formatted date that we get back has backslashes in it, which we don’t want in our directory names so we will use the replace method to replace them. We will use the mkdir method to create the new folder using the path of our original script using the “__file__” variable. This is a specially defined variable in Python and as such, it uses the “double under” notation also known as “dunder.” Basically, if you ever refer to “__file__” it will reference the current script that is running the code, in our case the “Make_New_Project.py” script. Finally, we will use the “close” method to close the file. 

for z in range(len(sub_directories[4])):
    fileDir = prj_dir + "\\05_OUTPUT\\" + sub_directories[4][z]
    fileName = file_dir + "\\" + "Make_Date_Folder.py"

    f = open(fileName, "a")
        "import os \n"
        + "from datetime import date \n"
        + "today = date.today() \n"
        + 'datetime = today.strftime("%m/%d/%y") \n'
        + 'datetime = datetime.replace("/","") \n'
        + 'os.mkdir(os.path.dirname(__file__) + "\\\\" + datetime)'

Alright, that’s all you need to create your super simple at-home freelancer pipeline. You can save this file and copy it to wherever you store your projects. And you now have a basic understanding of coding in Python and how it can be used to automate boring, repetitive tasks. 

You can check out the complete code to compare to your own.