Python strange "string indices must be integers" error - python

Problem solved! was newfilename[0,3] instead of newfilename[0: 3]
I know this question has been asked before and I have look around on all the answers and the types of problems people have been having related to this error message, but was unable to find anyone with the same type of problem.
I am sowing the whole method just in case. So here is my problem;
When I am trying to get is a substring of "newfilename" using newfilename[int, int] and the compiler keeps thinking I don't have an integer there when I do, at least from my checking I do.
What I'm doing with this code: I am cutting of the end of a filename such as 'foo.txt' to get 'foo' that is saved as newfilename. Then I am adding the number (converted to a string) to the end of it to get 'foo 1' and after that adding back the '.txt' to get the final result of 'foo 1.txt'. The problem occurs when I try to get the substring out and delete the last four characters of the filename to get just 'foo'. After that, I do another check to see if there is a file like that still in the folder and if so I do another set of cutting and pasting to add 1 to the previous file. To be honest, I have not tested of the while loop will work I just thought it should work technically, but my code does not reach that far because of this error lol.
My error:
File "C:/Users/Reaper/IdeaProjects/Curch Rec Managment/Setup.py", line 243, in moveFiles
print(newfilename[0, 3])
TypeError: string indices must be integers
NOTE this error is from when I tried to hard code the numbers it to see if it would work
Here is the current error with the hard code commented out:
newfilename = newfilename[0, int(newfilename.__len__() - 4)] + " 1.m4a"
TypeError: string indices must be integers
What I have tried: I have tried hard coding the numbers is by literally typing in newfilename[0, 7] and still got the same error. I have tried doing this in a separate python file and it seems to work there fine. Also, what is really confusing me is that it works in another part of my program just fine as shown here:
nyear = str(input("Enter new Year: "))
if nyear[0:2] != "20" or nyear.__len__() > 4:
print("Sorry incorrect year. Please try again")
So I have been at it for a while now trying to figure out what in the world is going on and can't get there. Decided I would sleep on it but would post the question just in case. If someone could point out what may be wrong that would be awesome! Or tell me the compilers are just being stupid, well I guess that will do as well.
My function code
def moveFiles(pathList, source, filenameList):
# moves files to new location
# counter keeps track of file name position in list
cnter = 0
for x in pathList:
filename = filenameList[cnter]
#print(x + "\\" + filename)
# new filename
if filename.find("PR") == 0:
newfilename = filename[3:filename.__len__()]
else:
newfilename = filename[2:filename.__len__()]
# checking if file exists and adding numbers to the end if it does
if os.path.isfile(x + "\\" + newfilename):
print("File Name exists!!")
# adding a 1 to the end
print(newfilename)
# PROBLEM ON NEXT TWO LINES, also prob. on any line with the following calls
print(newfilename[0, 3])
newfilename = newfilename[0, int(newfilename.__len__() - 4)] + " 1.m4a"
print("Adding 1:", newfilename)
# once again check if the file exists and adding 1 to the last number
while os.path.isfile(x + "\\" + newfilename):
# me testing if maybe i just can't have math operations withing the substring call
print("File exists again!!")
num = newfilename.__len__() - 6
num2 = newfilename.__len__() - 4
num3 = int(newfilename[num, num2])
num = newfilename.__len__() - 5
newfilename = newfilename[0, num] + str(num3 + 1)
print("Adding 1:", newfilename)
# moving file and deleting prefix
if not os.path.isdir(x):
os.makedirs(x)
os.rename(source + "\\" + filename, x + "\\" + newfilename)
cnter += 1

I think you need this:
print(newfilename[0:3])

Related

How do I get my code to show a certain number of characters from a text file

