How to handle \2 in the Windows path with Python? - python

I run an external function that returns a Windows path to a file on disk as a string (part of the string:
Error details are at "C:\Users\ADMINI~1\AppData\Local\Temp\2\BuildErrors.txt" Succeeded
So, I load the result returned into a string variable:
s = '''Error details are at "C:\Users\ADMINI~1\AppData\Local\Temp\2\BuildErrors.txt" Succeeded'''
file_path = s.split('"')[1]
print file_path
> C:\Users\ADMINI~1\AppData\Local\Temp\BuildErrors.txt #(with STX icon after Temp
If I access the file_path in the Python Shell, its printed like this:
file_path
'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\x02\\BuildErrors.txt'
I understand that \2 is handled as a special character in Python, but this makes it impossible to for me to read the file as the path is not valid.
As I am getting the string from external function, I already have a string object and as far as I know, you cannot make a raw string (r'') from that.
I've tried s.encode('string-escape') on the source string, but it keeps the \x02 in place.
How do produce a valid path by handling the \2 in it?

So you have a few things going on.
1) You should be using Python 3. Its time.
2) Monik's answer is correct if you just want to switch to unix style path separator characters. Python will let you use unix style paths on a windows system. Just remember that other windows shells and program will not.
3) Here is what is going on. If your string is in a file called fred.txt then
>>> with open('fred.txt') as f:
... derf = f.readline()
...
>>> derf
'Error details are at "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\2\\BuildErrors.txt" Succeeded'
>>> file_path = derf.split('"')[1]
>>> file_path
'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\2\\BuildErrors.txt'
>>> os.path.split(file_path)
('C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\2', 'BuildErrors.txt')
>>>
Then everything seems to work ok. The python shell displays the double slashes because of how it stores strings internally. If you write that value to a file or print it to the screen you get
>>> print(file_path)
C:\Users\ADMINI~1\AppData\Local\Temp\2\BuildErrors.txt
>>>
So now we get to the crux of the problem. The slash character '\' has special meaning in python strings. It is used to tell the system, hey what follows might be different. So I can specify characters that don't appear on my keyboard via hexadecimal or unicode. for example 3 ways to define a pound sign in a string. I recommend reading http://python-reference.readthedocs.io/en/latest/docs/str/escapes.html
>>> a = "#"
>>> b = "\x23"
>>> c = "\u0023"
>>> a
'#'
>>> b
'#'
>>> c
'#'
>>> a == b
True
>>> a == c
True
>>> b == c
True
>>>
So if '\' has a special meaning, how do I tell the system that I really just want a slash? You escape it! '\\' in the python shell just says I want a slash.
>>> s = "\\"
>>> s
'\\'
>>> print(s)
\
>>>

If your string path is 'C:\ABC\xyz.txt'
then the statement, it gives you 'C:\\ABC\\xyz.txt'
To make it a valid path for python file handling, it should be in format of C:/ABC/xyz.txt
So if path = 'C:\\ABC\\xyz.txt'
path = path.replace("\\","/")
and path is in right format.

Related

How to get my path written with back slashes instead of forward slashes?

I hope someone can help as I am stuck, I can't find the answer to this problem anywhere on google.
I need to replace my forward slash path with a backslash path in order for it to work with windows command prompt. Forward slash paths work for local folders, i.e. C:/Users/Lorcan - but not network folders, i.e. //Networkfolder/Storage
I learned that you can't use the backslash in python as it is a special character, so you must use two backslashes. However, this causes my path to have too many backslashes, and command prompt doesn't work.
>>> s = '//Networkfolder/Storage/Myfolder/Myfile'
>>> s2 = s.replace('/','\\')
>>> s2
'\\\\Networkfolder\\Storage\\Myfolder\\Myfile'
In the python shell, backslashes are displayed as \\, but it's really \ in the string. Your code is working fine, the real string is correct, it's being displayed like that.
You can print out your current working directory instead of writing it out:
import os
cwd = str(os.getcwd())
x = cwd.replace("/", "\\")
print(x)
This worked for me, hope it does for you as well!

Why won't pd.read_csv accept a variable name within the file path in windows?

