Issue related to: os Automation, Core Python – For Loops
Module used: OS
Issue Link: https://www.reddit.com/r/learnpython/comments/g1g3wj/trying_to_learn_to_automate_repetitive_tasks/
Issue:
Hello I have a text file that has a file name in each line i.e. foldername1 foldername2 etc.
I wanted to create folders with the read lines from the text file. I got the reading from the file and creating folders part. Unfortunately it only makes one folder and stops. Why does my counter stop?
import os linecounter = 0 fileforest = open("filenames.txt", "r") for filenames in fileforest.readlines(): linecounter = linecounter +1 fileforest.close print(filenames) def createFolder(directory): try: if not os.path.exists(directory): os.makedirs(directory) except OSError: print ('Error: Creating directory. ' + directory) createFolder('./data/{}{}'.format(filenames, linecounter))
Short Answer
The createFolder functions needs to be in a loop
Explanation
The user would like to create folders and name them quickly. He plans to use a text file filenames.txt to store the names of the folders line by line. He also wants the folders to be in the folder data. Our task is to take the names from the text file and create these folders.
filenames.txt
There are several tasks that need to be completed to achieve our goal;
Lets tackle the first task opening the text file in Python
To do this we can use the open() function in Python. We will pass the location and the name of the text file into the open() function – In our case, the text file will be in the same directory and will be called filenames.txt .
As we are reading a text file we do not need to pass “rt” into the open function as this are default values.
We will store the contents into the variable content:
content = open("filenames.txt")
The second task is to read the first file
We know that the text file will look something as follows:
foldernamea
foldernameb
foldernamec
foldernamed
It is helpful to know the names of the folders are on separate lines. However we do need to remember Python sees a new line as \n
This means we can use the readline() function to read the first line in Python.
We will then store this as the variable folder:
folder = content.readline()
We now need to remove the \n at the end of the folder name – We can use the function .rstrip(), we do not need to pass any parameters and will overwrite the variable folder
folder = folder.rstrip()
So we have
folder = content.readline()folder = folder.rstrip()
The third task to create a folder using this name
To achieve this will use the library os
import os
To create a folder we can use the function os.makedirs(). The function os.makedirs() takes in the directory where you want to make the folder, this gives us the chance to instruct the computer that we want to put our folder in the data folder
We can use .format() function to achieve this:
'./data/{}'.format(folder)
We will store this in the variable directory
directory = './data/{}'.format(folder)
So in the end we will have
os.makedirs(directory)
Now before we can run this we should use try and except so that we can identify issues if they do arise.
We need to first check if the file path ./data/ already exists – Inside of a try block, if the directory does not exist then try to create it
We can use the function os.path.exists() and pass directory to see if it is there
In addition this will make sure we do not have duplicate folders of the same name in the future
try: if not os.path.exists(directory): os.makedirs(directory)
Otherwise raise an error with the reference OSError
except OSError: print ('Error: Creating directory. ' + directory)
By now we have:
directory = './data/{}'.format(folder)try: if not os.path.exists(directory): os.makedirs(directory) except OSError: print ('Error: Creating directory. ' + directory)
Now this should create our first folder in a data folder
The fourth task is to create a loop for the whole file
Going back to task two where we the created a folder variable “folder = content.readline()” we will now convert this to a for loop:
for folder in content.readlines()
Instead of using the readline() functions we will use readlines() function to read the whole text file.
Inside of the for loop we will have everything we had before:
for folder in content.readlines(): folder = folder.rstrip() directory = './data/{}'.format(folder) try: if not os.path.exists(directory): os.makedirs(directory) except OSError: print ('Error: Creating directory. ' + directory)
We have now successfully completed the main task
The fifth task is to Finalize the program
The user wants a number beside the folder name. In addition, we need to put create folder into a function of its own
We will define a function as createFolder and we will pass in the directory as the parameter.
The function will come before our for loop
Inside of the function we will have the try and except block like so:
def createFolder(directory): try: if not os.path.exists(directory): os.makedirs(directory) except OSError: print ('Error: Creating directory. ' + directory)
Before the for loop but not in the createFolder function we need to have the variable linecounter=0 to initialize the linecounter variable
linecounter=0
Inside the for loop we need to increment the linecounter:
linecounter+=1
We also need to invoke the create folder which now takes in the linecounter as well:
createFolder('./data/{}{}'.format(folder.rstrip(),linecounter))
I have moved the .rstrip() function here as well.
In the end of the program we can print Task completed
print("Task Completed")
Furthermore we can open the data folder in windows explorer by using the subprocess.Popen() from the sub process library
import subprocesssubprocess.Popen('explorer "data"')
The final code:
import os import subprocesscontent = open("filenames.txt")linecounter = 0 def createFolder(directory): try: if not os.path.exists(directory): os.makedirs(directory) except OSError: print ('Error: Creating directory. ' + directory) for folder in content.readlines(): linecounter += 1 createFolder('./data/{}{}'.format(folder.rstrip(),linecounter)) print("Task Completed")subprocess.Popen('explorer "data"')