In my assignment i'm expected to look for a word and only return a set number of characters (which is 80, and 40 on each side surrounding the word), without the use of nltk or regex.
I've set my code up as so
open = open("a2.txt", 'r')
file2read = open.readlines()
name = 'word'
for line in file2read:
s2 = line.split ("\n", 1)
if name in line:
i = line.find(name)
half = (80 - len(name) - 2) // 2
left = line[i - half]
right = line[i + len(word) + half]
print(left + word + right)
but then my print out looks like this(updated screenshot) instead of the 80 character lines which i'm hoping to find.
Sorry if this is a really newbie error as i'm only 3 weeks into the program and i've been searching and can't seem to get the answer
Instead of doing readlines which might not be consistent due to differences in windows/Unix you can also read the entire text at once:
You don't need to separate it in lines:
with open('a2.txt', 'r') as file:
a = file.read()
name = 'word'
if name in a:
i = a.find(name)
half = (80 - len(name) - 2) // 2
left = a[i-half:i]
right = a[i+len(name):i + len(name) + half]
print(left + name + right)
This way you are reading the entire text at once. Finding your word and printing the necessary 80 characters. This is the output
ut. even know say trip tip sandwich. words describe it. meat eater, love it. b
If you want to make it work for all the words in the text. You will need to make a loop =) but that i'm sure you can figure it out by yourself!

Python Flask Uploading Image to S3 - random filename from nowhere overwritten

Well I am currently facing a weird issue where my filename (which is correctly generated is overwritten with something random).
I am using this code to upload to AWS3, here the code checks wether a file with such name exists already in the bucket and if it does, it adds a 1 to the end of the file, then it keeps checking for existing files and increments the number until the filename is unique.
I tested the code in a seperate python file and it seemed to work fine, but here my filename is overwritten with random stringname b1.a
I was debugging now for a while and I have no clue. I remember having something similar a while ago, where a missing favicon caused the issue (probably someone knows what was going on and how these issues are connected). But this time I cant figure out what happened.
k.key = bucketpath + filename_hauptbild
if k.key in bucket:
new_filename_haupt_split = filename_hauptbild.split(".")
while k.key in bucket:
if new_filename_haupt_split[0][-1] not in "0123456789":
new_filename_haupt = new_filename_haupt_split[0] + "1." + new_filename_haupt_split[1]
else:
new_filename_haupt = new_filename_haupt_split[0][:-1] + str(int(new_filename_haupt_split[0][-1]) + 1) + "." + new_filename_haupt_split[1]
new_filename_haupt_split = new_filename_haupt
k.key = bucketpath + new_filename_haupt
print "this", new_filename_haupt
k.key = bucketpath + new_filename_haupt
filename_hauptbild = new_filename_haupt
k.set_contents_from_string(file_contents)
else:
k.set_contents_from_string(file_contents)
print filename_hauptbild
setattr(model_to_change, model_column, filename_hauptbild)
Notice here:
I use 2 x prints and the output shows 3 lines.
The first print "this", new_filename_haupt shows initialy the correct filename but is overwritten by b1.a:
Console output:
When you update your filename, you don't properly update your _split variable:
new_filename_haupt_split = new_filename_haupt
hence, on the next loop when you call new_filename_haupt_split[0] you just get the first letter of the filename - b - rather than the filename itself, and when you call new_filename_haupt_split[1] you get the second letter - a - rather than the extension. Hence the name b1.a. Change your line to:
new_filename_haupt_split = new_filename_haupt.split(".")
and I think this should work.
EDIT: you could re-write this as a function to make your life a little easier. Here's an example of the kind of approach you might require:
bucket = ['baubedarf.png', 'baubedarf1.png']
def get_filename(input_filename, all_files):
if input_filename in all_files:
filename, ext = input_filename.rsplit('.', 1)
counter = 1
while '{}{}.{}'.format(filename, counter, ext) in all_files:
counter += 1
return '{}{}.{}'.format(filename, counter, ext)
else:
return input_filename
print get_filename('baubedarf.png', bucket)

Python - Trying to check input against range, then convert the variable into a string to be concatenated

