Using absolute path with os.stat - python

I would like to iterate through a directories file listing and check the permissions of each file. The following code works well for iterating through each file
path = "/home/bob/test"
for i in os.listdir(path):
osstat = oct(os.stat(i).st_mode & 0777)
But the os.stat commands fails as it needs to run against the absolute path.
I know this as if I run the script from /home/bob/test/ it works (as it runs against the working directory)
Should I use:
os.chdir(path)
Or is there a cleaner way (I don't want to get into changing directories back and forth all the time).

Erm...
osstat = oct(os.stat(os.path.join(path, i)).st_mode & 0777)

Related

Regarding file io in Python

I mistakenly, typed the following code:
f = open('\TestFiles\'sample.txt', 'w')
f.write('I just wrote this line')
f.close()
I ran this code and even though I have mistakenly typed the above code, it is however a valid code because the second backslash ignores the single-quote and what I should get, according to my knowledge is a .txt file named "\TestFiles'sample" in my project folder. However when I navigated to the project folder, I could not find a file there.
However, if I do the same thing with a different filename for example. Like,
f = open('sample1.txt', 'w')
f.write('test')
f.close()
I find the 'sample.txt' file created in my folder. Is there a reason for the file to not being created even though the first code was valid according to my knowledge?
Also is there a way to mention a file relative to my project folder rather than mentioning the absolute path to a file? (For example I want to create a file called 'sample.txt' in a folder called 'TestFiles' inside my project folder. So without mentioning the absolute path to TestFiles folder, is there a way to mention the path to TestFiles folder relative to the project folder in Python when opening files?)
I am a beginner in Python and I hope someone could help me.
Thank you.
What you're looking for are relative paths, long story short, if you want to create a file called 'sample.txt' in a folder 'TestFiles' inside your project folder, you can do:
import os
f = open(os.path.join('TestFiles', 'sample1.txt'), 'w')
f.write('test')
f.close()
Or using the more recent pathlib module:
from pathlib import Path
f = open(Path('TestFiles', 'sample1.txt'), 'w')
f.write('test')
f.close()
But you need to keep in mind that it depends on where you started your Python interpreter (which is probably why you're not able to find "\TestFiles'sample" in your project folder, it's created elsewhere), to make sure everything works fine, you can do something like this instead:
from pathlib import Path
sample_path = Path(Path(__file__).parent, 'TestFiles', 'sample1.txt')
with open(sample_path, "w") as f:
f.write('test')
By using a [context manager]{https://book.pythontips.com/en/latest/context_managers.html} you can avoid using f.close()
When you create a file you can specify either an absolute filename or a relative filename.
If you start the file path with '\' (on Win) or '/' it will be an absolute path. So in your first case you specified an absolute path, which is in fact:
from pathlib import Path
Path('\Testfile\'sample.txt').absolute()
WindowsPath("C:/Testfile'sample.txt")
Whenever you run some code in python, the relative paths that will be generate will be composed by your current folder, which is the folder from which you started the python interpreter, which you can check with:
import os
os.getcwd()
and the relative path that you added afterwards, so if you specify:
Path('Testfiles\sample.txt').absolute()
WindowsPath('C:/Users/user/Testfiles/sample.txt')
In general I suggest you use pathlib to handle paths. That makes it safer and cross platform. For example let's say that your scrip is under:
project
src
script.py
testfiles
and you want to store/read a file in project/testfiles. What you can do is get the path for script.py with __file__ and build the path to project/testfiles
from pathlib import Path
src_path = Path(__file__)
testfiles_path = src_path.parent / 'testfiles'
sample_fname = testfiles_path / 'sample.txt'
with sample_fname.open('w') as f:
f.write('yo')
As I am running the first code example in vscode, I'm getting a warning
Anomalous backslash in string: '\T'. String constant might be missing an r prefix.
And when I am running the file, it is also creating a file with the name \TestFiles'sample.txt. And it is being created in the same directory where the .py file is.
now, if your working tree is like this:
project_folder
-testfiles
-sample.txt
-something.py
then you can just say: open("testfiles//hello.txt")
I hope you find it helpful.

What is the pythonic way to get file handles from the command line with relative or absolute paths?

When I write a command line script in python, I'm assuming that it can be invoked from anywhere. This seems to cause incongruity when I want to pass a list of files into the script.
Passing the files using a list or wildcard arguments (whether expanded by bash under *nix or glob.glob with Windows) will return either a relative path or an absolute one, depending on how the file path was described, but this seems to give two different behaviors which have to either be checked or harmonized.
If the script is in the same directory as the files to be imported, this isn't really a problem, but if the script is in a different directory, it seems like you need to grab the absolute path first:
import os,sys,glob
for arg in sys.argv[1:]:
file_list = glob.glob(arg)
for fn in file_list:
print("File Reference: {}".format(os.path.abspath(fn)))
> pwd
/Users/user1/Desktop/script_dir/
> cd ~/Desktop
> script_dir/test.py test_dir/*.csv /Users/user1/Desktop/test_dir/*.txt
File Reference: /Users/user1/Desktop/test_dir/temp1.csv
File Reference: /Users/user1/Desktop/test_dir/temp2.csv
File Reference: /Users/user1/Desktop/test_dir/temp1.txt
File Reference: /Users/user1/Desktop/test_dir/temp2.txt
Assuming the program continued on to do something with the files, it would then manipulate them by absolute path. Is this the correct thing to do here? It seems weirdly klugy, and I can seem to find any references that lay this out.

How to load dependencies and subfolders in Pycharm?

I am so new with python and pycharm and i got confuse!!
When I run my project in pycharm it gives me an error about not finding the path of my file. The physical file path is:
'../Project/BC/RequiredFiles/resources/a_reqs.csv'
My project working directory is "Project/BC" and the project running file (startApp.sh) is there too. but the .py file that wants to work with a_req.csv is inside the "RequiredFiles" folder. There is the following code in the .py file:
reqsfile = os.getcwd() + "/resources/a_reqs.csv"
it returns: '../Project/BC/resources/a_reqs.csv'
instead of: '../Project/BC/resources/RequiredFiles/a_reqs.csv'
while the .py file is in "RequiredFiles" the os.getcwd() must include it too. but it does not.
The problem is that i can not change the addressing code. because this code works in another IDE and other people who work with the code in other platform or OS do not have any problem. I am working in mac OS and if i am not mistaken the code works with windows!!
So, how can i tell Pycharm (in mac) to see and load "RequiredFiles" folder as the subfolder of my working directory!!!
os.getcwd returns the current working directory of the process (which may be the directory where startApp.sh is located or another one, depending on the PyCharm's run configuration setting, or, if you start the program from the command line, the directory in which you execute the command).
To make a path independent on the current working directory, you can take the directory where your Python file is located and build the path from it:
os.path.dirname(__file__) + "/resources/a_reqs.csv"
From your question what I see is:
reqsfile = os.getcwd() + "/resources/a_reqs.csv"
Which produces: "../Project/BC/resources/a_reqs.csv", whereas your desired output is
"../Project/BC/resources/RequiredFiles/a_reqs.csv". Since we know os.getcwd is returning "/Project/BC/", then to get your desired result you should be doing:
reqsfile = os.getcwd() + "/resources/RequiredFiles/a_reqs.csv"
But since you want the solution to work with or without the RequiredFiles subdirectory you could apply a conditional solution, ie something like:
import os.path
if os.path.exists(os.getcwd() + "/resources/RequiredFiles/a_reqs.csv"):
reqsfile = os.getcwd() + "/resources/RequiredFiles/a_reqs.csv"
else:
reqsfile = os.getcwd() + "/resources/a_reqs.csv"
This solution will set the reqsfile to the csv in the RequiredFiles directory if the directory exists, and thus will work for you. On the other-hand, if the RequiredFiles directory doesn't exist, it will default to the csv in /resources/.
Typically when groups collaborate on projects, the maintain the same file hierarchy so that these types of issues are avoided, so you might want to consider moving the csv from /RequiredFiles/ to /resources/.

How to open a specific path with open()?

I'm trying to build a file transfer system with python3 sockets. I have the connection and sending down but my issue right now is that the file being sent has to be in the same directory as the program, and when you receive the file, it just puts the file into the same directory as the program. How can I get a user to input the location of the file to be sent and select the location of the file to be sent to?
I assume you're opening files with:
open("filename","r")
If you do not provide an absolute path, the open function will always default to a relative path. So, if I wanted to open a file such as /mnt/storage/dnd/5th_edition.txt, I would have to use:
open("/mnt/storage/dnd/4p5_edition","r")
And if I wanted to copy this file to /mnt/storage/trash/ I would have to use the absolute path as well:
open("/mnt/storage/trash/4p5_edition","w")
If instead, I decided to use this:
open("mnt/storage/trash/4p5_edition","w")
Then I would get an IOError if there wasn't a directory named mnt with the directories storage/trash in my present folder. If those folders did exist in my present folder, then it would end up in /whatever/the/path/is/to/my/current/directory/mnt/storage/trash/4p5_edition, rather than /mnt/storage/trash/4p5_edition.
since you said that the file will be placed in the same path where the program is, the following code might work
import os
filename = "name.txt"
f = open(os.path.join(os.path.dirname(__file__),filename))
Its pretty simple just get the path from user
subpath = raw_input("File path = ")
print subpath
file=open(subpath+str(file_name),'w+')
file.write(content)
file.close()
I think thats all you need let me know if you need something else.
like you say, the file should be in the same folder of the project so you have to replace it, or to define a function that return the right file path into your open() function, It's a way that you can use to reduce the time of searching a solution to your problem brother.
It should be something like :
import os
filename = "the_full_path_of_the_fil/name.txt"
f = open(os.path.join(os.path.dirname(__file__),filename))
then you can use the value of the f variable as a path to the directory of where the file is in.

Renaming files in Python: No such file or directory

If I try to rename files in a directory, for some reason I get an error.
I think the problem may be that I have not inserted the directory in the proper format ?
Additional info:
python 2 &
linux machine
OSError: [Errno 2] No such file or directory
Though it prints the directories content just fine. What am I doing wrong?
import os
for i in os.listdir("/home/fanna/Videos/strange"):
#print str(i)
os.rename(i, i[:-17])
os.rename() is expecting the full path to the file you want to rename. os.listdir only returns the filenames in the directory. Try this
import os
baseDir = "/home/fanna/Videos/strange/"
for i in os.listdir( baseDir ):
os.rename( baseDir + i, baseDir + i[:-17] )
Suppose there is a file /home/fanna/Videos/strange/name_of_some_video_file.avi, and you're running the script from /home/fanna.
i is name_of_some_video_file.avi (the name of the file, not including the full path to it). So when you run
os.rename(i, i[:-17])
you're saying
os.rename("name_of_some_video_file.avi", "name_of_some_video_file.avi"[:-17])
Python has no idea that these files came from /home/fanna/Videos/strange. It resolves them against the currrent working directory, so it's looking for /home/fanna/name_of_some_video_file.avi.
I'm a little late but the reason it happens is that os.listdir only lists the items inside that directory, but the working directory remains the location where the python script is located.
So to fix the issue add:
os.chdir(your_directory_here)
just before the for loop where your_directory_here is the directory you used for os.listdir.

Categories