Whats the explanation for this behaviour? - python

from pathlib import Path
file = Path(r"C:\Users\SerT\Desktop\a.txt")
print (file.name)
file.rename(file.with_name("b.txt"))
print (file.name)
i'd like to know why file.name prints out "a.txt" in both instances even though the file actually gets renamed in windows explorer

The file is being renamed, but the original Path object (file in your case) is not changed itself.
Since Path.rename() returns a new Path object, to get the result you're expecting, do:
file = file.rename(file.with_name("b.txt"))
print(file.name)

.rename doesn't modify the file object, instead it simply returns the new filepath. If you want to rename a file, you can set file equal to the file.rename method:
import os
from pathlib import Path
file = Path(r"C:\Users\SerT\Desktop\a.txt")
print (file.name)
file = file.rename(file.with_name("b.txt"))
print(file.name)

Related

Get name of created file

I'm creating files in python and I want to print the full path of the already file created. Example:
dt = datetime.datetime.now()
datetime = dt.strftime("%d-%m")
output = open("c:\path\to\file_"+datetime+".txt","w")
How can I print the final name of the created file?
I tried:
print (output)
but it gives me a rare string.
For real file objects such as that,
print(output.name)
open() method doesn't return anything relevant. You can try on below methods...
1.print(output.__file__)
2. Import os
os.path.abspath("filename.ext"). # it will add the cwd to file name or if iterating the real path
os.path.dirname("filename.ext")
os.path.dirname("filename.ext")
3. Files= os.listdir(os.getcwd()) # it will list the files in cwd(you can give any path)
for i in files:
print(os.path.abspath(i))

Problems while getting absolute path?

I have the following file which I would like to read, as you can see its incomplete:
file = 'dir2/file.hdf5'
However, I would like to get the full path of file (*):
'/home/user/git_hub_repo/dir1/dir2/file.hdf5'
However, when I do:
from pathlib import Path
filename = Path('dir2/file.hdf5').resolve()
print(filename)
I get:
'/home/user/git_hub_repo/dir2/file.hdf5'
Which is wrong because a dir1 is missing in the retrieved path, how can I get (*) path
Note, that in my terminal i am in:
/home/user/git_hub_repo/
If your current directory is
/home/user/git_hub_repo/
and your file is in
/home/user/git_hub_repo/dir1/dir2/file.hdf5
You should change this
file = 'dir2/file.hdf5'
to
file = 'dir1/dir2/file.hdf5'

Renaming file extension using pathlib (python 3)

I am using windows 10 and winpython. I have a file with a .dwt extension (it is a text file). I want to change the extension of this file to .txt.
My code does not throw any errors, but it does not change the extension.
from pathlib import Path
filename = Path("E:\\seaborn_plot\\x.dwt")
print(filename)
filename_replace_ext = filename.with_suffix('.txt')
print(filename_replace_ext)
Expected results are printed out (as shown below) in winpython's ipython window output:
E:\seaborn_plot\x.dwt
E:\seaborn_plot\x.txt
But when I look for a file with a renamed extension, the extension has not been changed, only the original file exists. I suspect windows file permissions.
You have to actually rename the file not just print out the new name.
Use Path.rename()
from pathlib import Path
my_file = Path("E:\\seaborn_plot\\x.dwt")
my_file.rename(my_file.with_suffix('.txt'))
Note: To replace the target if it exists use Path.replace()
Use os.rename()
import os
my_file = 'E:\\seaborn_plot\\x.dwt'
new_ext = '.txt'
# Gets my_file minus the extension
name_without_ext = os.path.splitext(my_file)[0]
os.rename(my_file, name_without_ext + new_ext)
Ref:
os.path.splitext(path)
PurePath.with_suffix(suffix)
From the docs:
Path.rename(target)
Rename this file or directory to the given target. On Unix, if target exists and is a file, it will be replaced silently if the user has permission. target can be either a string or another path object.
pathlib — Object-oriented filesystem paths on docs.python.org
You could use it like this:
from pathlib import Path
filename = Path("E:\\seaborn_plot\\x.dwt")
filename_replace_ext = filename.with_suffix(".txt")
filename.rename(filename_replace_ext)

Copy file to a different location and changing the filename at the same time

