Python folder paths on synched pcs - python

I use .py files on two different pcs and synch the files using google drive.
As I handle files quite often with subfolders I use the complete path to read csv
passport = pd.read_csv(r'C:\Users\turbo\Google Drive\Studium\Master_thesis\Python\Databases\passport_uzb.csv')
However, when switching pcs I have to change the path manually since for my second pc its:
C:\Users\turbo\My Drive\Studium\Master_thesis\Python\Databases
so the only difference really is 'Google Drive' =/= 'My Drive'
Is there a work around using the complete filepath to read files?

You can use a relative path to access the CSV instead of an absolute one. The pathlib module is useful for this. For example, assuming your script is directly inside the ...Python/Databases folder, you can compute the path to the CSV like so, using the __file__ module attribute:
from pathlib import Path
# this is a path object that always refers to the script in which it is defined
this_file = Path(__file__).resolve()
# this path refers to .../Python/Databases, no matter where it is located
this_folder = this_file.parent
csv_path = this_folder / "passport_uzb.csv"
passport = pd.read_csv(csv_path)
Edit: no matter where your script is located, you can use some combination of .parent and / "child" to construct a relative path that will work. If your script is in ...Python/Databases/nasapower then simply add another .parent:
this_file = Path(__file__).resolve()
nasapower_folder = this_file.parent
databases_folder = nasapower_folder.parent
Or you can use the .parents sequence to get there faster:
databases_folder = Path(__file__).resolve().parents[1]
Likewise, for the output folder:
output_folder = Path(__file__).resolve().parent / "json"

Related

How to use data files of sub-directories and perform iterative operation in python