first time posting here. I have searched high and low to figure out a way to do this, but I either don't understand how to apply existing answers to my code.
What I am trying to do is this: I want to take user input (a year), make sure it's between a range of years, and then if it is, concatenate it with an existing string as a variable.
The result of this code is that I get through and give all the necessary inputs, and then it fails with "fullInstr = str("cp -r /mnt/data/archive"+ fquery+ "/" + yquery+mquery+dquery+"/"+hquery+"*" + " " + outl2)
TypeError: cannot concatenate 'str' and 'int' objects"
import os
import sys
os.system("clear")
overW = str("0")
outf = str("/autocopy.sh") # Output file full path and file name
if os.path.isfile("/autocopy.sh"): #
overW = raw_input("This will overwrite the previous version. Do you want to continue? (y/n) ")
os.system("clear")
else:
os.system("clear")
if overW != "y":
os.system("clear")
sys.exit("No changes made.\n\n")
else:
os.system("clear")
#! Could also prompt for output file name, depending on how army-proof this needs to be.
finishMessage = "Finished."
outl = str("0") # Copy-to location
outl2 = str("0") # Modified Copy-to location
fquery = str("0") # A or B location variable
yquery = int("0") # Year variable
mquery = int("0") # Month variable
dquery = int("0") # Day variable
hquery = str("0") # Hour variable
mh1 = int("0") # Modified starting hour after transformation
mh2 = int("0") # Modified ending hour after transformation
mpath = str("0") # makes path if needed
fullInstr = str("0") # Full command set to write to file
formatList = (['A', 'B'])
yearList = list(range(2000,2099))
#monthList = (['01']-['12'])
#! hquery is going to have to parse for ranges
# Instruction header
print "Builds a script to automatically copy folders and files from the storage array to a location of your choosing.\n"
print "Valid inputs for the questions below are numeric."
print "Year would be the full year, i.e. 2013"
print "Month is the two-digit month, i.e. 10"
print "Day is the two-digit day, i.e. 22"
print "Hour or hour range is just the first two digits of the hours you want to copy. i.e. 15 or 00-23\n\n"
outl = raw_input("Where do you want to copy the files to? Type the full path: ")
while not os.path.exists(outl):
mpath = raw_input ("\nThat path doesn't exist on this system. Do you want to create it? (y/n) ")
if mpath != "y":
outl = raw_input("Where do you want to copy the files to? Type a valid path: ")
else:
os.mkdir(outl)
print "\n"
if not outl.endswith("/"):
outl2 = outl + "/"
fquery = raw_input("Do you want to copy A or B? ")
while not(fquery in formatList):
print "\nInvalid input. You have to choose one of the two as printed above."
fquery = raw_input("\nDo you want to copy A or B? ")
print "\n"
yquery = int(raw_input("What year? "))
while yquery not in yearList:
print "\nInvalid input. You have to choose a year in this century."
yquery = int(raw_input("\nWhat year? "))
print "\n"
mquery = raw_input("What day? ")
#! Valid months are 01 to 12
dquery = raw_input("What day? ")
#! Valid days are 01 to 31
hquery = raw_input("What hour or hour range? ")
#! if input is greater than two characters is must contain a - character
#! if is not 00-23, separate first and last numbers and write a line for each. If it isn't a range, don't transform it.
#os.system("touch " + outf)
#! if no error keep going
fullInstr = str("cp -r /mnt/data/archive"+ fquery+ "/" + yquery+mquery+dquery+"/"+hquery+"*" + " " + outl2)
os.system("echo "+fullInstr+ "> /autocopy.sh")
#os.system("chmod u+x "+outf) # Makes the output file executable
#! if error = 0 set finishMessage to print "Your shell script is complete and is ready to run. Run it by typing ." + outf
#! if error is <> 0 set finishMessage to print "Wasn't able to make the output file executable automatically. Use chmod to modify the file permissions manually on the file "+outf
#os.system("clear")
print finishMessage+"\n\n"
Stuff that is commented out is either not working or not implemented yet. I know the code quality is probably not the best, but this is my first time coding to do something I require. I have tried a lot of things like yquery = str(yquery) or just changing the fullInstr string to have str(yquery) in it and I can not get it to work. I am becoming frustrated.
You should use format for string formatting to avoid worrying about the type of variable being concatenated.
fullInstr = "cp -r /mnt/data/archive/{0}/{1}{2}{3}/{4}* {5}".format(fquery,yquery,mquery,dquery,hquery,out12)
That is because you need to convert the int to a str object.
fullInstr = str("cp -r /mnt/data/archive" + fquery + "/" + str(yquery) + mquery + dquery + "/" + hquery + "*" + " " + ^
outl2) ^
# ^ -> Use str to convert
The above code worked on my machine. Running windows 8. Python 2.7.5. I just had to change clear to cls.