I want to copy file to a different location and changing the filename at the same time:
from shutils import copyfile, copy
path = os.path.join(dst, 'file_new_name.xls')
copyfile(src, path) # or
copy(src, path)
I get a FileNotFoundError with path : dst\old_filename\newfilename.
It happens because I try to copy as a different file name.
You should join the directory name of the old file path with the new file name instead:
path = os.path.join(os.path.dirname(dst), 'file_new_name.xls')
I guess the fastest way is to use this right here:
At first you import fs on top of your document with this line
var fs = require('fs');
And than you can use it like this to copy the file to the new Location and also Change the Name at the same time.
fs.createReadStream('FirstLocationFile.txt').pipe(fs.createWriteStream('SecondLocationFile.txt'));
You could of course also add Folder paths into the Strings to decribe if they are or shall be inside a Folder.

Error in converting multiple FASTA files to Nexus using Biopython

I want to convert multiple FASTA format files (DNA sequences) to the NEXUS format using BIO.SeqIO module but I get this error:
Traceback (most recent call last):
File "fasta2nexus.py", line 28, in <module>
print(process(fullpath))
File "fasta2nexus.py", line 23, in process
alphabet=IUPAC.ambiguous_dna)
File "/Library/Python/2.7/site-packages/Bio/SeqIO/__init__.py", line 1003, in convert
with as_handle(in_file, in_mode) as in_handle:
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/Library/Python/2.7/site-packages/Bio/File.py", line 88, in as_handle
with open(handleish, mode, **kwargs) as fp:
IOError: [Errno 2] No such file or directory: 'c'
What am I missing?
Here is my code:
##!/usr/bin/env python
from __future__ import print_function # or just use Python 3!
import fileinput
import os
import re
import sys
from Bio import SeqIO, Nexus
from Bio.Alphabet import IUPAC
test = "/Users/teton/Desktop/test"
files = os.listdir(os.curdir)
def process(filename):
# retuns ("basename", "extension"), so [0] picks "basename"
base = os.path.splitext(filename)[0]
return SeqIO.convert(filename, "fasta",
base + ".nex", "nexus",
alphabet=IUPAC.ambiguous_dna)
for files in os.listdir(test):
for file in files:
fullpath = os.path.join(file)
print(process(fullpath))
This code should solve the majority of problems I can see.
from __future__ import print_function # or just use Python 3!
import fileinput
import os
import re
import sys
from Bio import SeqIO, Nexus
from Bio.Alphabet import IUPAC
test = "/Users/teton/Desktop"
def process(filename):
# retuns ("basename", "extension"), so [0] picks "basename"
base = os.path.splitext(filename)[0]
return SeqIO.convert(filename, "fasta",
base + ".nex", "nexus",
alphabet=IUPAC.ambiguous_dna)
for root, dirs, files in os.walk(test):
for file in files:
fullpath = os.path.join(root, file)
print(process(fullpath))
I changed a few things. First, I ordered your imports (personal thing) and made sure to import IUPAC from Bio.Alphabet so you can actually assign the correct alphabet to your sequences. Next, in your process() function, I added a line to split the extension off the filename, then used the full filename for the first argument, and just the base (without the extension) for naming the Nexus output file. Speaking of which, I assume you'll be using the Nexus module in later code? If not, you should remove it from the imports.
I wasn't sure what the point of the last snippet was, so I didn't include it. In it, though, you appear to be walking the file tree and process()ing each file again, then referencing some undefined variable named count. Instead, just run process() once, and do whatever count refers to within that loop.
You may want to consider adding some logic to your for loop to test that the file returned by os.path.join() actually is a FASTA file. Otherwise, if any other file type is in one of the directories you search and you process() it, all sorts of weird things could happen.
EDIT
OK, based on your new code I have a few suggestions. First, the line
files = os.listdir(os.curdir)
is completely unnecessary, as below the definition of the process() function, you're redefining the files variable. Additionally, the above line would fail, as you are not calling os.curdir(), you are just passing its reference to os.listdir().
The code at the bottom should simply be this:
for file in os.listdir(test):
print(process(file))
for file in files is redundant, and calling os.path.join() with a single argument does nothing.
NameError
You imported SeqIO but are calling seqIO.convert(). Python is case-sensitive. The line should read:
return SeqIO.convert(filename + '.fa', "fasta", filename + '.nex', "nexus", alphabet=IUPAC.ambiguous_dna)
IOError: for files in os.walk(test):
IOError is raised when a file cannot be opened. It often arises because the filename and/ or file path provided does not exist.
os.walk(test) iterates through all subdirectories in the path test. During each iteration, files will be a list of 3 elements. The first element is the path of the directory, the second element is a list of subdirectories in that path, and the third element is a list of files in that path. You should be passing a filename to process(), but you are passing a list in process(files).
You have implemented it correctly in this block for root, dirs, files in os.walk(test):. I suggest you implement it similarly in the for loop below.
You are adding .fa to your filename. Don't add .fa.

Categories

Resources