I try to write a script in Python that saves the file in each user directory.
Example for user 1, 2 and 3.
C:\Users\user1\Documents\ArcGIS\file1.gdb
C:\Users\user2\Documents\ArcGIS\file1.gdb
C:\Users\user3\Documents\ArcGIS\file1.gdb
How can I do this?
As one commenter pointed out, the simplest solution is to use the USERPROFILE environment variable to write the file path. This would look something like:
import os
userprofile = os.environ['USERPROFILE']
path = os.path.join(userprofile, 'Documents', 'ArcGIS', 'file1.gdb')
Or even more simply (with better platform-independence, as this will work on Mac OSX/Linux, too; credit to Abhijit's answer below):
import os
path = os.path.join(os.path.expanduser('~'), 'Documents', 'ArcGIS', 'file1.gdb')
Both of the above may have some portability issues across Windows versions, since Microsoft has been known to change the name of the "Documents" folder back and forth from "My Documents".
If you want a Windows-portable way to get the "Documents" folder, see the code here: https://stackoverflow.com/questions/3858851#3859336
In Python you can use os.path.expanduser to get the User's home directory.
>>> import os
>>> os.path.expanduser("~")
This is a platform independent way of determining the user's home directory.
You can then concatenate the result to create your final path
os.path.join(os.path.expanduser("~"), 'Documents', 'ArcGIS', 'file1.gdb')
You want to use the evironment variable HOME, something like this:
import os
homeDir = os.environ["HOMEPATH"]
file = open(homeDir+"Documents\ArcGIS\file1.gdb")
file.write("Hello, World")
file.close()
Notice that I've used HOMEPATH considering you're using Windows, it may be wrong depending on your OS. Take a look at this: http://en.wikipedia.org/wiki/Environment_variable
Related
I want to open a file in the desktop, or anywhere else in the C:/Users/USERNAME/ directory. but I don't know what the code to get the username is.
for example, in batch-file programming I could use:]
c:/Users/%USERNAME%/...
I want to use it in the open function. I have tried both:
open('C:/Users/%%USERNAME/Desktop/data3.txt')
open('C:/Users/%USERNAME%/Desktop/data3.txt')
I know there should be an import that can give the username to my code. But I don't know what it is. And I also would like to know if I can use the username like %USERNAME% or %%USERNAME or a single thing that doesn't need any import.
Three ways to do this using the os module:
Use os.getlogin():
import os
>>> os.path.join("C:", os.sep, "Users", os.getlogin(), "Desktop")
'C:\\Users\\your_username\\Desktop'
Use os.environ():
>>> os.path.join(os.environ['userprofile'], "Desktop")
'C:\\Users\\your_username\\Desktop'
Use os.path.exapndvars():
>>> os.path.join(os.path.expandvars("%userprofile%"), "Desktop")
'C:\\Users\\your_username\\Desktop'
you can use expanduser and ~ for that :
import os
open(os.path.expanduser('~\\Desktop\\data3.txt'))
or if you want to use os.path.join :
open(os.path.join(os.path.expanduser('~'), 'Desktop', 'data3.txt'))
The program is based on the owner we have to return the absolute path of files from the path specified, the path specified can be from any directory. This program has to be done in python using windows.
I think this might be what you are looking for
import os
print(os.getcwd())
This prints out the current working directory, which includes the name of the user which I'm guessing is what you are after.
If you just want the username
import os
os.getlogin()
I'm trying to test a program using Python's pathlib module. With the os module, you used to be able to access networked drives by just following the same url-like form. But for some reason, you can't do this with pathlib. Or at least I can't figure out how to do it.
With the os module, all one would have to do is:
path = os.path.join(r'//server-01', 'directory', 'filename.txt')
But if you try to do this with the pathlib module, one could try something like:
path = Path('//server-01', 'directory', 'filename.txt')
If I'm on a Windows machine, path will resolve to:
>> WindowsPath('/server-01/directory/filename.txt)
And if I were to say path.exists() I will of course get False. Because yes, /server-01 does NOT exist, however //server-01 does exist.
Ideally of course, the result I expect to get when I run path.exists() is True and if I were to display path it would look something like:
>> WindowsPath('//server-01/directory/filename.txt')
Update
It's kind of hacky, but it works I guess, regardless I'd like to know the right way to do it.
In order to get to the network location you can:
os.chdir(join(r'//server-01', 'directory', 'filename.txt'))
path = Path()
path = path.resolve()
The result is something like:
>> WindowsPath('//server-01/directory/filename.txt')
path.exists()
>> True
If anyone knows the better way to do it, let me know.
If you create your path as:
path = Path('//server-01/directory/filename.txt')
instead of comma separating each directory it will work.
The server name by itself is not a valid component of a UNC path. You must also include a share. So path = Path('//server-01/directory', 'file') will work. It should resolve and return True when you run path.exists().
Microsoft docs here: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dfsc/149a3039-98ce-491a-9268-2f5ddef08192
after several attempts, I think you can visit the smb folder/file with pathlib by:
folder = pathlib.Path('//server/')
file = pathlib.Path('//server/') / 'relative/path/to/file'
# or
file = pathlib.Path('//server/relative/path/to/file')
the key is that if you want to visit a smb folder, the arg should end with '/'.
Instantiating path as a PureWindowsPath should do the trick:
path = PureWindowsPath("//server-01", "directory", "file") # '\\\\server-01\\directory\\file'
I'm trying to load a simple text file with an array of numbers into Python. A MWE is
import numpy as np
BASE_FOLDER = 'C:\\path\\'
BASE_NAME = 'DATA.txt'
fname = BASE_FOLDER + BASE_NAME
data = np.loadtxt(fname)
However, this gives an error while running:
OSError: C:\path\DATA.txt not found.
I'm using VSCode, so in the debug window the link to the path is clickable. And, of course, if I click it the file opens normally, so this tells me that the path is correct.
Also, if I do print(fname), VSCode also gives me a valid path.
Is there anything I'm missing?
EDIT
As per your (very helpful for future reference) comments, I've changed my code using the os module and raw strings:
BASE_FOLDER = r'C:\path_to_folder'
BASE_NAME = r'filename_DATA.txt'
fname = os.path.join(BASE_FOLDER, BASE_NAME)
Still results in error.
Second EDIT
I've tried again with another file. Very basic path and filename
BASE_FOLDER = r'Z:\Data\Enzo\Waste_Code'
BASE_NAME = r'run3b.txt'
And again, I get the same error.
If I try an alternative approach,
os.chdir(BASE_FOLDER)
a = os.listdir()
then select the right file,
fname = a[1]
I still get the error when trying to import it. Even though I'm retrieving it directly from listdir.
>> os.path.isfile(a[1])
False
Using the module os you can check the existence of the file within python by running
import os
os.path.isfile(fname)
If it returns False, that means that your file doesn't exist in the specified fname. If it returns True, it should be read by np.loadtxt().
Extra: good practice working with files and paths
When working with files it is advisable to use the amazing functionality built in the Base Library, specifically the module os. Where os.path.join() will take care of the joins no matter the operating system you are using.
fname = os.path.join(BASE_FOLDER, BASE_NAME)
In addition it is advisable to use raw strings by adding an r to the beginning of the string. This will be less tedious when writing paths, as it allows you to copy-paste from the navigation bar. It will be something like BASE_FOLDER = r'C:\path'. Note that you don't need to add the latest '\' as os.path.join takes care of it.
You may not have the full permission to read the downloaded file. Use
sudo chmod -R a+rwx file_name.txt
in the command prompt to give yourself permission to read if you are using Ubuntu.
For me the problem was that I was using the Linux home symbol in the link (~/path/file). Replacing it with the absolute path /home/user/etc_path/file worked like charm.
I have recently begun working on a new computer. All my python files and my data are in the dropbox folder, so having access to the data is not a problem. However, the "user" name on the file has changed. Thus, none of my os.chdir() operations work. Obviously, I can modify all of my scripts using a find and replace, but that won't help if I try using my old computer.
Currently, all the directories called look something like this:
"C:\Users\Old_Username\Dropbox\Path"
and the files I want to access on the new computer look like:
"C:\Users\New_Username\Dropbox\Path"
Is there some sort of try/except I can build into my script so it goes through the various path-name options if the first attempt doesn't work?
Thanks!
Any solution will involve editing your code; so if you are going to edit it anyway - its best to make it generic enough so it works on all platforms.
In the answer to How can I get the Dropbox folder location programmatically in Python? there is a code snippet that you can use if this problem is limited to dropbox.
For a more generic solution, you can use environment variables to figure out the home directory of a user.
On Windows the home directory is location is stored in %UserProfile%, on Linux and OSX it is in $HOME. Luckily Python will take care of all this for you with os.path.expanduser:
import os
home_dir = os.path.expanduser('~')
Using home_dir will ensure that the same path is resolved on all systems.
Thought the file sq.py with these codes(your olds):
C:/Users/Old_Username/Dropbox/Path
for x in range:
#something
def Something():
#something...
C:/Users/Old_Username/Dropbox/Path
Then a new .py file run these codes:
with open("sq.py","r") as f:
for x in f.readlines():
y=x
if re.findall("C:/Users/Old_Username/Dropbox/Path",x) == ['C:/Users/Old_Username/Dropbox/Path']:
x="C:/Users/New_Username/Dropbox/Path"
y=y.replace(y,x)
print (y)
Output is:
C:/Users/New_Username/Dropbox/Path
for x in range:
#something
def Something():
#something...
C:/Users/New_Username/Dropbox/Path
Hope its your solution at least can give you some idea dealing with your problem.
Knowing that eventually I will move or rename my projects or scripts, I always use this code right at the beginning:
import os, inspect
this_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
this_script = inspect.stack()[0][1]
this_script_name = this_script.split('/')[-1]
If you call your script not with the full but a relative path, then this_script will also not contain a full path. this_dir however will always be the full path to the directory.