TypeError: "NoneType" object is unsubscriptable

I have this error when running this code with Python:
TypeError: "NoneType" object is unsubscriptable".
Code:
number = 0
with open('playlist.txt') as read_number_lines:
for line in read_number_lines:
if line.strip():
number += 1
number = number - 1
print 'number: ', number
for i in range(number):
author_ = raw_input('author: ')
line = input('line: ')
file = open('playlist.txt','a').writelines(' - ' + author_)[line]
How do I fix it?
You've got a few problems in
file = open('playlist.txt','a').writelines(' - ' + author_)[line]
The immediate source of your error is that .writelines() doesn't return anything (so it returns None) which you're trying to index using [line]. That produces your error.
Also, you shouldn't be calling that method on the open() call directly.
The entire second for loop is mysterious to me. You're opening that file again during each iteration of the loop (which you don't want to do; it probably wouldn't even work).
Perhaps you wanted to do something like
with open('playlist.txt','a') as file:
for i in range(number):
author_ = raw_input('author: ')
line = raw_input('line: ')
file.write(author + " - " + line)
but it's still hard to see the point of this...

Automator/Applescript rename files if

I have a large list of images that have been misnamed by my artist. I was hoping to avoid giving him more work by using Automator but I'm new to it. Right now they're named in order what001a and what002a but that should be what001a and what001b. So basically odd numbered are A and even numbered at B. So i need a script that changes the even numbered to B images and renumbers them all to the proper sequential numbering. How would I go about writing that script?
A small Ruby script embedded in an AppleScript provides a very comfortable solution, allowing you to select the files to rename right in Finder and displaying an informative success or error message.
The algorithm renames files as follows:
number = first 3 digits in filename # e.g. "006"
letter = the letter following those digits # e.g. "a"
if number is even, change letter to its successor # e.g. "b"
number = (number + 1)/2 # 5 or 6 => 3
replace number and letter in filename
And here it is:
-- ask for files
set filesToRename to choose file with prompt "Select the files to rename" with multiple selections allowed
-- prepare ruby command
set ruby_script to "ruby -e \"s=ARGV[0]; m=s.match(/(\\d{3})(\\w)/); n=m[1].to_i; a=m[2]; a.succ! if n.even?; r=sprintf('%03d',(n+1)/2)+a; puts s.sub(/\\d{3}\\w/,r);\" "
tell application "Finder"
-- process files, record errors
set counter to 0
set errors to {}
repeat with f in filesToRename
try
do shell script ruby_script & (f's name as text)
set f's name to result
set counter to counter + 1
on error
copy (f's name as text) to the end of errors
end try
end repeat
-- display report
set msg to (counter as text) & " files renamed successfully!\n"
if errors is not {} then
set AppleScript's text item delimiters to "\n"
set msg to msg & "The following files could NOT be renamed:\n" & (errors as text)
set AppleScript's text item delimiters to ""
end if
display dialog msg
end tell
Note that it will fail when the filename contains spaces.
A friend of mine wrote a Python script to do what I needed. Figured I'd post it here as an answer for anyone stumbling upon a similar problem looking for help. It is in Python though so if anyone wants to convert it to AppleScript for those that may need it go for it.
import os
import re
import shutil
def toInt(str):
try:
return int(str)
except:
return 0
filePath = "./"
extension = "png"
dirList = os.listdir(filePath)
regx = re.compile("[0-9]+a")
for filename in dirList:
ext = filename[-len(extension):]
if(ext != extension): continue
rslts = regx.search(filename)
if(rslts == None): continue
pieces = regx.split(filename)
if(len(pieces) < 2): pieces.append("")
filenumber = toInt(rslts.group(0).rstrip("a"))
newFileNum = (filenumber + 1) / 2
fileChar = "b"
if(filenumber % 2): fileChar = "a"
newFileName = "%s%03d%s%s" % (pieces[0], newFileNum, fileChar, pieces[1])
shutil.move("%s%s" % (filePath, filename), "%s%s" % (filePath, newFileName))

Categories

Resources