Python loop files from a specific filename - python-3.x

For example:
Under the folder, the file list is like:
20110101
20110102
20110103
...
20140101
20140102
...
20171231
How can I start looping those files not from the natural beginning (20110101)
but from a middle one (20140101)?

Well you can get an unsorted list of all the files in the current directory with os.listdir(). So you need to first sort this alphabetically (the default when using the sorted() function), and find the index of that "beginning file" and iterate from there.
So, in code, the above would look something like:
import os
b = '20110101'
fs = sorted(os.listdir())
for f in fs[fs.index(b):]:
...

Related

Issues in numerical sorting of the files in a subfolder

I have written a function for returning the contents of folders which are like this
temp-vts1
.....
temp-vts10
Inside this, we have images, where I want to sort their contents numerically.
Contents--
temp-vts1-0.png
.....
temp-vts1-1000.png
Similarly,
temp-vts2-0.png
temp-vts2-1.png.......
temp-vts2-999.png...
temp-vts2-1000.png...
Similarly for other 8 folders.
paths- it's sorting like this:
\user\...\temp-vts1-0.png
\user\...\temp-vts1-10.png....
but I WANT:- every image in numerical for each folder... How should I sort?
\user\...\temp-vts1-0.png
\user\...\temp-vts1-1.png
\user\...\temp-vts1-2.png
....
\user\...\temp-vts1-1000.png
\user\...\temp-vts2-0.png
\user\...\temp-vts2-1.png
\user\...\temp-vts2-3.png..... rest folders like this.....
Code- where should I update?
paths_frames = []
for folder, subs, files in os.walk(path_data):
for filename in sorted(files):
if filename[-3:].lower() == 'png':
paths_frames.append(os.path.abspath(os.path.join(folder, filename)))
txt = "temp-vts2-1.png"
txt.split("-")
# gives list that can be indexed ['temp', 'vst2', '1.png']
# also read https://docs.python.org/3/library/pathlib.html
# I think the mistake you are making is expecting sorted to sort by the number which are actually text.

Removing \n from a list

so i'm currently learning about mail merging and was issued a challenge on it. The idea is to open a names file, read the name on the current line and then replace it in the letter and save that letter as a new item.
I figured a good idea to do this would be a for loop.
Open file > for loop > append names to list > loop the list and replace ect.
Except when I try to actually append the names to the list, i get this:
['Aang\nZuko\nAppa\nKatara\nSokka\nMomo\nUncle Iroh\nToph']
The code I am using is:
invited_names = []
with open ("./Input/Names/invited_names.txt") as names:
invited_names.append(names.read())
for item in invited_names:
new_names = [str.strip("\n") for str in invited_names]
print(new_names)
Have tried to replace the \n and now .strip but I have not been able to remove the \n. Any ideas?
EDIT: not sure if it helps but the .txt file for the names looks like this:
Aang
Zuko
Appa
Katara
Sokka
Momo
Uncle Iroh
Toph
As you can see, read() only returns a giant string of what you have in your invited_names.txt file. But instead, you can use readlines() which returns a list which contains strings of every line (Thanks to codeflush.dev for the comment). Then use extend() method to add this list to another list invited_names.
Again, you are using for loop and list comprehension at the same time. As a result, you are running the same list comprehension code for many times. So, you can cut off any of them. But I prefer you should keep the list comprehension because it is efficient.
Try this code:
invited_names = []
with open ("./Input/Names/invited_names.txt") as names:
invited_names.extend(names.readlines()) # <--
new_names = [str.strip("\n") for str in invited_names]
print(new_names)

What is the appropriate way to take in files that have a filename with a timestamp in it?

What is the appropriate way to take in files that have a filename with a timestamp in it and read properly?
One way I'm thinking of so far is to take these filenames into one single text file to read all at once.
For example, filenames such as
1573449076_1570501819_file1.txt
1573449076_1570501819_file2.txt
1573449076_1570501819_file3.txt
Go into a file named filenames.txt
Then something like
with open('/Documents/filenames.txt', 'r') as f:
for item in f:
if item.is_file():
file_stat = os.stat(item)
item = item.replace('\n', '')
print("Fetching {}".format(convert_times(file_stat)))
My question is how would I go about this where I can properly read the names in the text file given that they have timestamps in the actual names? Once figuring that out I can convert them.
If you just want to get the timestamps from the file names, assuming that they all use the same naming convention, you can do so like this:
import glob
import os
from datetime import datetime
# Grab all .txt files in the specified directory
files = glob.glob("<path_to_dir>/*.txt")
for file in files:
file = os.path.basename(file)
# Check that it contains an underscore
if not '_' in file:
continue
# Split the file name using the underscore as the delimiter
stamps = file.split('_')
# Convert the epoch to a legible string
start = datetime.fromtimestamp(int(stamps[0])).strftime("%c")
end = datetime.fromtimestamp(int(stamps[1])).strftime("%c")
# Consume the data
print(f"{start} - {end}")
...
You'll want to add some error checking and handling; for instance, if the first or second index in the stamps array isn't a parsable int, this will fail.

how can read files in directory and write to file

I want to write all mp3 files in a file that are in a certain directory.
I used this code
import os
path = 'P:\dn\test55'
wrname = r'P:\dn\path\test55.txt'
test_files = [f for f in os.listdir(path) if f.endswith('.mp3')]
f = open(wrname, "w")
f.write(str(test_files))
f.close()
the file is also written, but it looks like this
['001-file.mp3', '002-file.mp3', '003-file.mp3']
but i want the file to look like this :
001-file.mp3
002-file.mp3
003-file.mp3
How can I change this?
Thanks a lot
the write method writes its input string in the file. You then need pass to write the actual string that you want in your file: the mp3 names separated by the \n character that means "go to line"
f.write("\n".join(test_files))
the join method of strings takes a list as input and then join the elements of the list separated by the string from which you call the method.

Rename files according to list

I'm trying to rename files in a directory using a list. My code so far will only rename the first file before giving me a FileNotFoundError. How can I read the list and rename my files in the same order as it?
import os
import glob
fileLib = ('/filepath1/')
ref = ('/filepath2/ref.csv')
for file in glob.glob(os.path.join(fileLib, '*.csv')):
with open(ref) as list1:
line = list1.read().split(',\n')
for name in line:
os.rename(file, os.path.join(fileLib, '{}.csv'.format(name)))
You're applying the rename to the same file, since the loops are nested.
So the first time it works, and the next time it tries to rename a file that has been already renamed.
Reorganize your code. First, read the new names file:
fileLib = '/filepath1/'
ref = '/filepath2/ref.csv'
with open(ref) as list1:
newnames = list1.read().split(',\n')
then zip directory contents and the new names list together with a single loop:
for file,newname in zip(glob.glob(os.path.join(fileLib, '*.csv')),newnames):
os.rename(file, os.path.join(fileLib, '{}.csv'.format(newname)))
Since zip stops when one of the iterable parameters is exhausted, if the glob result is longer than the new names list, renaming will be done only partially, so it would be better to check that both lists have the same size prior to renamining.

Resources