Path name format - Windows - Python - python

I am working on a code that takes the path of a file and the reads it.
The code is,
import sys
import os
user_input = input("Enter the path of your file: ")
assert os.path.exists(user_input), "I did not find the file at, "+str(user_input)
However, I am on a Windows machine in which, the path names come with a \, like, C:\your\path\and\file.xlsx
Each time I enter the file name to the prompt, I need to manually replace all \ with / and then run the code.
Is there a solution such that I enter C:\your\path\and\file.xlsx but the code takes it as, C:/your/path/and/file.xlsx
Regards.

Use pythons builtin pathlib like this:
from pathlib import Path
# No matter what slash you use in the input path
# I used Raw-Prefix 'r' here because \t would otherwise be interpreted as tab
path_a = Path(r"C:\Temp\test.txt)
path_b = Path(r"C:\Temp/test.txt)
path_c = Path(r"C:/Temp/test.txt)
path_d = Path(r"C:\\Temp\\test.txt)
print(path_a, path_b, path_c, path_d)
# all Paths will be the same:
# out >> C:\Temp\test.txt C:\Temp\test.txt C:\Temp\test.txt C:\Temp\test.txt
Furthermore you can also easily extend a given Path like this:
path_e = Path("C:\Temp")
extended_path = path_e / "Test"
print(extended_path)
# out >> C:\Temp\Test
So in your case simply do it like this:
import sys
import os
from pathlib import Path
user_input = input("Enter the path of your file: ")
file_path = Path(user_input)
if not os.path.exists(file_input):
print("I did not find the file at, " + str(file_path))

Oddly enough, when I use \ in my path it just worked. But for whatever reason if yours is not, here is a way to change backslash to slash. One with a regex and one using replace:
import sys
import os
import re
user_input = input("Enter the path of your file: ")
#with a regex
user_input_regex = re.sub(r"\\", "/", user_input)
print(user_input_regex)
#using replace
user_input_replace = user_input.replace("\\","/")
print(user_input_replace)
I believe that replace is slightly faster but if you want to change other stuff (or just like using regex) the regex will probably offer more options down the road. The key to this is the \ needs to be escaped with a \ since itself is an escape character.

Related

Python Variable with Asterisk

I need to create a variable with an asterisk.
originalFilePath = "/home/user/reports/file_name_xxxx.pdf"
The file_name will be replaced every day with a numeric value, like - file_name_20221116.pdf. How can I pass "*" - star, in the variable?
So the code would look like this -
originalFilePath = "/home/user/reports/file_name_*.pdf"
Any help would be appreciated.
If you want to create like this,
originalFilePath = "/home/user/reports/file_name_xxxx.pdf"
You have to pass your arguments like the following way.
abc = "xxxx" #abc is a variable name
originalFilePath = f"/home/user/reports/file_name_{abc}.pdf"
I need to create a variable with an asterisk.
I don't think you do.
What you seems to need is to get a list of files by a UNIX-style globbing pattern, so it's a job for glob — Unix style pathname pattern expansion module from stdlib.
import glob
report_pattern = "/home/user/reports/file_name_*.pdf"
reports = glob.glob(report_pattern)
# reports == ['/home/user/reports/file_name_20221116.pdf']
What abouf f-string?
import datetime
timestamp = datetime.datetime.now().date()
originalFilePath = f"/home/user/reports/file_name_{timestamp}.pdf"
You could also search file in a directory like this:
import os
from os import listdir
from os.path import isfile, join
current_path = os.path.dirname(os.path.dirname(__file__))
onlyfiles = [f for f in listdir(current_path) if isfile(join(current_path, f))][0]
originalFilePath = f"/home/user/reports/{onlyfiles}"

How to include a variable in 'r' raw string

I've created a new variable for user path, but not sure how to add in to the following.
import os, pwd
path=os.getcwd()
#crif0 = r '/abc/crif/gpio_mem_0_crif.xml' - original
crif0 = r (path+ '/crif/gpio_mem_0_crif.xml') - I tried with this but doesn't work
As mentioned in the comments, r is a literal prefix which you cannot apply to anything but string literals, so path + r'/crif/...' is enough. However, in this particular case when you need to compose a file path, I'd use the standard library, which makes the code more portable:
import os
path = os.getcwd()
crif0 = os.path.join(path, 'crif', 'gpio_mem_0_crif.xml')
or, in a more modern way using path objects rather than strings:
from pathlib import Path
crif0 = Path.cwd() / 'crif' / 'gpio_mem0_crif.xml'

Read argument with spaces from windows cmd Python

I'm trying to read arguments with spaces in windows cmd.
So here is the code.
from avl_tree import *
import sys,os
if __name__ == '__main__':
avl = AVLTreeMap()
infile = sys.argv[1] + '.txt'
avl._preprocessing(infile)
avl._interface(infile)
I've written it as sys.argv[1] since I'm gonna type in the cmd as following:
python filename.py textfilename
But then if the text file has spaces in the name it won't work like that.
Any suggestions?
Thanks in advance.
This is a very hacky fix, and I wouldn't necessarily suggest it because it will mess with other arguments you might need to add later but you could do something like this:
infile = " ".join(sys.argv[1:]) + '.txt'
So you if you run the program like this:
python filename.py my file name
infile will equal "my file name.txt"

Find and replace a part of several lines in multiple documents using python?

I'm trying to replace parts of several lines in multiple latex documents using python. This is what I've done:
import fileinput, glob, string, sys, os
from os.path import join
def search_rep(path,search,replace):
# replace a string in multiple files
files = glob.glob(path)
for file in files:
if os.path.isfile(file):
for line in file.splitlines(): # or whatever arbitrary loop
if line.find(search) > -1:
print "Replacing" + replace + "on line: %s" % line
line.replace(search, replace)
def main():
path = "/home/stig/test/*.tex"
search = "/home/stig/hfag/oppgave/figs_plots/"
replace = "/home/stig/forskning_linux/oppgave_hf2/figs_plots/"
search_rep(path,search,replace)
if __name__ == "__main__":
sys.exit(main())
But the script doesn't change anything in the files. What's wrong?
Thanks
Stig
Consider using the fileinput module. It's a good fit for this problem. Example:
import fileinput
import glob
import sys
path = "/home/stig/test/*.tex"
search = "/home/stig/hfag/oppgave/figs_plots/"
replace = "/home/stig/forskning_linux/oppgave_hf2/figs_plots/"
for line in fileinput.input(glob.glob(path), inplace=1):
sys.stdout.write(line.replace(search, replace))
See also the inplace and backup parameters, which allow you to do the replacement in place (with the safety of backup in case of a mistake).

Build the full path filename in Python

I need to pass a file path name to a module. How do I build the file path from a directory name, base filename, and a file format string?
The directory may or may not exist at the time of call.
For example:
dir_name='/home/me/dev/my_reports'
base_filename='daily_report'
format = 'pdf'
I need to create a string '/home/me/dev/my_reports/daily_report.pdf'
Concatenating the pieces manually doesn't seem to be a good way. I tried os.path.join:
join(dir_name,base_filename,format)
but it gives
/home/me/dev/my_reports/daily_report/pdf
This works fine:
os.path.join(dir_name, base_filename + '.' + filename_suffix)
Keep in mind that os.path.join() exists only because different operating systems use different path separator characters. It smooths over that difference so cross-platform code doesn't have to be cluttered with special cases for each OS. There is no need to do this for file name "extensions" (see footnote) because they are always preceded by a dot character, on every OS.
If using a function anyway makes you feel better (and you like needlessly complicating your code), you can do this:
os.path.join(dir_name, '.'.join((base_filename, filename_suffix)))
If you prefer to keep your code clean, simply include the dot in the suffix:
suffix = '.pdf'
os.path.join(dir_name, base_filename + suffix)
That approach also happens to be compatible with the suffix conventions in pathlib, which was introduced in python 3.4 a few years after this question was asked. New code that doesn't require backward compatibility can do this:
suffix = '.pdf'
pathlib.PurePath(dir_name, base_filename + suffix)
You might be tempted to use the shorter Path() instead of PurePath() if you're only handling paths for the local OS. I would question that choice, given the cross-platform issues behind the original question.
Warning: Do not use pathlib's with_suffix() for this purpose. That method will corrupt base_filename if it ever contains a dot.
Footnote: Outside of Microsoft operating systems, there is no such thing as a file name "extension". Its presence on Windows comes from MS-DOS and FAT, which borrowed it from CP/M, which has been dead for decades. That dot-plus-three-letters that many of us are accustomed to seeing is just part of the file name on every other modern OS, where it has no built-in meaning.
If you are fortunate enough to be running Python 3.4+, you can use pathlib:
>>> from pathlib import Path
>>> dirname = '/home/reports'
>>> filename = 'daily'
>>> suffix = '.pdf'
>>> Path(dirname, filename).with_suffix(suffix)
PosixPath('/home/reports/daily.pdf')
Um, why not just:
>>> import os
>>> os.path.join(dir_name, base_filename + "." + format)
'/home/me/dev/my_reports/daily_report.pdf'
Is not it better to add the format in the base filename?
dir_name='/home/me/dev/my_reports/'
base_filename='daily_report.pdf'
os.path.join(dir_name, base_filename)
Just use os.path.join to join your path with the filename and extension. Use sys.argv to access arguments passed to the script when executing it:
#!/usr/bin/env python3
# coding: utf-8
# import netCDF4 as nc
import numpy as np
import numpy.ma as ma
import csv as csv
import os.path
import sys
basedir = '/data/reu_data/soil_moisture/'
suffix = 'nc'
def read_fid(filename):
fid = nc.MFDataset(filename,'r')
fid.close()
return fid
def read_var(file, varname):
fid = nc.Dataset(file, 'r')
out = fid.variables[varname][:]
fid.close()
return out
if __name__ == '__main__':
if len(sys.argv) < 2:
print('Please specify a year')
else:
filename = os.path.join(basedir, '.'.join((sys.argv[1], suffix)))
time = read_var(ncf, 'time')
lat = read_var(ncf, 'lat')
lon = read_var(ncf, 'lon')
soil = read_var(ncf, 'soilw')
Simply run the script like:
# on windows-based systems
python script.py year
# on unix-based systems
./script.py year
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATE_PATH = Path.joinpath(BASE_DIR,"templates")
print(TEMPLATE_PATH)
Adding code below for better understanding:
import os
def createfile(name, location, extension):
print(name, extension, location)
#starting creating a file with some dummy contents
path = os.path.join(location, name + '.' + extension)
f = open(path, "a")
f.write("Your contents!! or whatever you want to put inside this file.")
f.close()
print("File creation is successful!!")
def readfile(name, location, extension):
#open and read the file after the appending:
path = os.path.join(location, name + '.' + extension)
f = open(path, "r")
print(f.read())
#pass the parameters here
createfile('test','./','txt')
readfile('test','./','txt')

Categories

Resources