im getting a weird error using this code (part of a class):
from sys import path as workingDIR
from os import system, path
image = '' # some jpeg image data
keep = 0
DIR = workingDIR[0] + '\\image'
if path.isfile(DIR + '.jpeg'): # adding numbers to end of file name like how windows prevents multiple files having the same name
x = 2
while path.isfile(DIR + ' (' + str(x) + ').jpeg'):
x += 1
DIR += ' (' + str(x) + ')'
DIR += '.jpeg'
f = open(DIR, 'w+b')
f.write(image)
f.close()
system(DIR)
system('pause')
if not(keep):
remove(DIR)
cmd is telling me '...\image' is not recognized as an internal or external command, operable program or batch file. (ignore the ...), which doesnt make sense, because DIR has already been changed to ...\image.jpeg and yet it is getting image. what am i doing wrong here?
You have an extra white space in the image filename - "..\image (1).jpeg"
so when you call system(DIR), "..\image" becomes the command and "(1).jpeg" is the first argument.
Related
I am working on a program in Arcgis however, I have a python issue.
While trying to run the following script I am getting an invalid MXD error which seems to suggest that it cannot find the location of my MXD file.
# modified by ESRI for use as a toolbox script tool
## imported sys to get the raw inputs and os to use for path separator
import arcpy, sys, os
# Set OverWrite if files already exist
arcpy.OverWriteOutput = 1
print "Enter folder path:"
mapDoc = raw_input()
#mapDoc = sys.argv[1]
print os.path.dirname(mapDoc)
# set a variable to the full path and file name of the MXD
fullnam = os.path.basename(mapDoc)
# Strip off the MXD file extension and store as string variable for use in the 'out_pdf'
nam = fullnam.strip(".mxd")
print nam
# Commented this out, since it doesnt need to be a parameter when you use the MXD name as the PDF name
##print "Enter save as name:"
##mapName = sys.argv[2]
map = arcpy.mapping
mxd = map.MapDocument(mapDoc)
map_document = mxd
#out_pdf = r"K:\projects" + "\\" + mapName + ".pdf"
#out_pdf = r"K:\projects" + os.sep + mapName + ".pdf"
#out_pdf = os.path.dirname(mapDoc) + os.sep + mapName + ".pdf"
out_pdf = os.path.dirname(mapDoc) + os.sep + nam + ".pdf"
# Set all the parameters as variables here:
data_frame = 'PAGE_LAYOUT'
resolution = "300"
image_quality = "NORMAL"
colorspace = "RGB"
compress_vectors = "True"
image_compression = "DEFLATE"
picture_symbol = 'RASTERIZE_BITMAP'
convert_markers = "False"
embed_fonts = "True"
layers_attributes = "NONE"
georef_info = "False"
# Due to a known issue, the df_export_width and df_export_height must be set to integers in the code:
map.ExportToPDF(map_document, out_pdf, data_frame, 640, 480, resolution, image_quality, colorspace, compress_vectors, image_compression, picture_symbol, convert_markers, embed_fonts, layers_attributes, georef_info)
# This gives feedback in the script tool dialog:
arcpy.GetMessages()
Now please look at the command prompt.
(arcgispro-py3) C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3>"C:\Us
ers\ant\Documents\MyCensus_Files\Python script\Export2PDF.py"
Enter folder path:
C:\Users\ant\Documents\MyCensus_Files\Python script
C:\Users\ant\Documents\MyCensus_Files
Python script
Traceback (most recent call last):
File "C:\Users\ant\Documents\MyCensus_Files\Python script\Export2PDF.py
", line 22, in <module>
mxd = map.MapDocument(mapDoc)
File "C:\Program Files (x86)\ArcGIS\Desktop10.6\ArcPy\arcpy\arcobjects\mixins.
py", line 651, in __init__
assert (os.path.isfile(mxd) or (mxd.lower() == "current")), gp.getIDMessage(
89004, "Invalid MXD filename")
AssertionError: Invalid MXD filename.
As you can see, the path I enter is different from what is being returned by print and I think that is what's causing my issue. Would appreciate it anyone could assist fixing handling this path error or with a python script that accomplishes converting MXD to PDF.
Regards
If you print out mapDoc right before the line map.MapDocument(mapDoc), you would see that you're trying to pass C:\Users\ant\Documents\MyCensus_Files\Python script as a mxd file. That's a directory, not a mxd file.
Try this:
import arcpy, sys, os
arcpy.OverWriteOutput = 1
mapDoc = os.path.join("C:/", "Users", "ant", "Documents", "MyCensus_Files", "Python_script", "test.mxd")
map = arcpy.mapping
mxd = map.MapDocument(mapDoc)
# ...
Looking at other people with a similar issue, it's usually that they only have a relative path, which is no the case, I'm using the full path which I'm getting with os.join().
This is my code:
def reencode(file):
global DEFAULT_GFORMAT
global DEFAULT_VCODEC
global DEFAULT_ACODEC
global containerformat
global input
filename = os.path.join(input, file)
Container = 0
Video = 0
Audio = 0
if changeContainer: # The container needs to be changed
Container = DEFAULT_GFORMAT
else: # Container is already fine
Container = "copy"
if reencodeVideo: # Video codec needs to be changed
Video = DEFAULT_VCODEC
else: # Video codec is already fine
Video = "copy"
if reencodeAudio: # Audio codec needs to be changed
Audio = DEFAULT_ACODEC
else: # Audio codec is already fine
Audio = "copy"
if(Container == "copy" and Video == "copy" and Audio == "copy"):
print("{}: File is playable by the fire tv stick".format(file))
print()
else: # File needs to be reencoded
name = os.path.splitext(file)[0] # This removes the file extension from the name
if(containerformat == "MPEG-4"): # We only need to check for mp4 since if it's not mp4 it's either mkv or it's gonna be reencoded to mkv
newName = name + ".mp4" # This is the new name for the output file
else:
newName = name + ".mkv" # This is the new name for the output file
print("Reencoding file...")
filename2 = shlex.quote(filename)
print(filename2)
os.rename(filename2, (filename + ".bak")) # File needs to be renamed so it's not overwritten
x = (input) + ".bak"
y = shlex.quote(x)
z = shlex.quote(newName)
command = "ffmpeg -loglevel error -stats -i " + y + " -map 0 -scodec copy -vcodec " + Video + " -acodec " + Audio + " " + z
try:
subprocess.call(command, shell=True) # Run the command
except OSError as e: # Some error happened
if e.errno == os.errno.ENOENT: # ffmpeg is not installed
print("ffmpeg does not seem to be installed. Please install it if you want to run this script")
else: # Something else went wrong
raise
print() # Just to make it look a little nicer
The error happens here:
os.rename(filename2, (filename + ".bak"))
The full error message is this:
line 153, in reencode
os.rename(filename2, (filename + ".bak")) # File needs to be renamed so it's not overwritten
FileNotFoundError: [Errno 2] No such file or directory: "'/home/robert/Filme/sex school.mkv'" -> '/home/robert/Filme/sex school.mkv.bak'
As you can see, the path '/home/robert/Filme/sex school.mkv' is the full path, not just a relative one. When I try something like
mpv '/home/robert/Filme/sex school.mkv'
on the command line, the file plays without issue, so the path is definitely correct. Why am I still getting this error though?
You don't need the shell extension quoting, because you are not renaming via the shell.
Ergo, remove this line:
filename2 = shlex.quote(filename)
And just use:
os.rename(filename, filename + ".bak")
Now, enjoy your sex school video.
I'm new here so bare in mind that and I hope my questions are clearly asked for you lot to help me out. I am trying to alter Brent Tylers Dropbox script so that I will be able to list Python under Python, Mel under Mel and so on(eventually plugins and other files too but not for now)
Ok so my directory is like so:
1.
sf=C:/users/scripts/ a.py + b.mel
pf=C:/users/scripts/Python/c.py
mf=C:/users/scripts/Mel/d.mel
(These are the folders my scripts will be placed in)
Code :
absoluteFiles = []
relativeFiles = []
folders = []
allFiles = []
currentFile = ''
for root, dirs, files in os.walk(sf):
for x in files:
correct = root.replace('\\', '/')
currentFile = (correct + '/' + x)
allFiles.append(currentFile)
if currentFile.endswith('.mel'):
relativeFiles.append(currentFile.replace((mf + '/'), ""))
if currentFile.endswith('.py'):
relativeFiles.append(currentFile.replace((pf + '/'), ""))
relativeFiles.sort()
for relativeFile in relativeFiles:
split = relativeFile.split('/')
fileName = split[-1].split('.')
i=0
while i<(len(split)):
### Create Folders ###
if i==0 and len(split) != 1:
if cmds.menu(split[i] ,ex=1) == 0:
cmds.menuItem(split[i], p=PadraigsTools, bld=1, sm=1, to=1, l=split[i])
if i > 0 and i < (len(split)-1):
if cmds.menu(split[i] ,ex=1) == 0:
cmds.menuItem(split[i], p=split[i-1], bld=1, sm=1, to=1, l=split[i])
### Create .mel Files ###
if fileName[-1] == 'mel':
if i==len(split)-1 and len(split) > 1:
scriptName = split[-1].split('.')
temp1 = 'source ' + '"' + sf + '/' + relativeFile + '"; ' + scriptName[0]
command = '''mel.eval(''' + "'" + temp1 + '''')'''
cmds.menuItem(split[i], p=split[i-1], c=command, l=split[i])
if i==len(split)-1 and len(split) == 1:
scriptName = split[-1].split('.')
temp1 = 'source ' + '"' + sf + '/' + relativeFile + '"; ' + scriptName[0]
command = '''mel.eval(''' + "'" + temp1 + '''')'''
cmds.menuItem(split[i], p=Mel, c=command, l=split[i])
### Create .py Files ###
if fileName[-1] == 'py':
if i==len(split)-1 and len(split) > 1:
command = 'import ' + fileName[0] + '\n' + fileName[0] + '.' + fileName[0]+ '()'
cmds.menuItem(split[i], p=split[i-1], c=command, l=split[i])
if i==len(split)-1 and len(split) == 1:
command = 'import ' + fileName[0] + '\n' + fileName[0] + '.' + fileName[0]+ '()'
cmds.menuItem(split[i], p=Python, c=command, l=split[i])
i+=1
So far I can print out individually (sf, pf, mf) to the corresponding Directory but I cant list out everything at once and the files under sf will not show at all. regarding the folders created it ends up very odd. sometimes i would get a duplicate folder as a submenu and if i use sf it give me C:/.
After days and hours of research trying to mend this script I have found no answer including
from itertools import chain
paths = (mf, sf, pf)
for path, dirs, files in chain.from_iterable(os.walk(path) for path in paths):
::QUESTION::
Is there a way i can put this together sanely so that new folders will show up with their contents on refresh as a submenu and the files will show up and allow me to execute them from their corresponding submenu.
I would appreciate any help possible including down votes haha. And bare in mind I don't want you to hand me the answer on a golden spoon because I wont know what is corrected or needs to be :)
Thanks Greatly
-- Padraig
There's a couple of things you can do to simplify things a bit.
First, it's a good idea to make this as data-driven as possible so you don't have to re-write it if your needs change. This does more or less what you do, but collects the results into a dictionary where the key are the root paths you supplied and the values are lists of relative paths:
def find_files(root, extensions = ('mel', 'py')):
def clean_path(*p):
return "/".join(p).replace('\\', '/')
for root, _, files in os.walk(root):
used = [f for f in files if f.split(".")[-1] in extensions]
for u in used:
yield clean_path(root, u)
def relativize(abs, roots):
low_roots = map (str.lower, roots) # all lower for comparison
for root, low_root in zip(roots,low_roots):
if abs.lower().startswith(low_root):
return root, abs[len(root):]
return ("", abs)
relative_paths = find_files('c:/users/scripts')
root_dict = {}
for item in relative_paths :
folder, file = relativize(item, ('C:/users/scripts/Python/', 'C:/users/scripts/Mel/', 'C:/users/scripts/'))
if not folder in root_dict:
root_dict[folder] = []
root_dict[folder].append(file)
So now you have a dictionary with a bunch of root folders and lists of relative paths (files that were not in any relative path you supplied are keyed to empty string and show up as absolute paths). You can make the menus in a very generic way because they are all in the same format. If you need the entire list, you can get it like this:
results = []
for each_root in root_dict:
for relpath in root_dict[each_root]:
results.append(each_root + relpath)
For creating the actual menus, you want to use a single function and bind it to the filename for each menu item as you make it. This is a slightly tricky topic (more detail here). The easy way to do this is to use a functools.partial object, which bundles a command and a bunch of arguments into an object which looks like a function: you can create a partial and attach it to the command of your menu items so they all call the same function with their individual arguments. Here's a simple example using the variables from above and a menubar; you can see how to adapt it to other kinds of menus pretty easily:
from functools import partial
# call this on every button selection
def test(filepath, ignore):
# maya will send "test(name, False)"; we just ignore the 'False'
print "Here's where I would reload", filepath
example = cmds.window(title = 'example')
menubar = cmds.menuBarLayout()
for name in folder_names:
menuname = name
if menuname:
menuname = menuname.split("/")[-2] # we used trailing slashes
else:
menuname = "root"
cmds.menu(label = menuname)
file_names = root_dict[name]
file_names.sort()
for fn in file_names:
mi = cmds.menuItem(label = fn, command = partial(test, fn))
cmds.setParent(menubar)
I'm working with *.cfg files. The file can be read in a text editor like gedit and has this format:
% some comments
VAR_1= 1
%
% More comments
ANOTHER_VAR= -8
%
% comments again
VAR_THE_COMEBACK= 10
I want to create multiple config files just changing VAR_1= 1....2...3.........10. I manage to import the *cfg file without any new import in python but I'm not getting a way to change just this parameter, saving the file and creating another one with another value for VAR_1.
my code until now is really simple:
import os
os.chdir('/home/leonardo/Desktop')
f = open('file.cfg','r') #if I replace r by w I erase the file ....
a = f.read()
print a.find('1')
a.replace('1','2') #I tried this but. ... :(
f.close()
Any tips ?
Thank you for the help !
Untested code, but you will get the idea:
with open('file.cfg', 'r') as f:
contents_by_line = f.readlines()
for var_index, line in enumerate(contents_by_line):
if line.startswith("VAR_"):
break
else:
raise RuntimeError("VAR_ not found in file")
for var_i, new_cfg_file in ((2,"file2.cfg"),
(3, "file3.cfg")): #add files as you want
with open(new_cfg_file, "w") as fout:
for i, line in enumerate(contents_by_line):
if i == var_index:
fout.write("VAR_1=%d\n" % var_i)
else:
fout.write(line)
Thank you guys for all the help. I changed my approach to the problem, since the lines would be all the 'same', I just created a new line and replaced with a function I found here in stack. I hope it will help someone someday.
This script will automate a series of CFD simulations for my final project at college. It creates a series of folders with some simulation conditions on the name, copies the mesh file to the folder created as well as the new config file, the last line will run the code but I need to work in the base simulation setup to run the script.
The code is just in preliminary fase, I'll change it to be more readable and to be easily modified.
thank you guys !
Any tip is welcome, I'm trying to improve my coding skill : )
the code :::
import fileinput
import os
import shutil
import subprocess
class stuff:
root_folder = '/home/leonardo/Desktop/testzone'
mini_mach = 0.3
maxi_mach = 1.3
number_steps = 3
increment = ((maxi_mach-mini_mach)/number_steps)
config_file = 'inv_NACA0012.cfg'
parameter_1 = 'MACH_NUMBER= 0.8'
parameter_2 = 'CONV_NUM_METHOD_ADJFLOW= JST'
init_pa = 'MACH_NUMBER= ' #use a space after '='
init_pa2 = 'CONV_NUM_METHOD_ADJFLOW= ' #use a space after '='
airfoil = 'NACA0012'
command1 = 'parallel_computation.py -f ' #use space before the last " ' "
command2 = '-n 2'
mesh_file = 'mesh_NACA0012_inv.su2'
class modify:
def replaceAll(self,files,searchExp,replaceExp):
for line in fileinput.input(files, inplace=1):
if searchExp in line:
line = line.replace(searchExp,replaceExp)
sys.stdout.write(line)
mod = modify()
stuff = stuff()
for i in xrange(stuff.number_steps):
mach_name = stuff.airfoil + '_mach_' + `float('%.2f'% stuff.mini_mach)`
folder_name = stuff.root_folder + '/' + mach_name
print 'creating ...' + folder_name
os.makedirs(folder_name)
file_father = stuff.root_folder + '/' + stuff.config_file
shutil.copy2(file_father,folder_name)
mesh_father = stuff.root_folder + '/' + stuff.mesh_file
shutil.copy2(mesh_father,folder_name)
os.chdir(folder_name)
pre_mod_file = mach_name + '.cfg'
os.renames(stuff.config_file,pre_mod_file)
new_parameter_1 = stuff.init_pa + `float('%.2f'% stuff.mini_mach)`
new_parameter_2 = stuff.init_pa2 + `float('%.2f'% stuff.mini_mach)`
mod.replaceAll(pre_mod_file,stuff.parameter_1,new_parameter_1)
mod.replaceAll(pre_mod_file,stuff.parameter_2,new_parameter_2)
stuff.mini_mach += stuff.increment
#subprocess.check_call(stuff.command + pre_mod_file + stuff.command2)
I am writing a Python function to change the extension of a list of files into another extension, like txt into rar, that's just an idle example. But I'm getting an error. The code is:
import os
def dTask():
#Get a file name list
file_list = os.listdir('C:\Users\B\Desktop\sil\sil2')
#Change the extensions
for file_name in file_list:
entry_pos = 0;
#Filter the file name first for '.'
for position in range(0, len(file_name)):
if file_name[position] == '.':
break
new_file_name = file_name[0:position]
#Filtering done !
#Using the name filtered, add extension to that name
new_file_name = new_file_name + '.rar'
#rename the entry in the file list, using new file name
print 'Expected change from: ', file_list[entry_pos]
print 'into File name: ', new_file_name
os.rename(file_list[entry_pos], new_file_name)
++entry_pos
Error:
>>> dTask()
Expected change from: New Text Document (2).txt
into File name: New Text Document (2).rar
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
dTask()
File "C:\Users\B\Desktop\dTask.py", line 19, in dTask
os.rename(file_list[entry_pos], new_file_name)
WindowsError: [Error 2] The system cannot find the file specified
I can succeed in getting the file name with another extension in variable level as you can see in the print-out, but not in reality because I can not end this process in OS level. The error is coming from os.rename(...). Any idea how to fix this ?
As the others have already stated, you either need to provide the path to those files or switch the current working directory so the os can find the files.
++entry_pos doesn't do anything. There is no increment operator in Python. Prefix + is just there fore symmetry with prefix -. Prefixing something with two + is just two no-ops. So you're not actually doing anything (and after you change it to entry_pos += 1, you're still resetting it to zero in each iteration.
Also, your code is very inelegant - for example, you are using a separate index to file_list and fail to keep that in synch with the iteration variable file_name, even though you could just use that one! To show how this can be done better.
-
def rename_by_ext(to_ext, path):
if to_ext[0] != '.':
to_ext = '.'+to_ext
print "Renaming files in", path
for file_name in os.listdir(path):
root, ext = os.path.splitext(file_name)
print "Renaming", file_name, "to", root+ext
os.rename(os.path.join(path, file_name), os.path.join(path, root+to_ext))
rename_by_ext('.rar', '...')
os.rename really doesn't like variables. Use shutil. Example taken from How to copy and move files with Shutil.
import shutil
import os
source = os.listdir("/tmp/")
destination = "/tmp/newfolder/"
for files in source:
if files.endswith(".txt"):
shutil.move(files,destination)
In your case:
import shutil
shutil.move(file_list[entry_pos], new_file_name)
You also want to double backslashes to escape them in Python strings, so instead of
file_list = os.listdir('C:\Users\B\Desktop\sil\sil2')
you want
file_list = os.listdir('C:\\Users\\B\\Desktop\\sil\\sil2')
Or use forward slashes - Python magically treats them as path separators on Windows.
You must use the full path for the rename.
import os
def dTask():
#Get a file name list
dir = 'C:\Users\B\Desktop\sil\sil2'
file_list = os.listdir(dir)
#Change the extensions
for file_name in file_list:
entry_pos = 0;
#Filter the file name first for '.'
for position in range(0, len(file_name)):
if file_name[position] == '.':
break
new_file_name = file_name[0:position]
#Filtering done !
#Using the name filtered, add extension to that name
new_file_name = new_file_name + '.rar'
#rename the entry in the file list, using new file name
print 'Expected change from: ', file_list[entry_pos]
print 'into File name: ', new_file_name
os.rename( os.path.join(dir, file_list[entry_pos]), os.path.join(dir,new_file_name))
++entry_pos
If you aren't in the directory C:\Users\B\Desktop\sil\sil2, then Python certainly won't be able to find those files.
import os
def extChange(path,newExt,oldExt=""):
if path.endswith != "\\" and path.endswith != "/":
myPath = path + "\\"
directory = os.listdir(myPath)
for i in directory:
x = myPath + i[:-4] + "." + newExt
y = myPath + i
if oldExt == "":
os.rename(y,x)
else:
if i[-4:] == "." + oldExt:
os.rename(y,x)
now call it:
extChange("C:/testfolder/","txt","lua") #this will change all .txt files in C:/testfolder to .lua files
extChange("C:/testfolder/","txt") #leaving the last parameter out will change all files in C:/testfolder to .txt