import os
import random
path = os.listdir(r"file path here")
list = [os.listdir(r"life path here")]
print(len(path))
for i in range(len(path)):
full_path = (r"file path here" + path[i])
print(full_path)
print_random_items = random.randint(0, len(path[i]))
print(print_random_items)
So Hi I would like to know how I can print the name of the file associated with the value return to print(print_random_items)
ex: If the value is 15 I would like to print the 15th files name
First time asking a question here sorry if the format is wrong.
Don't bother with the random numbers. Just use random.choice:
random.choice(paths)
For example:
>>> import random
>>> paths = os.listdir('./exampledir')
>>> paths
['a.txt', 'b.txt', 'c.txt', 'd.txt', 'e.txt', 'f.txt']
>>> random.choice(paths)
'e.txt'
>>> random.choice(paths)
'c.txt'
Note: I see in your code that you are not familiar with python style iteration.
This
for i in range(len(path)):
full_path = (r"file path here" + path[i])
print(full_path)
is better written as
for partial_path in path:
full_path = r"file path here" + partial_path
print(full_path)
So rather than using range(len(path)) to get an index you can just iterate over path directly.
Related
i want to build a function that convert names from csv to a document in word by docx library and i want to create an empty file with os.makedirs(), the file is created but i cant get its path to later join path with word document to save the document in that file
here is my code:
import docx
import pandas as pd
from datetime import datetime
import os
from docx2pdf import convert
from pathlib import Path
def auto_fill(x,y):
database=pd.read_csv(x)
df=pd.DataFrame(database)
df=df.dropna(axis=0)
targeted_doc=docx.Document(y)
date = datetime.date(datetime.now())
strdate = date.strftime("%m-%d-%Y")
path = strdate
newfile = os.makedirs(path)
newfile_path = path(newfile)
for i in range(len(df.Name)+1):
for n in range (len(targeted_doc.paragraphs)+1):
if targeted_doc.paragraphs[n].text=="Name of trainee":
name=targeted_doc.paragraphs[n].runs[0].text=df.at[i,'Name']
for m in range(len(targeted_doc.paragraphs) + 1):
if targeted_doc.paragraphs[m].text == "tissue date":
date = targeted_doc.paragraphs[n].runs[0].text = strdate
for l in range(len(targeted_doc.paragraphs) + 1):
if targeted_doc.paragraphs[n].text == "tserial number":
sr_num = targeted_doc.paragraphs[l].runs[0].text = df.at[i, 'serial number']
name_of_file = (f"{df.at[i, 'Name']}.docx")
outputdoc=targeted_doc.save(name_of_file)
path_of_document=path(outputdoc)
completesave = os.path.join(path_of_document, name_of_file)
convert(path_of_document,newfile_path+f"{name_of_file}.pdf")
auto_fill("database.csv","01.docx")
If I'm understanding what you're trying to accomplish, then just use the path variable you made earlier. Since you used os.makedirs(path), then the path to that would just be the path object.
If you don't change the location, you can use the same path. If you change the location, you can get the path from your script using os.getcwd() and join it wiht the path using os.path.join()
You can store the result of os.path.join(os.getcwd(), path) to a variable and use it later. You can compose that absolute path before creating the file, so you'll have the entire path
i trying to add a path to list but removing the double backslash from each item in the list but i couldn't make this happened.
code :
import os
import shutil
sorc = r'D:\Try\Sorc'
dest = r'D:\Try\Dest'
#variables for sorc
folder_in_sorc = []
files_in_sorc = []
#variables for dest
folder_in_dest = []
files_in_dest = []
for root_sorc, dirs_sorc, files_sorc in os.walk(sorc):
for folder in dirs_sorc:
folder_in_sorc.append(os.path.join(os.path.abspath(root_sorc), folder))
for root_dest, dirs_dest, files_dest in os.walk(dest):
for folder in dirs_dest:
files_in_dest.append(os.path.join(root_dest, folder))
print(folder_in_sorc)
Try using forward slashes (I know you are using windows) , they work for me so try it once i guess. Good Luck :)
import os
import shutil
sorc = 'D:/Try/Sorc'
dest = 'D:/Try/Dest'
#variables for sorc
folder_in_sorc = []
files_in_sorc = []
#variables for dest
folder_in_dest = []
files_in_dest = []
for root_sorc, dirs_sorc, files_sorc in os.walk(sorc):
for folder in dirs_sorc:
folder_in_sorc.append(os.path.join(os.path.abspath(root_sorc), folder))
for root_dest, dirs_dest, files_dest in os.walk(dest):
for folder in dirs_dest:
files_in_dest.append(os.path.join(root_dest, folder))
print(folder_in_sorc)
You are printing a list, so Python prints out the internal representation of the list because it is not 1:1 convertible to a string.
Since backslashes are escape character in Python, they need to be escaped itself.
To solve your issue, print each element in your list to get the real string:
import os
import shutil
sorc = r'C:\temp'
dest = r'C:\temp2'
...
for folder in folder_in_sorc:
print(folder)
Out:
C:\temp\In
C:\temp\libui
C:\temp\pugi
C:\temp\py2exe-0.6.9
C:\temp\pylibui
C:\temp\pyNuklear
C:\temp\python-exe-unpacker
C:\temp\python-qt5
C:\temp\libui\.git
What would be the best way to change a single directory name (only the first occurence) within a path?
Example:
source_path = "/path/to/a/directory/or/file.txt"
target_path = "/path/to/different/directory/or/file.txt"
I this case, the instruction would be: "replace the first directory of the name 'a' with a directory of the name 'different'"
I can think of methods where I would split up the path in its single parts first, then find the first "a", replace it and join it again. But I wonder if there is a more elegant way to deal with this. Maybe a built-in python function.
There is a function called os.path.split that can split a path into the final part and all leading up to it but that's the closest your going to get. Therefore the most elegant thing we can do is create a function that calls that continuously:
import os, sys
def splitall(path):
allparts = []
while 1:
parts = os.path.split(path)
if parts[0] == path: # sentinel for absolute paths
allparts.insert(0, parts[0])
break
elif parts[1] == path: # sentinel for relative paths
allparts.insert(0, parts[1])
break
else:
path = parts[0]
allparts.insert(0, parts[1])
return allparts
Then you could use it like this, joining back together with os.path.join:
>>> source_path = '/path/to/a/directory/or/file'
>>> temp = splitall(source_path)
>>> temp
['path', 'to', 'a', 'directory', 'or', 'file']
>>> temp[2] = 'different'
>>> target_path = os.path.join(*temp)
>>> target_path
'path/to/different/directory/or/file'
If I understand what you want to say, you want this:
source_path = "/path/to/a/directory/or/file.txt"
target_path = source_path.replace("/a/", "/different/", 1)
print target_path
Use https://docs.python.org/3/library/pathlib.html#module-pathlib:
>>> from pathlib import PurePath
>>> import os
>>> path = PurePath("/path/to/a/directory/or/file.txt")
>>> path.parts
('/', 'path', 'to', 'a', 'directory', 'or', 'file.txt')
>>> a_idx = -1
>>> for idx,part in enumerate(path.parts):
... if part == 'a':
... a_idx = idx
... break
...
>>> a_idx
3
>>> pre_path = os.path.join(*path.parts[:a_idx])
>>> post_path = os.path.join(*path.parts[a_idx+1:])
>>> new_path = os.path.join(pre_path, 'different', post_path)
>>> new_path
'/path/to/different/directory/or/file.txt'
In case you don't know the name of the directory, but only its index:
from pathlib import Path
source_path = Path("/path/to/a/directory/or/file.txt")
unknown_name = source.parts[3] # position including root
target_path = "/".join([part if part != unknown_name else "different" for part in source.parts])[1:]
In case you know the name of the directory but not its index, almost the same:
from pathlib import Path
source = Path("/path/to/a/directory/or/file.txt")
src_parts = source.parts
unknown_index = src_parts.index('a')
target_path = "/".join([src_parts[part] if part != unknown_index else "different" for part in range(len(src_parts))])[1:]
I'm new to Python and I need a program that copies files from the same day into a new folder.
Example files:
20120807_first_day_pic.jpg
20120807_first_day_sheet.jpg
20120807_first_day_sheet2.jpg
20120907_second_day_pic.jpg
20120907_second_day_sheet.jpg
20120907_second_day_sheet2.jpg
This is what I have so far, but every file gets a folder and not the whole day.
import os, re, shutil
tfolder = 'D:/Testing/src/'
os.chdir(tfolder)
re_year19xxxxxx = re.compile('(19[0-9][0-9][0-9][0-9])')
re_year20xxxxxx = re.compile('(20[0-9][0-9][0-9][0-9])')
re_ed = re.compile('(ED[0-9])')
destPath = 'D:/Testing/Dest/'
def analyse_file_name(fname):
filePath, coords = os.path.split(fname) #the new folders will be named according to the first 4 characters of the original file name
coordsFolder = coords[:53]
coordsFname = coords[:53]
coordsExt = os.path.splitext(fname)
year = 'year' #create variable year
ed = 'ed' #create variable ed to store the edition number if necessary
bname = fname #the original file name
for re_year in (re_year19xxxxxx, re_year20xxxxxx):
rx = re_year.search(fname) #search for regex in the file name and store it in rx
if rx:
year = rx.group(1) #if the regex is found, store the year
bname.replace(year, ' ')
res = re_ed.search(fname)
if res:
ed = res.group(1)
bname.replace(ed, ' ')
os.chdir(destPath)
if year is 'year':
fname2 = os.path.join(destPath, coordsFolder) + '\\' + coordsFname + coordsExt[1]
else:
fname2 = os.path.join(destPath, coordsFolder,year,ed) + '\\' + coordsFname + coordsExt[1]
print('%s -> %s' % (fname, fname2)) #debug print
dirn, _ = os.path.split(fname2)
if not os.path.exists(dirn):
os.makedirs(dirn)
shutil.copy(fname, fname2)
for root, dirs, files in os.walk(tfolder):
for name in files:
fn = os.path.join(root, name)
analyse_file_name(fn)
If you just want to copy files that start with a known date string format, how about something like this?
def copyfile(filepath, target_dir):
p, filename = os.path.split(filepath)
# get date component of name
date_component = filename.split("_", 1)[0]
# try to parse out the date
try:
d = datetime.datetime.strptime(date_component, "%Y%m%d")
except ValueError:
print "Could not place: ", filename
return
target_date_dir = os.path.join(target_dir, str(d.year), str(d.month), str(d.day))
os.makedirs(target_date_dir)
shutil.copy(filepath, target_date_dir)
First, create a dict (a defaultdict was even more convenient here) that will gather the files for a date (it's good to use re, but given the names of your files using split was easier):
>>> import os
>>> import re
>>> pat = r'(\d+)(?:_\d+)?_(\w+?)[\._].*'
>>> from collections import defaultdict
>>> dict_date = defaultdict(lambda : defaultdict(list))
>>> for fil in os.listdir(path):
if os.path.isfile(os.path.join(path, fil)):
date, animal = re.match(pat, fil).groups()
dict_date[date][animal].append(fil)
>>> dict_date['20120807']
defaultdict(<type 'list'>, {'first': ['20120807_first_day_pic.jpg', '20120807_first_day_sheet.jpg', '20120807_first_day_sheet2.jpg']})
Then for each date, create a subfolder and copy the corresponding files there:
>>> from shutil import copyfile
>>> for date in dict_date:
for animal in dict_date[date]:
try:
os.makedirs(os.path.join(path, date, animal))
except os.error:
pass
for fil in dict_date[date][animal]:
copyfile(os.path.join(path, fil), os.path.join(path, date, animal, fil))
EDIT: took into account OP's new requirements, and Khalid's remark.
Regex day :)
What about trying to match the filename with
pattern=r'(?P<filedate>(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2}))\_(?P<bloodyrestofname>.*)'
Complete date, year, etc. may be retrieved from the respective named groups in the match.
import os, shutil
src_path = "D:\\Testing\\Src\\"
dest_path = "D:\\Testing\\Dest\\"
for file in os.listdir(src_path):
if not os.path.isdir(dest_path + file.split("-")[0]):
os.mkdir(dest_path + file.split("-")[0])
shutil.copy(src_path + file, dest_path + file.split("-")[0])
I can't figure out what's wrong. I've used rename before without any problems, and can't find a solution in other similar questions.
import os
import random
directory = "C:\\whatever"
string = ""
alphabet = "abcdefghijklmnopqrstuvwxyz"
listDir = os.listdir(directory)
for item in listDir:
path = os.path.join(directory, item)
for x in random.sample(alphabet, random.randint(5,15)):
string += x
string += path[-4:] #adds file extension
os.rename(path, string)
string= ""
There are a few strange things in your code. For example, your source to the file is the full path but your destination to rename is just a filename, so files will appear in whatever the working directory is - which is probably not what you wanted.
You have no protection from two randomly generated filenames being the same, so you could destroy some of your data this way.
Try this out, which should help you identify any problems. This will only rename files, and skip subdirectories.
import os
import random
import string
directory = "C:\\whatever"
alphabet = string.ascii_lowercase
for item in os.listdir(directory):
old_fn = os.path.join(directory, item)
new_fn = ''.join(random.sample(alphabet, random.randint(5,15)))
new_fn += os.path.splitext(old_fn)[1] #adds file extension
if os.path.isfile(old_fn) and not os.path.exists(new_fn):
os.rename(path, os.path.join(directory, new_fn))
else:
print 'error renaming {} -> {}'.format(old_fn, new_fn)
If you want to save back to the same directory you will need to add a path to your 'string' variable. Currently it is just creating a filename and os.rename requires a path.
for item in listDir:
path = os.path.join(directory, item)
for x in random.sample(alphabet, random.randint(5,15)):
string += x
string += path[-4:] #adds file extension
string = os.path.join(directory,string)
os.rename(path, string)
string= ""