I'm trying to put a variable name into a file path to open a csv using spyder 5, python 3.7.9, in windows. It worked fine on the raspberry pi and also on Ubuntu but I can't figure out the windows file path conventions. Code below
import pandas as pd
#%%
needle_size = '14mm_'
Pressure = '5mb'
test_var = needle_size+Pressure
prelim = pd.read_csv('C:\Users\Edwardtx\Downloads\Tomsstuff\data_pp_kvals\test2\Inner\14mm\'+test_var+'.csv')
I get the error of a red circle with a white cross in the middle on the left of the screen and it says
'EOL while scanning string literal pyflakes E'
What's also weird to me is that normally the text that can be used as a variable turns black between the plus signs as opposed to being green when it's a string. In the example above .csv is black and the rest is green, why?
Furthermore I've tried adding r before the path and ,'rb' after, separately, but to no avail.
The \ in the file path is being mistaken for an escape character. Unfortunately, even raw strings cannot end in a backslash (\) character, as the ending quote would still be escaped. Try defining your path and filename separately, then join them with a format string.
path = r"C:\Users\Edwardtx\Downloads\Tomsstuff\data_pp_kvals\test2\Inner\14mm"
filename = test_var + ".csv"
file_path = r"%s\%s" % (path, filename)
prelim = pd.read_csv(file_path)
Reference: String and Bytes literals
\ is being read as the beginning of an escape sequence. You should use an f-string instead:
prelim = pd.read_csv(f'C:\Users\Edwardtx\Downloads\Tomsstuff\data_pp_kvals\test2\Inner\14mm\{test_var}.csv')
This is of course assuming that you're using Python 3.6+.
You can also change the default \ Windows path delimiter to /:
prelim = pd.read_csv('C:/Users/Edwardtx/Downloads/Tomsstuff/data_pp_kvals/test2/Inner/14mm/' + test_var + '.csv')
This will work just fine, but you have to make sure it's not a raw string.
However, the truly Pythonic answer is to use os.path. For example:
>>> import os.path
>>> test_var = "foo"
>>> base_path = r"C:\Users\Edwardtx\Downloads\Tomsstuff\data_pp_kvals\test2\Inner\14mm"
# note the raw string and lack of trailing \
>>> full_path = os.path.join(base_path, test_var + ".csv")
>>> print(full_path)
'C:\\Users\\Edwardtx\\Downloads\\Tomsstuff\\data_pp_kvals\\test2\\Inner\\14mm\\foo.csv'
os.path.join() joins its arguments with os.path.sep, which is system-dependent.
You could do it the following way using an f-string to read the CSV files
example:
import pandas as pd
#%%
needle_size = '14mm_'
Pressure = '5mb'
test_var = needle_size+Pressure
prelim = pd.read_csv(f'C:\Users\Edwardtx\Downloads\Tomsstuff\data_pp_kvals\test2\Inner\14mm\{test_var}.csv')

"ValueError: embedded null character" when using open()

I am taking python at my college and I am stuck with my current assignment. We are supposed to take 2 files and compare them. I am simply trying to open the files so I can use them but I keep getting the error "ValueError: embedded null character"
file1 = input("Enter the name of the first file: ")
file1_open = open(file1)
file1_content = file1_open.read()
What does this error mean?
It seems that you have problems with characters "\" and "/". If you use them in input - try to change one to another...
Default encoding of files for Python 3.5 is 'utf-8'.
Default encoding of files for Windows tends to be something else.
If you intend to open two text files, you may try this:
import locale
locale.getdefaultlocale()
file1 = input("Enter the name of the first file: ")
file1_open = open(file1, encoding=locale.getdefaultlocale()[1])
file1_content = file1_open.read()
There should be some automatic detection in the standard library.
Otherwise you may create your own:
def guess_encoding(csv_file):
"""guess the encoding of the given file"""
import io
import locale
with io.open(csv_file, "rb") as f:
data = f.read(5)
if data.startswith(b"\xEF\xBB\xBF"): # UTF-8 with a "BOM"
return "utf-8-sig"
elif data.startswith(b"\xFF\xFE") or data.startswith(b"\xFE\xFF"):
return "utf-16"
else: # in Windows, guessing utf-8 doesn't work, so we have to try
try:
with io.open(csv_file, encoding="utf-8") as f:
preview = f.read(222222)
return "utf-8"
except:
return locale.getdefaultlocale()[1]
and then
file1 = input("Enter the name of the first file: ")
file1_open = open(file1, encoding=guess_encoding(file1))
file1_content = file1_open.read()
Try putting r (raw format).
r'D:\python_projects\templates\0.html'
On Windows while specifying the full path of the file name, we should use double backward slash as the seperator and not single backward slash.
For instance, C:\\FileName.txt instead of C:\FileName.txt
I got this error when copying a file to a folder that starts with a number. If you write the folder path with the double \ sign before the number, the problem will be solved.
The first slash of the file path name throws the error.
Need Raw, r
Raw string
FileHandle = open(r'..', encoding='utf8')
FilePath='C://FileName.txt'
FilePath=r'C:/FileName.txt'
The problem is due to bytes data that needs to be decoded.
When you insert a variable into the interpreter, it displays it's repr attribute whereas print() takes the str (which are the same in this scenario) and ignores all unprintable characters such as: \x00, \x01 and replaces them with something else.
A solution is to "decode" file1_content (ignore bytes):
file1_content = ''.join(x for x in file1_content if x.isprintable())
I was also getting the same error with the following code:
with zipfile.ZipFile("C:\local_files\REPORT.zip",mode='w') as z:
z.writestr(data)
It was happening because I was passing the bytestring i.e. data in writestr() method without specifying the name of file i.e. Report.zip where it should be saved.
So I changed my code and it worked.
with zipfile.ZipFile("C:\local_files\REPORT.zip",mode='w') as z:
z.writestr('Report.zip', data)
If you are trying to open a file then you should use the path generated by os, like so:
import os
os.path.join("path","to","the","file")

os.path.isdir() returns False even when folder exists

I'm currently writing a script which has to check if all specified folders actually exist.
I found out I have to use os.path.isdir() with absolute paths.
I have the following directory structure:
X:\
pythonscripts\
files\
Films\
Series\
src\
When I open op my python command line and try if the folders actually exist, I get the following:
>>> import os
>>> os.path.isdir('X:\pythonscripts\src')
True
>>> os.path.isdir('X:\pythonscripts\files')
False
>>> os.path.isdir('X:\pythonscripts\files\Films')
False
>>> os.path.isdir('X:\pythonscripts\files\Series')
False
Which is odd, because when I copy and paste these paths into Windows Explorer, I can access them without problems. I checked permissions and all folders have the same permissions on them. Does anyone know what I'm doing wrong?
Escape backslash (\)
os.path.isdir('X:\\pythonscripts\\src')
or use raw string:
os.path.isdir(r'X:\pythonscripts\src')
without escape, you get wrong path:
>>> '\f'
'\x0c'
>>> print '\f'
>>> print '\\f'
\f
>>> print r'\f'
\f
Rather than use \, you might want to use the os.path.sep so that your code works on other platforms, then you don't have to escape these either.
When you are using
os.path.normpath(your_path)
you get rit of frontslash/backslash problemens. (But it can change the meaning, so just know what you are doing. But for normal paths there is no problem)
https://docs.python.org/3.6/library/os.path.html#os.path.normpath
Works very well :)

