This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Rename Files in Python
Hey all, I am creating a script in Python to wrap a number of OS commands related to bulk image editing, and most of the tasks are completed, however I am stumped on one task (a seemingly simple one at that).
When I scan pictures on my scanner, I get a filename similar to this:
201105151110_0001A.jpg
where the first part is some sort of a timestamp (which I want to replace), however I wanted to make that an input variable (where I, or other users could just paste that into the command line, if I'm using another scanner where the filename structure could be different. 0001A means the front side of the first photo/document, and I would like to keep that part of the filename.
I have three variables set up:
old_prefix = input(bcolors.PROMPT + "Enter the prefix to replace: " + bcolors.ENDC)
new_prefix = input(bcolors.PROMPT + "Enter the new prefix: " + bcolors.ENDC)
working_directory
working_directory is the variable from another part of the code, which is where the images would be located. The color part is just so I can colorize the output and make it easier to read. There would be anywhere from 1-1000 files in the directory when I work on it.
This script will be run on Linux.
Thank you!
---EDIT---
Sorry for wasting your time guys, it seems I overlooked some information in the question linked here by Kiril Kirov, the code that I came up with, which works is:
elif retouch_option == "06":
print(" ")
old_prefix = input(bcolors.PROMPT + "Enter the prefix to replace: " + bcolors.ENDC)
new_prefix = input(bcolors.PROMPT + "Enter the new prefix.......: " + bcolors.ENDC)
print(bcolors.OUTPUT + " ")
for fname in glob(working_directory + "*.jpg"):
keeper = fname[-9:]
print("Renaming image", keeper)
os.rename(fname, fname.replace(old_prefix, new_prefix))
I think it should be safe, since it is just replacing the old_prefix variable with the new_prefix variable. Is this true? If not I'd definitely appreciate feedback, although this seems to be working fine so far.
something like:
sep = '_'
try:
prefix,keeper = filename.split(sep)
except: # filename does not match desired structure
print "not processed: no '" + sep + "' in '"+ filename + "'"
else: # split succeeded:
if prefix == old_prefix:
filename = new_prefix + sep + keeper
# more processing...
else:
print "prefix doesn't match in '" + filename + "'"
Related
I have seen this question multiple times but none of them can apply to my code and none of it makes sense to my code. So I am sorry for asking this question.
I have written up a code where the data from previous inputs are written into a csv file. The name of the variable is called file and i have numerous of these for different inputs. But when I try to close the csv it comes up with the error:
NameError: name 'file' is not defined
Here is the code:
if classCode=="1":
file=open("class1.csv","w")
file.write("name, correct\n" + name + "," + str(correct) + "\n")
elif classCode=="2":
file=open("class2.csv","w")
file.write("name, correct\n" + name + "," + str(correct) + "\n")
elif classCode=="3":
file=open("class3.csv","w")
file.write("name, correct\n" + name + "," + str(correct) + "\n")
file.close()
I don't know why it says that 'file' isn't defined when I clearly have for all three. Am i just being stupid?
What happens if the class code is not 1,2 or 3. If all class code do the same thing you can make the filename dynamic, instead of repeating the code several times.
class_file=open("class{}.csv".format(classCode),"w")
class_file.write("name, correct\n" + name + "," + str(correct) + "\n")
class_file.close()
file variable will only declare when classCode is either "1", "2" or "3" otherwise it will not declare and error will come.
you should make sure either control goes to any of the if statement or you should declare this variable outside If statement.
I have a very simple problem that I have been unable to find the solution to, so I thought I'd try my "luck" here.
I have a string that is created using variables and static text altogether. It is as follows:
filename_gps = 'id' + str(trip_id) + '_gps_did' + did + '_start' + str(trip_start) + '_end' + str(trip_end) + '.json'
However my problem is that pylint is complaining about this string reprensentation as it is too long. And here is the problem. How would I format this string representation over multiple lines without it looking weird and still stay within the "rules" of pylint?
At one point I ended up having it looking like this, however that is incredible "ugly" to look at:
filename_gps = 'id' + str(
trip_id) + '_gps_did' + did + '_start' + str(
trip_start) + '_end' + str(
trip_end) + '.json'
I found that it would follow the "rules" of pylint if I formatted it like this:
filename_gps = 'id' + str(
trip_id) + '_gps_did' + did + '_start' + str(
trip_start) + '_end' + str(
trip_end) + '.json'
Which is much "prettier" to look at, but in case I didn't have the "str()" casts, how would I go about creating such a string?
I doubt that there is a difference between pylint for Python 2.x and 3.x, but if there is I am using Python 3.x.
Don't use so many str() calls. Use string formatting:
filename_gps = 'id{}_gps_did{}_start{}_end{}.json'.format(
trip_id, did, trip_start, trip_end)
If you do have a long expression with a lot of parts, you can create a longer logical line by using (...) parentheses:
filename_gps = (
'id' + str(trip_id) + '_gps_did' + did + '_start' +
str(trip_start) + '_end' + str(trip_end) + '.json')
This would work for breaking up a string you are using as a template in a formatting operation, too:
foo_bar = (
'This is a very long string with some {} formatting placeholders '
'that is broken across multiple logical lines. Note that there are '
'no "+" operators used, because Python auto-joins consecutive string '
'literals.'.format(spam))
I have the following piece of code that generates plots with gnuplot:
import sys, glob, subprocess, os, time
for file in glob.glob('comb_*.out'):
fNameParts = file[5:].split('.')[0].split('-')
gPlotCmd = []
gPlotCmd = 'unset border; set xl "rotation period #"; set yl "T [K]"\n'
gPlotCmd += 'set key above\n'
gPlotCmd += 'set grid xtics ytics\n'
gPlotCmd += 'set term post eps enh color solid\n'
gPlotCmd += 'set xrange [20:876]\n'
gPlotCmd += 'set output "fig_TestRelax-' + fNameParts[1] + '-' + fNameParts[2] + '-' + fNameParts[3] + '-' + fNameParts[4] + '.eps"\n'
conf = fNameParts[1] + '-' + fNameParts[2] + '-' + fNameParts[3]
gPlotCmd += 'plot "' + file + '" using ($1/36000):($9-$3) w l lw 5 title "OP3-OP1 ' + conf + '", "' + file + '" using ($1/36000):($6-$3) w l lw 3 title "OP2-OP1 ' + conf + '", "' + file + '" using ($1/36000):($9-$6) w l lw 1 title "OP3-OP2 ' + conf + '"'
fw = open('temp.plt','w+')
fw.writelines(gPlotCmd)
subprocess.call(["gnuplot","temp.plt"])
print(file)
In the last loop execution the subprocess.call(["gnuplot","temp.plt"]) does not seem to be executed. At the end of the program, temp.plt exists with data from the last iteration. Also print(file) is executed during the last loop. Also if I plot the temp.plt left after the program I get the last plot (so there is no problem on the side of the data). Only the line subprocess.call(["gnuplot","temp.plt"]) is not executed. I also tried popen and monitor stdout and stderr but both were empty (as in all other iterations.
The checked the problem occurs both on linux and windows and in versions 3.3.5 and 2.7.3.
I conclude that there is something wrong with the script but I do not know what.
#lvc's and yours answer are correct; it is a buffering issue and fw.flush() should fix it. But you don't need the temporary file, you could pass the input commands to gnuplot directly without writing them to disk:
from subprocess import Popen, PIPE
p = Popen('gnuplot', stdin=PIPE)
p.communicate(input=gPlotCmd.encode('ascii'))
One likely error here is that the file temp.plt isn't actually written to disk at the time you run gnuplot. Python doesn't necessarily flush its buffers immediately after a call to writelines. This would mean that when gnuplot is launched from your script, it sees an empty file. It doesn't give an error, because an empty input isn't an error, and it has no way of knowing its expecting anything else. By the time you run it outside of your script, Python has exited and hence can't be holding anything in its own buffers anymore.
Use the with statement to ensure that fw is closed once you're done with it:
with open('temp.plt', 'w') as fw:
fw.writelines(gPlotCmd)
subprocess.call(["gnuplot","temp.plt"])
It seems I figured that out. I am missing fw.close(). The last lines of code should look:
fw = open('temp.plt','w+')
fw.writelines(gPlotCmd)
fw.close()
subprocess.call(["gnuplot","temp.plt"])
print(file)
Now the code produces the intended plots.
I have an excel book with a couple of sheets. Each sheet has two columns with PersonID and LegacyID. We are basically trying to update some records in the database based on personid. This is relatively easy to do TSQL and I might even be able to get it done pretty quick in powershell but since I have been trying to learn Python, I thought I would try this in Python. I used xlrd module and I was able to print update statements. below is my code:
import xlrd
book = xlrd.open_workbook('D:\Scripts\UpdateID01.xls')
sheet = book.sheet_by_index(0)
myList = []
for i in range(sheet.nrows):
myList.append(sheet.row_values(i))
outFile = open('D:\Scripts\update.txt', 'wb')
for i in myList:
outFile.write("\nUPDATE PERSON SET LegacyID = " + "'" + str(i[1]) + "'" + " WHERE personid = " + "'" + str(i[0])
+ "'")
Two problems - when I read the output file, I see the LegacyID printed as float. How do I get rid of .0 at the end of each id? Second problem, python doesn't print each update statement in a new line in the output text file. How to I format it?
Edit: Please ignore the format issue. It did print in new lines when I opened the output file in Notepad++. The float issue still remains.
Can you turn the LegacyID into ints ?
i[1] = int(i[1])
outFile.write("\nUPDATE PERSON SET LegacyID = " + "'" + str(i[1]) + "'" + " WHERE personid = " + "'" + str(i[0])
+ "'")
try this..
# use 'a' if you want to append in your text file
outFile = open(r'D:\Scripts\update.txt', 'a')
for i in myList:
outFile.write("\nUPDATE PERSON SET LegacyID = '%s' WHERE personid = '%s'" %( int(i[1]), str(i[0])))
Since you are learning Python (which is very laudable!) you should start reading about string formatting in the Python docs. This is the best place to start whenever you have a question light this.
Hint: You may want to convert the float items to integers using int().
It has been awhile since I have written functions with for loops and writing to files so bare with my ignorance.
This function is given an IP address to read from a text file; pings the IP, searches for the received packets and then appends it to a .csv
My question is: Is there a better or an easier way to write this?
def pingS (IPadd4):
fTmp = "tmp"
os.system ("ping " + IPadd4 + "-n 500 > tmp")
sName = siteNF #sys.argv[1]
scrap = open(fTmp,"r")
nF = file(sName,"a") # appends
nF.write(IPadd4 + ",")
for line in scrap:
if line.startswith(" Packets"):
arrT = line.split(" ")
nF.write(arrT[10]+" \n")
scrap.close()
nF.close()
Note: If you need the full script I can supply that as well.
This in my opinion at least makes what is going on a bit more obvious. The len('Received = ') could obviously be replaced by a constant.
def pingS (IPadd4):
fTmp = "tmp"
os.system ("ping " + IPadd4 + "-n 500 > tmp")
sName = siteNF #sys.argv[1]
scrap = open(fTmp,"r")
nF = file(sName,"a") # appends
ip_string = scrap.read()
recvd = ip_string[ip_string.find('Received = ') + len('Received = ')]
nF.write(IPadd4 + ',' + recvd + '\n')
You could also try looking at the Python csv module for writing to the csv. In this case it's pretty trivial though.
This may not be a direct answer, but you may get some performance increase from using StringIO. I have had some dramatic speedups in IO with this. I'm a bioinformatics guy, so I spend a lot of time shooting large text files out of my code.
http://www.skymind.com/~ocrow/python_string/
I use method 5. Didn't require many changes. There are some fancier methods in there, but they didn't appeal to me as much.