How to change directories within Python? - python

I have the following code. It works for the first directory but not the second one...
What I am trying to do is to count the lines on each of the files in different directory.
import csv
import copy
import os
import sys
import glob
os.chdir('Deployment/Work/test1/src')
names={}
for fn in glob.glob('*.c'):
with open(fn) as f:
names[fn]=sum(1 for line in f if line.strip() and not line.startswith('/') and not line.startswith('#') and not line.startswith('/*')and not line.startswith(' *'))
print ("Lines test 1 ", names)
test1 = names
os.chdir('Deployment/Work/test2/src')
names={}
for fn in glob.glob('*.c'):
with open(fn) as f:
names[fn]=sum(1 for line in f if line.strip() and not line.startswith('/') and not line.startswith('#') and not line.startswith('/*')and not line.startswith(' *'))
print ("Lines test 2 ", names)
test2 = names
print ("Lines ", test1 + test2)
Traceback:
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'Deployment/Work/test2/src'

You'll either have to return to the root directory using as many .. as required, store the root directory or specify a full directory from your home:
curr_path = os.getcwd()
os.chdir('Deployment/Work/test2/src')
os.chdir(curr_path)
os.chdir('Deployment/Work/test2/src')
Or:
os.chdir('Deployment/Work/test2/src')
os.chdir('../../../../Deployment/Work/test2/src') # Not advisable
Instead of the above, you may consider more Pythonic ways to change directories on the fly, like using a context manager for directories:
import contextlib
import os
#contextlib.contextmanager
def working_directory(path):
prev_cwd = os.getcwd()
os.chdir(path)
yield
os.chdir(prev_cwd)
with working_directory('Deployment/Work/test1/src'):
names = {}
for fn in glob.glob('*.c'):
with working_directory('Deployment/Work/test2/src'):
names = {}
for fn in glob.glob('*.c'):
...
You simply specify the relative directory from the current directory, and then run your code in the context of that directory.