Add an extra \ in python winpaths

Using python with windows I'm trying to get my program to see if Dropbox.exe exists if it doesn't nothing will happen if it does then the program will run. I used the print appdata as a debugging feature and this is what it prints: C:\Users\Me\AppData\Roaming
and I think the problem is that it needs to print C:\\Users\\me\\AppData\\Roaming\\ so then I can add the last part as \\Dropbox\\bin\\Dropbox.exe
import winpaths
appdata = winpaths.get_appdata()
print appdata
try:
with open('appdata\Dropbox\bin\Dropbox.exe') as f: pass
except IOError as e:
print 'dropbox cant be found'
First of all, you should use forward slashes for paths as backslashes are used to escape special characters, and forward slashes will work fine, even under windows. Alternatively, use raw strings (r"C:\some\path"). For an example of why you should do this:
>>> print("\path\to\random")
andom o
>>> print("/path/to/random")
/path/to/random
>>> print(r"\path\to\random")
\path\to\random
To do what you want, look at os.path.join() to join the two parts:
>>> import os
>>> os.path.join("/path/to", "some/file")
'/path/to/some/file'
Note that I am using Linux, so this produces a linux-style path, however, under Windows it will adjust accordingly.
So in your case:
with open(os.path.join(appdata, 'Dropbox/bin/Dropbox.exe')) as f:
...
You're likely to encounter bugs due to backslashes escaping characters in your string. Use a raw string to prevent this:
with open(r'appdata\Dropbox\bin\Dropbox.exe') as f:
Also, to add extra bits to pathnames, look at the os.path module, especially os.path.join.
You don't seem to be using the appdata variable in your open:
with open(appdata + r'\Dropbox\bin\Dropbox.exe') as f: pa

Categories