I have been given a Project on Python Programming so I wanted to ask you that how can I give relative directory paths to the generated files in Python so that it could be opened in other machines as absolute paths won't work on every PC
If you have write access to the folder containing your script then you can use something like
import sys, os
if __name__ == '__main__':
myself = sys.argv[0]
else:
myself = __file__
myself = os.path.abspath(myself)
whereami = os.path.dirname(myself)
print(myself)
print(whereami)
datadir = os.path.join(whereami, 'data')
if not os.path.exists(datadir):
os.mkdir(datadir)
datafile = os.path.join(datadir, 'foo.txt')
with open(datafile, 'w') as f:
f.write('Hello, World!\n')
with open(datafile) as f:
print(f.read())
In the file that has the script, you want to do something like this:
import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')
This will give you the absolute path to the file you're looking for, irrespective of the machine you are running your code on.
You can also refer these links for more information:
Link1
Link2
For more specific information, please make your question specific. i.e Please post the code that you have tried along with your inputs and expected outputs.
Related
I got this code and i need to take the first path of a file and the files name an have put it as a string
from pathlib import Path
from os import walk
import os
from posixpath import dirname
f = []
jhon = r'C:\Users\ioshu\Desktop\you'
for (dirpath, dirnames, filenames) in walk(jhon):
f.extend(filenames)
f.extend(dirnames)
break
Ben1= filenames[:1]
Ben2= dirpath[:2]
dataFolder = Path(r'C:\Users\ioshu\Desktop\you')
print(Ben1 , dataFolder)
print(dataFolder)
The print (ben1, dataFolder)
the output" of that file is
C:\Users\ioshu\Desktop\you ['07a5iya4vfm91-DASH_720.mp4']
The problem is that i need the out put to be like this C:\Users\ioshu\Desktop\you\0q74nqluycm91-DASH_720
Using walk will walk the whole tree, which is overkill for your needs. You can simply
first_file_name = os.listdir('/etc')[0]
if you are sure there are only files, or:
import os
path = '/etc' # any path you want
first_file = None
for i in os.listdir(path):
file_path = os.path.join(path, i)
if os.path.isfile(file_path):
first_file = file_path
break # assuming you don't need to sort the names
Always use os.path.join to join paths, works on Linux, Windows, MacOS and any other supported platform.
PS: Ben1 = filenames[:1] returns a list with one element, not the element. If you need the element then: Ben1 = filenames[0].
PS2: If you want to use pathlib then dataFolder / filenames[0] or something will help.
I am having an issue of trying to load CSV files in a python script when trying to run the file from outside the directory of the script called main.py and the CSV files. (CSV files and main are in the same directory) I think the same issues as this SO post which doesn't appear to contain a solution.
If I run this from terminal:
$ python /home/bbartling/Desktop/Load-Shredder/Load-Shift/main.py
I get some CSV file loading errors [Errno 2] No such file or directory: 'addresses_jci.csv'
But if I run the script in the directory of Load-Shift $ python main.py it works just fine.
How do I fix my script to accommodate this? I added this to the top of my script:
script_dir = os.path.abspath( os.path.dirname( __file__ ) )
print("script directory: ",script_dir)
which prints:
script directory: /home/bbartling/Desktop/Load-Shredder/Load-Shift
But still no luck. Any ideas to try?
Edit
CSV file loading function in main.py
dir_path = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(dir_path, f'log_{dt_string}.log')
script_dir = os.path.abspath( os.path.dirname( __file__ ) )
print("script directory: ",script_dir)
def load_addresses(csv_file):
try:
print(f"Loading csv file: {csv_file}!")
os.path.join(script_dir, f'{csv_file}.csv')
with open(f'{csv_file}', newline='') as f:
reader = csv.reader(f)
data = list(reader)
# flattens list of lists
csv_file = sum(data, [])
print(f"{csv_file} addresses loaded: ",csv_file)
except Exception as error:
print(f"CSV file load error: {error}")
csv_file = [] # errors out
return csv_file
The problem in your code, I think you did not update the csv_file variable update:
csv_file = os.path.join(script_dir, f'{csv_file}.csv')
Though it can be more simpler:
import os
script_path = os.path.dirname(__file__)
filename = 'sample'
file_path = os.path.join(script_path, f'{filename}.csv')
print(file_path)
filepaths in general are a bit confusing in programming languages, so this is a very common problem for beginners.
I typically have a fixed working directory for my projects, and tend to access all files relative to that working directory. If you can implement it, this is the simplest solution.
$ cd /home/bbartling/Desktop/Load-Shredder/Load-Shift/
$ python main.py
can give the desired solution, but depending upon your project this may or may not be feasible. This is by no means a hard-code or a hot fix, and perfectly valid for my projects. However, if you're making a reusable shell script, you probably don't want this.
I've used Path(__file__).parent before to get the directory the file is running in, but IDK how the speed compares to the way you compute it.
I've used this a couple times before V
import os
HERE = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(HERE, 'mkdocs.yml')) as fl:
print(fl.read())
You can change the filename here to your script's path, and that will work. If you know where it will be stored relative to your main.py dir, you can hard-code it. otherwise get it from the command line or console, whichever you prefer. Use the relative path from your main.py directory to your csv here.
This is working! in the function to load a file:
THIS WORKS with specifing object to reference for the os.path.join:
full_csv_path = os.path.join(dir_path, f'{csv_file}')
THIS DOESNT WORK without specifying an object for the program to reference:
os.path.join(dir_path, f'{csv_file}')
Example below that also includes logging:
import csv, os, logging
# datetime object containing current date and time
now = datetime.now()
dt_string = now.strftime("%m_%d_%Y %H_%M_%S")
dir_path = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(dir_path, f'log_{dt_string}.log')
# Logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
file_handler = logging.FileHandler(filename)
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger.addHandler(file_handler)
print("dir_path is: ",dir_path)
def load_addresses(csv_file):
try:
print(f"Loading csv file: {csv_file}!")
full_csv_path = os.path.join(dir_path, f'{csv_file}')
print("full_csv_path: ",full_csv_path)
with open(full_csv_path, newline='') as f:
reader = csv.reader(f)
data = list(reader)
# flattens list of lists
csv_file = sum(data, [])
print(f"{csv_file} addresses loaded: ",csv_file)
except Exception as error:
print(f"CSV file load error: {error}")
csv_file = [] # errors out
return csv_file
You can use pandas , os and fnmatch for this purpose as given below,
import pandas as pd
import os,fnmatch
# change path to the folder from another folder
os.chdir("/path_to_the_folder_having_files_from_another_folder")
# print the current working directory to check if you have arrived
# in the right folder/directory
print(os.getcwd())
# then use fnmatch package to get the CSV files only
# or you can make some other pattern using some prefix or suffix
# like *this.csv or *that.csv
files = fnmatch.filter(os.listdir('.'), '*.csv')
# print the files to check that you have captured the right files
files
# read your files using pandas
# be careful with `sep`, you need to check specifically for your
# files
csv_files = [pd.read_csv(f, low_memory=False,sep = "\t",header=0 for f in files]
Im new to Python so apologies if this is a basic question.
I have successfully created an exe file that writes to my specific desktop directory, but I am struggling to find a way to write to any users desktop directory.
The idea being my exe file can be copied onto any user profile and work the same.
Here is my code:
file = open('C:\\Users\\user\\Desktop\\PC info.txt','w')
Could somebody help me adjust my code to work on any users desktop. Thank you in advance
You can get the username with the os module:
import os
username = os.getlogin() # Fetch username
file = open(f'C:\\Users\\{username}\\Desktop\\PC info.txt','w')
file.write('Hello desktop')
file.close()
You could use os.getlogin with an f-string to insert the username to the file path:
import os
with open(fr'C:\Users\{os.getlogin()}\Desktop\PC info.txt', 'w') as f:
# do something with f
But, a much better cleaner way nowadays would be to use pathlib:
import pathlib
with open(pathlib.Path.home() / "Desktop/PC info.txt", "w"):
# do something with f
Also, it's always advisable to use a context manager (with open(...) as f) to handle files, so that the filehandler gets closed even if an exception occurs.
If you are using Python3.5+, you can use the following to get the path to the current user's home directory:
import os
import sys
from pathlib import Path
def main():
home = str(Path.home())
path = os.path.join(home, "filename.txt")
with open(path, "w") as f:
f.write("HelloWorld")
if __name__ == '__main__':
main()
Is this what you are looking for?
username = "MrShaun"
filename = "C:\\Users\\{0}\\Desktop\\PC info.txt".format(username)
file = open(filename, 'w')
In this example, filename would be: "C:\Users\MrShaun\Desktop\PC info.txt"
Obviously, you would probably want to build a structure around it, for example asking the user for input of a username and assigning that to the variable username.
Read more about formatting strings in Python here
I have some files in the same directory which have the same extension(.html). Those files need to all be copied to another directory. I've looked up documentations on both shutil and os but couldn't find any proper answer...
I have some pseudo codes as below:
import os, shutil
copy file1, file2, file3 in C:\abc
to C:\def
If anyone knows how to solve this, pls let me know. Appreciated!!
Some time ago I created this script for sorting files in a folder. try it.
import glob
import os
#get list of file
orig = glob.glob("G:\\RECOVER\\*")
dest = "G:\\RECOVER_SORTED\\"
count = 0
#recursive function through all the nested folders
def smista(orig,dest):
for f in orig:
#split filename at the last point and take the extension
if f.rfind('.') == -1:
#in this case the file is a folder
smista(glob.glob(f+"\\*"),dest)
else:
#get extension
ext = f[f.rfind('.')+1:]
#if the folder does not exist create it
if not os.path.isdir(dest+ext):
os.makedirs(dest+ext)
global count
os.rename(f,dest+ext+"\\"+str(count)+"."+ext)
count = count+1
#if the destination path does not exist create it
if not os.path.isdir(dest):
os.makedirs(dest)
smista(orig,dest)
input("press close to exit")
[assuming python3, but should be similiar in 2.7]
you can use listdir from os and copy from shutil:
import os, shutil, os.path
for f in listdir("/path/to/source/dir"):
if os.path.splitext(f)[1] == "html":
shutil.copy(f, "/path/to/target/dir")
warning: this is scrapped together without testing. corrections welcome
edit (cause i can't comment):
#ryan9025 splitext is fromos.path, my bad.
I finally got an correct answer by myself with a combinations of all the replies.
So if I have a python script in (a) directory, all the source files in (b) directory, and the destination is in (c) directory.
Below is the correct code that should work, and it looks very neat as well.
import os
import shutil
import glob
src = r"C:/abc"
dest = r"C:/def"
os.chdir(src)
for files in glob.glob("*.html"):
shutil.copy(files, dest)
I am trying to use the listdir function from the os module in python to recover a list of filenames from a particular folder.
here's the code:
import os
def rename_file():
# extract filenames from a folder
#for each filename, rename filename
list_of_files = os.listdir("/home/admin-pc/Downloads/prank/prank")
print (list_of_files)
I am getting the following error:
OSError: [Errno 2] No such file or directory:
it seems to give no trouble in windows, where you start your directory structure from the c drive.
how do i modify the code to work in linux?
The code is correct. There should be some error with the path you provided.
You could open a terminal and enter into the folder first. In the terminal, just key in pwd, then you could get the correct path.
Hope that works.
You could modify your function to exclude that error with check of existence of file/directory:
import os
def rename_file():
# extract filenames from a folder
#for each filename, rename filename
path_to_file = "/home/admin-pc/Downloads/prank/prank"
if os.exists(path_to_file):
list_of_files = os.listdir(path_to_file)
print (list_of_files)