Your os.chdir is interpreted relative to the current working directory. Your first os.chdir changes the working directory. The system tries to find the second path relative to the first path.
There are several ways to solve this. You can keep track of the current directory and change back to it. Else make the second os.chdir relative to the first directory. (E.g. os.chdir(../../test2/src'). This is slightly ugly. A third option is to make all paths absolute instead of relative.

I suppose the script is not working because you are trying to change the directory using a relative path. This means that when you execute the first os.chdir you change your working directory from the current one to 'Deployment/Work/test1/src' and when you call os.chdir the second time the function tries to change working directory to 'Deployment/Work/test1/src/Deployment/Work/test2/src' that I suppose is not what you want.
To solve this you can either use an absolute path:
os.chdir('/Deployment/Work/test1/src')
or before the first os.chdir you could keep track of your current folder:
current = os.getcwd()
os.chdir('Deployment/Work/test1/src')
...
os.chdir(current)
os.chdir('Deployment/Work/test2/src')

Related

Change Saving-Path - Python

I´m trying to save a file, which I create with the "open" function.
Well I tried nearly everything to change the directory, but nothing works. The file gets always saved in the folder of my file, which I read in before.
file = open(fname[0] + ft, 'w')
file.write("Test")
file.close()
So this is it simple, but what do I have to add, to change the path of creation?
The File Dialog in a individual Function:
global fname
fname = QFileDialog.getOpenFileName(None, 'Please choose your File.',"C:\\Program Files", "Text-Files(*.txt)")
And the File Typ ( in a individual Function too) I set the file type by ticking a check box and ft will set to .py or .pyw
if self.exec_py.isChecked() == True:
global ft
ft = ".py"
I should have mentioned that I already tried os.path.join and os.chdir, but the file will get printed in the file anyway. Any solutions or approaches how to fix it? Here is how i tried it:
tmppath = "C:/temp"
tmp = os.path.join(tmppath,fname[0]+ft)
file = open(tmp, 'w')
Your question is a little short on details, but I am guessing that fname is the tuple returned by QFileDialog, and so fname[0] is the absolute path of the original file. So if you display fname[0], you will see something like this:
>>> fname[0]
'C:\\myfolder\\file.txt'
Now look what happens when you try to use that with os.path.join:
>>> tmppath = 'C:\\temp'
>>> os.path.join(tmppath, fname[0])
'C:\\myfolder\\file.txt'
Nothing! Conclusion: attempting to join two absolute paths will simply return the original path unchanged. What you need to do instead is take the basename of the original path, and join it to the folder where you want to save it:
>>> basename = os.path.basename(fname[0])
>>> basename
'file.txt'
>>> os.path.join(tmppath, basename)
'C:\\tmp\\file.txt'
Now you can use this new path to save your file in the right place.
You need to provide the full filepath
with open(r'C:\entire\path\to\file.txt', 'w') as f:
f.write('test')
If you just provide a file name without a path, it will use the current working directory, which isn't necessarily the directory where the python script your running is located. It will be the directory where you launched the script from.
C:\Users\admin> python C:\path\to\my_script.py
In this instance, the current working directory is C:\Users\admin, not C:\path\to.

Python create folder for each file in a directory

I have a directory with a set of files in it. I'm trying to create a folder for each filename inside the existing directory, and name it the given filename. but i'm getting an I/O error permission denied... what is wrong with this code?
import os
path = "C:/Users/CDGarcia/Desktop"
os.chdir(path)
gribs = os.listdir("testgrib")
print gribs
print os.getcwd()
if not os.path.exists(os.path.basename("gribs")):
os.makedirs(os.path.dirname("gribs"))
with open(path, "w") as f:
f.write("filename")
os.path.dirname() does not do what you expect it to do. It returns the directory name for the path you pass to it. So it interprets whatever string you pass as a path. As such, when you pass a path that has no directory part, it returns an empty string:
>>> os.path.dirname("gribs")
''
So with os.makedirs() you are trying to create an empty directory, which of course will not create the path you are looking for.
Instead, you should just use os.makedirs('gribs') to create gribs folder relative to your current directory.
Furthermore, open(path) will not work when path is the path to the desktop directory. You will have to pass a path to a file there. You probably meant to use a file path relative to the folder you create there:
with open('gribs/something.txt', 'w+') as f:
f.write('example content')

Python - Deleting the last few characters of specific files in a directory

I'm trying to delete the last several characters of multiple files in a specific directory using the rename function. The code I have written using suggestions on this site looks like it should work, but it returns the error message:
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'test1.txt' -> 'test'
And here is my code:
import os
list = os.listdir("C:\\Users\\Jonathan\\Desktop")
for file in list:
if file.startswith("test"):
os.rename(file, file[0:4])
My code shows that for all files beginning with the word "test", delete all characters after it. As I said, to me it looks like it should work, but I am new at Python, and I don't even understand what the error message means.
Are you actually in the folder where you're renaming? If not, the problem is likely that you're looking in the local folder (where you launched the program). Prepend that path to each file name:
import os
cwd = "C:\\Users\\Jonathan\\Desktop"
list = os.listdir(cwd)
for file in list:
if file.startswith("test"):
os.rename(cwd+file, cwd+"test")
As you didn't specify the complete path to your file, it is likely that your program was saving the in your root directory. Also, you should not use list or file as variable names since they shadow two of Python's types.
import os
files_path = "C:\\Users\\Jonathan\\Desktop\\"
lst = os.listdir(files_path)
for file_name in lst:
if file_name.startswith("test"):
os.rename(files_path + file_name, files_path + file_name[:-4])
Try this:
import os
list = os.listdir("C:\\Users\\Jonathan\\Desktop\\")
for file in list:
if file[:4] == "test":
os.renames(list+file, list+file[:4])
And by the way, if you need find the files and rename them recursively(That means will find all directories in that directory). You can use os.walk() like this:
for root, dirs, files in os.walk("C:\\Users\\Jonathan\\Desktop\\"):
for name in files:
if name[:4] == "test":
os.renames(os.path.join(root, name), os.path.join(root, name)[:4])
you need to use os.rename() with existing paths. if your working directory is not the directory containing the file your script will fail. this should work independently of your working directory:
files_path = "C:\\Users\\Jonathan\\Desktop\\"
lst = os.listdir(files_path)
for fle in lst:
if fle.startswith("test"):
os.rename(os.path.join(files_path, fle),
os.path.join(files_path, fle[:4]) )
and avoid using list as a varaible name.

File path in python

I'm trying to load the json file but it gives me an error saying No such file or directory:
with open ('folder1/sub1/sub2/sub2/sub3/file.json') as f:
data = json.load(f)
print data
The above file main.py is kept outside the folder1. All of this is kept under project folder.
So, the directory structure is Project/folder1/sub1/sub2/sub2/sub3/file.json
Where am I going wrong?
I prefer to point pathes starting from file directory
import os
script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, 'relative/path/to/file.json')
with open(file_path, 'r') as fi:
pass
this allows not to care about working directory changes. And also this allows to run script from any directory using it's full path.
python script/inner/script.py
or
python script.py
I would use os.path.join method to form the complete path starting from the current directory.
Something like:
json_filepath = os.path.join('.', 'folder1', 'sub1', 'sub2', 'sub3', 'file.json')
As always, an initial slash indicates that the path starts from the root. Omit the initial slash to indicate that it is a relative path.

Create path and filename from string in Python

Given the following strings:
dir/dir2/dir3/dir3/file.txt
dir/dir2/dir3/file.txt
example/directory/path/file.txt
I am looking to create the correct directories and blank files within those directories.
I imported the os module and I saw that there is a mkdir function, but I am not sure what to do to create the whole path and blank files. Any help would be appreciated. Thank you.
Here is the answer on all your questions (directory creation and blank file creation)
import os
fileList = ["dir/dir2/dir3/dir3/file.txt",
"dir/dir2/dir3/file.txt",
"example/directory/path/file.txt"]
for file in fileList:
dir = os.path.dirname(file)
# create directory if it does not exist
if not os.path.exists(dir):
os.makedirs(dir)
# Create blank file if it does not exist
with open(file, "w"):
pass
First of all, given that try to create directory under a directory that doesn't exist, os.mkdir will raise an error. As such, you need to walk through the paths and check whether each of the subdirectories has or has not been created (and use mkdir as required). Alternative, you can use os.makedirs to handle this iteration for you.
A full path can be split into directory name and filename with os.path.split.
Example:
import os
(dirname, filename) = os.path.split('dir/dir2/dir3/dir3/file.txt')
os.makedirs(dirname)
Given we have a set of dirs we want to create, simply use a for loop to iterate through them. Schematically:
dirlist = ['dir1...', 'dir2...', 'dir3...']
for dir in dirlist:
os.makedirs( ... )

Categories