I have my jupyter notebook (python script) in current directory. In current directory, I have two subfolders, namely a and b. In both directories a and b I have equal number of .dat files with same names. For example, directory a contains files, namely x1-x1-val_1, x1-x1-val_5, x1-x1-val_11...x1-x1-val_86 and x1-x2-val_1, x1-x2-val_5, x1-x2-val_11...x1-x2-val_86, i.e. values are in range(1,90,5). Likewise I have files in directory b.
I want to use my python script to access files in a and b to perform iterative operations on .dat files. My present code works only if I keep files of directory a or b in current directory. For example, my script uses following function.
def get_info(test):
my_dict = {'test':test}
c = []
for i in range(1,90,5):
x_val = 'x_val_'+test+'-val_'+str(i)
y_val = 'y_val_'+test+'-val_'+str(i)
my_dict[x_val],my_dict[y_val]= np.loadtxt(test+'-val_'+str(i)+'.dat'
,usecols= (1,2),unpack=True)
dw = compute_yy(my_dict[x_val],my_dict[y_val],test)
c.append(dw)
my_dict.update({test+'_c'+:np.array(c)})
return my_dict
I call get_info() by using following:
tests = ['x1-x1', 'x1-x2']
new_dict = {}
for i in tests:
new_dict.update({i:get_info(i)})
How can I use my code to access files in either directory a and/or b? I know its about providing correct path, but I am unsure how can I do so. One way I thought is following;
ext = '.dat'
for files in os.listdir(path_to_dir):
if files.endswith(ext):
print(files) # do operations
Alternative could be to make use of os.path.join(). However, I am unable to solve it such that I can use same python script (with minimum changes perhaps) that can use files and iterate on them which are in subfolders a and b. Thanks for your feedback in advance!
If you want to run get_info() on every folder separatelly then you have two methods:
First: described by #medium-dimensional in comment
You can use os.chdir(folder) to change Current Working Directory. And then code will run with files in this folder
You can see current working directory with print( os.getcwd() )
os.chdir("a")
get_info(i)
os.chdir("..") # move back to parent folder
os.chdir("b")
get_info(i)
os.chdir("..") # move back to parent folder
chdir() (similar to command cd in console) can use relative path (r"a") full path (r"C:\full\path\to\a") and .. to move to parent folder (r"a\..\b")
If files can be in nested folders then .. may not go back you can use getcwd()
cwd = os.getcwd()
os.chdir("folder1/folder2/a")
get_info(i)
os.chdir(cwd) # move back to previous folder
os.chdir("folder1/folder2/b")
get_info(i)
os.chdir(cwd) # move back to previous folder
(BTW: in console on Linux you can use cd - to move back to previous folder)
Second: use folder when you open file
Every command which gets filename can also get path with folder\filename (it can be relative path, full path, and path with ..) like
r"a\filename.dat"
r"C:\full\path\to\b\filename.dat"
r"a\..\b\filename.dat"
So you could define function with extra option folder
def get_info(text, folder):
and use this folder when you read file
loadtxt(folder + r'\' + test+'-val_'+str(i)+'.dat', ...)
or more readable with f-string
loadtxt(rf'{folder}\{test}-val_{i}.dat', ...)
And later you run it as
get_info(i, "a")
get_info(i, "b")

How do change the save location of files when file names are being saved based on a list?

How can I customize the save path for the to_csv function below? I have multiple files that are being pulled via Python and the files are being saved as with the date being substituted into the {date} below, but it's saving to where the script is located. How can I change the save location?
df_call.to_csv(f'call_{date}.csv')
df_put.to_csv(f'put_{date}.csv')
You can write path;
windows
df_call.to_csv(f'C:\\Users\\YOURUSERNAME\\Desktop\\call_{date}.csv')
linux
df_put.to_csv(f'~/Desktop/put_{date}.csv')
Have a look at path and pathlib modules in the python standard library. Utilizing these modules, your operations will be more robust and work across different OS.
To save a file to a parent folder, you can do the following:
from pathlib import Path
...
scriptpath = Path(__file__) # e.g. /home/usr/scripts/script.py
parentfolder = scriptpath.parents[1] # /home/usr/
outputdir = parentfolder / 'output' # /home/usr/output
filename = 'output.csv'
outputpath = outputdir / filename # /home/usr/output/output.csv

Is there a way to be able to use a variable path using os

The goal is to run through a half stable and half variable path.
I am trying to run through a path (go to lowest folder which is called Archive) and fill a list with files that have a certain ending. This works quite well for a stable path such as this.
fileInPath='\\server123456789\provider\COUNTRY\CATEGORY\Archive
My code runs through the path (recursive) and lists all files that have a certain ending. This works well. For simplicity I will just print the file name in the following code.
import csv
import os
fileInPath='\\\\server123456789\\provider\\COUNTRY\\CATEGORY\\Archive
fileOutPath=some path
csvSeparator=';'
fileList = []
for subdir, dirs, files in os.walk(fileInPath):
for file in files:
if file[-3:].upper()=='PAR':
print (file)
The problem is that I can manage to have country and category to be variable e.g. by using *
The standard library module pathlib provides a simple way to do this.
Your file list can be obtained with
from pathlib import Path
list(Path("//server123456789/provider/".glob("*/*/Archive/*.PAR"))
Note I'm using / instead of \\ pathlib handles the conversion for you on windows.

How to normalize a relative path using pathlib

I'm trying to use relative paths in Python, and I want to put my csv files in a separate folder from my python code.
My python program is in the following folder:
G:\projects\code
I want to read this file which is one level up:
G:\projects\data\sales.csv
How do I specify a path using pathlib that is one level up from my current working folder? I don't want to change the current working folder.
I tried this:
from pathlib import Path
file = Path.cwd() /'..'/'data'/'sales.csv'
But now the 'file' variable equals this:
'G:/projects/code/../data/sales.csv'
I read through the docs and either it isn't explained there or I'm just missing it.
Although it's not a problem that your path includes '..' (you can still use this path to open files, etc. in Python), you can normalize the path using resolve():
from pathlib import Path
path = Path.cwd() / '..' / 'data' / 'sales.csv'
print(path) # WindowsPath('G:/projects/code/../data/sales.csv')
print(path.resolve()) # WindowsPath('G:/projects/data/sales.csv')
NB: I personally would name a variable that contains a path path, not file. So you could later on do file = open(path).
print(
Path(__file__).parent, # the folder
Path(__file__).parent.parent, # the folder's parent
sep='\n'
)
print(
Path(
Path(__file__).parent.parent, 'hello.py'
)
)
results in
C:\Users\isik\Desktop\Python\MessAround\project\module
C:\Users\isik\Desktop\Python\MessAround\project
C:\Users\isik\Desktop\Python\MessAround\project\hello.py
with this file structure
-project
-module
-__init__.py
-hello.py
-__init__.py
while the code is located inside project.module.__init__.py
Do you mean "read my csv files"?
The import keyword has a different meaning in Python (you import only other Python modules).
In any case, in order to read a file located one folder above your Python file, you can use this:
import os
filePath = os.path.dirname(__file__)+'/../'+fileName
fileDesc = open(filePath)
fileData = fileDesc.read()
fileDesc.close()
...
here is an example I used:
import json
from pathlib import Path
def read_files(folder_name, file_name):
base_path = Path.cwd().joinpath('configs','resources')
path = base_path.joinpath(folder_name,file_name)
open_file = open(path,'r')
return json.load(open_file.read())
This is pretty old, but I happened on it looking for something else.
Oddly you never got a direct, obvious, answer -- you want the parent property:
from pathlib import Path
file = Path.cwd().parent / 'data' / 'sales.csv'
Note that some of the answers that say you want __file__ rather than the current working directory may be correct (depending on your use case), in which case it's:
from pathlib import Path
file = Path(__file__).parent.parent / 'data' / 'sales.csv'
(parent of the python file is the code dir, parent of that is the projects dir.
However, It's not great practice to refer to your data by its relative path to your code -- I think using the cwd is a better option -- though what you should do is pass the path to the data in to the script via sys.argv.

How do I create a string containing the filepath of my python program?

We are creating a python program that executes specific macros within Polyworks based on user input into the program. Right now the code is:
roto.command.CommandExecute('MACRO EXEC("C:\\RotoWorks\\Macros\\CentrifugalCompressor")')
However this assumes that our program is always installed in C:\RotoWorks. Ideally, our app is portable. I'm sure theres a way to retrieve the filepath that Rotoworks is stored in, then just concatenate the rest of the filepath to the end. How do I do this?
You can retrieve the path from the __file__ attribute of the file. Use os.path.abspath on that attribute to retrieve the absolute path of the file and then os.path.dirname to retrieve the containing directory:
import os
file_directory = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(file_directory, other_path) # join directory to an inner path
roto.command.CommandExecute('MACRO EXEC({})'.format(path))
Use os.path.dirname recursively to move out as many directories as you want.

Categories

Resources