I have a program that reads in 5 files, performs a "two sum" algorithm over the arrays in the file, and outputs to a new file if there's a sum of two numbers that matches the target.
I've got the logic to handle everything except if there's no match. If there's no match I need to write "No" to the output file. If I just add else: f.write("No") after the second if then it'll write "No" for every pass that it's not a match. I need it write "No" ONCE at the end of the processing, after it hasn't found a match.
Read 5 "in" files
inPrefix = "in"
outPrefix = "out"
for i in range(1, 6):
inFile = inPrefix + str(i) + ".txt"
with open(inFile, 'r') as f:
fileLines = f.readlines()
target = fileLines[1]
arr = fileLines[2]
Output 5 "out" files
outFile = outPrefix + str(i) + ".txt"
with open(outFile, 'a') as f:
f.write(target)
f.write(arr)
target = int(target)
num_arr = [int(j) for j in arr.split()]
for a in range(len(num_arr)):
for b in range(a, len(num_arr)):
curr = num_arr[a] + num_arr[b]
if num_arr[a]*2 == target:
a = str(num_arr[a])
target = str(target)
answer = "{}+{}={}".format(a,a,target)
f.write("Yes")
f.write("\n")
f.write(answer)
break
if curr == target:
a = str(num_arr[a])
b = str(num_arr[b])
target = str(target)
answer = "{}+{}={}".format(a,b,target)
f.write("Yes")
f.write("\n")
f.write(answer)
break
f.close()
Initialize a variable -- let's call it wrote_yes -- to False at the top of the code.
Anytime you write "Yes" to the file, set that variable to True.
When you reach the end of all the processing, check that variable. If it's still False, then you never wrote "Yes", so now you can write "No".
Related
I only want to get the second result, which num prints and use it.
savee1 is a .txt file
def copycoordinates():
savee1 = filedialog.askopenfilename(initialdir="C:/USERS/" + username + "/documents/Euro Truck Simulator 2/profiles", title="Choose FIRST File", filetypes=[("sii files", "*.sii")])
savee2 = filedialog.askopenfilename(initialdir="C:/USERS/" + username + "/documents/Euro Truck Simulator 2/profiles", title="Choose SECOND File", filetypes=[("sii files", "*.sii")])
i1 = Label(frame5, text="Chosen FIRST File \n" + savee1)
i1.pack()
i2 = Label(frame5, text="Chosen SECOND File \n" + savee2)
i2.pack()
command=lambda:[save1()]
subprocess.Popen(["C:/SII_Decrypt.exe", savee1])
command=lambda:[save2()]
subprocess.Popen(["C:/SII_Decrypt.exe", savee2])
#time.sleep(1)
with open(savee1, "r+") as save1:
for num, line in enumerate(save1, 1):
if "truck_placement:" in line:
print(num)
If you mean you want the second match, you can try:
with open(savee1, "r+") as save1:
match = 0
for num, line in enumerate(save1, 1):
if 'truck_placement:' in line:
match += 1
if match == 2
print(num)
else:
continue
The num will print on the second match.
There are definitely better ways, but this is one of the most easy solution.
results = list()
with open(savee1, "r+") as save1:
for num, line in enumerate(save1, 1):
if "truck_placement:" in line:
print(num)
results.append(num)
print(results[1]) #this is the value you want
not sure what's in your text file, but usually things are separated in some way (line break, tab separated, comma separated). You should split on what ever it is that separates and then you can just index the resulting list. the following code assumes the things you want are separated by new lines:
with open(save1, "r+") as infile:
f=infile.read()
list_o_txt = f.split('\n')
print (list_o_txt[1])
if you want to make a sublist of texts that only contain a phrase 'truck_placement'
with open(save1,'r') as infile:
f=infile.read()
list_o_txt = f.split('\n') # produces a list
filtered_list = [line for line in list_o_txt if 'truck_placement' in line] #filters the list
print (filtered_list[1]) #prints the second item
I'm trying to loop through a bunch of text files and append line #2 of each file to a list. Below is my sample code. This looks like it should be pretty close, but nothing at all is getting appended to my list.
import os
directory = 'C:\\my_path\\'
i=0
list2 = []
for filename in os.listdir(directory):
with open(directory + filename) as infile:
try:
print(filename)
i=i+1
print(i)
data = infile.readlines()
for line in data:
if (line == 2):
list2.append(line)
infile.close()
except:
print(filename + ' is throwing an error')
print('DONE!!')
print(list2)
When writing:
for line in data:
if (line == 2):
list2.append(line)
infile.close()
The line variable is not the index of the line but the line itself as a string.
Also note that the second line will have an index of 1, not 2 because indexes start at 0 in Python.
You should at least change this loop to:
for index, line in enumerate(data):
if (index == 1):
list2.append(line)
infile.close()
Also, as suggested by #bruno-desthuilliers, you do not need to use the readlines() method which uses memory, instead you can directly iterate on your file like this:
#no infile.readlines() needed
for index, line in enumerate(infile):
if (index == 1):
list2.append(line)
infile.close()
Finally, you do not need to call infile.close() as you're wrapping the statement in a with block. The call is made for you.
When you test if line == 2, you are asking wether the line you read from infile is equal to 2 (which it never is). Instead, you need some counter to test if you are at line 2. Or even better, just index into it:
data = infile.readlines()
list2.append(data[1]) # the line at index 1 is the second line
line == 2 in your code tries to compare a text/string with number 2 which won't help to catch the ordinal number of the line being read.
Instead, just skip the 1st line and append the next one to the resulting list.
Note:
no need to read all lines infile.readlines() if you only need the 2nd line!
no need to close the file handler when using context manager with ...
import os
directory = 'C:\\my_path\\'
list2 = []
for filename in os.listdir(directory):
with open(directory + filename) as infile:
try:
print(filename)
next(infile)
list2.append(next(infile))
except:
print(filename + ' is throwing an error')
print('DONE!!!')
print(list2)
Try this version:
import os
directory = 'C:\\my_path\\'
secondLines = []
for filename in os.listdir(directory):
try:
#Use open() because it is optimized and does not read the whole file into RAM
with open(directory + "\\" + filename) as infile:
for lineIndex, line in enumerate(infile):
if lineIndex == 1:
secondLines.append(line)
except:
print(filename + ' is throwing an error')
print(secondLines)
Your version:
import os
directory = 'C:\\my_path\\'
i=0
list2 = []
for filename in os.listdir(directory):
#add "\\" to read the correct file
with open(directory + "\\" + filename) as infile:
try:
print(filename)
i=i+1
print(i)
data = infile.readlines()
#To get the second line, you have to use indexes
for line in range(len(data)):
#if line (index) equals 1, it is the second line (0th element is first)
if (line == 1):
#If the index of the line is 1, append it to the list
#data[line] = take the element on index 1 from list data. Indexing starts at 0
list2.append(data[line])
infile.close()
except:
print(filename + ' is throwing an error')
print('DONE!!')
print(list2)
Another elegant way of doing it is following, which takes care of not iterating through all the data as well as opening and closing the file automatically.
# With open should take care of automatic opening and closing of file. You don't need to close it explicitly.
with open(directory + filename) as infile:
try:
print(filename)
i=i+1
print(i)
skip_count = 0
line in infile:
skip_count += 1
if skip_count == 2:
list2.append(line)
break # This will go out of loop and you don't have to iterate through all the data
except:
print(filename + ' is throwing an error')
I have a text file that I am reading in, and based on certain conditions modifying specific lines and rewriting the file to a new text file. My present code mostly works but one of the elif statements seems to be simply ignored by Python as there are no run time errors. A MWE is as follows:
energy = .1
source = str('source x y z energy=%f' %energy)
c = energy - 0.001
c_string = str("1010 %f %f" %(c, energy))
f = open("file.txt", "r+")
with open ("newfiletxti", 'w') as n:
d = f.readlines()
for line in d:
if not line.startswith("source"):
if not line.startswith("xyz"):
n.write(line)
elif line.startswith("source"):
n.write(source + "\n")
elif line.startswith("xyz"):
n.write(c_string + "\n")
n.truncate()
n.close()
The code:
elif line.startswith("source"):
n.write(source + "\n")
Works as expected where the line in the text file is replaced with the string titled "source" however the next block:
elif line.startswith("xyz"):
n.write(c_string + "\n")
Has no effect. The new text file is simply missing the line that starts with xyz. My guess is my syntax for multiple elif statements is incorrect but I am uncertain as to why.
The first if and elif handle all the cases -- either the line starts with source or it doesn't. I think you need to combine the first if and its nested if into a single condition:
if not line.startswith("source") and not line.startswith("xyz"):
n.write(line)
or the equvivalent (by de Morgan's Laws):
if not(line.startswith("source") or line.startswith("xyz")):
n.write(line)
Or you can make it clearer by reordering your conditions:
if line.startswith("source"):
n.write(source + "\n")
elif line.startswith("xyz"):
n.write(c_string + "\n")
else:
n.write(line)
Try your if block like this:
if line.startswith("source"):
n.write(source + "\n")
elif line.startswith("xyz"):
n.write(c_string + "\n")
else:
n.write(line)
The third elif will never be reached. Here is the code reduced for clarity:
if not line.startswith("source"):
# suff
elif line.startswith("xyz"):
# stuff
Something that starts with "xyz" does not start with "source".
I'm basically trying to code a simple spell-check program that will prompt you for an input file, then analyze the input file for possible spelling errors (by using binary search to see if the word is in the dictionary), before printing them in the output file.
However, currently, it outputs everything in the input file instead of just the errors...
My code is as follows:
import re
with open('DICTIONARY1.txt', 'r') as file:
content = file.readlines()
dictionary = []
for line in content:
line = line.rstrip()
dictionary.append(line)
def binary_search(array, target, low, high):
mid = (low + high) // 2
if low > high:
return -1
elif array[mid] == target:
return mid
elif target < array[mid]:
return binary_search(array, target, low, mid-1)
else:
return binary_search(array, target, mid+1, high)
input = input("Please enter file name of file to be analyzed: ")
infile = open(input, 'r')
contents = infile.readlines()
text = []
for line in contents:
for word in line.split():
word = re.sub('[^a-z\ \']+', " ", word.lower())
text.append(word)
infile.close()
outfile = open('TYPO.txt', 'w')
for data in text:
if data.strip() == '':
pass
elif binary_search(dictionary, data, 0, len(data)) == -1:
outfile.write(data + "\n")
else:
pass
file.close
outfile.close
I can't seem to figure out what's wrong. :(
Any help would be very much appreciated!
Thank you. :)
I tried replacing len(data) with len(dictionary) as that made more sense to me and it seems to work in my very limited tests.
I think you were passing the length of the word in question as the upper bound on the dictionary. So if you were looking up the word "dog" you were only checking the first 3 words in the dictionary, and since your dictionary is probably very large, almost every word was never found (so every word was in the output file).
message = 'aaa'
for alpha in message:
num = ord(alpha) + 2
ans = chr(num)
print(ans)
file = open('f.txt', 'w')
file.write(ans)
file.close()
print(ans) prints ccc as expected, but file.write(ans) writes only 'c'. How come it doesn't print the entire string? Thanks a bunch.
write method starts to write from a certain (current) position in a file. Since you open the file on every iteration, write will always start from the beginning of the file, overwriting the existing data. In your case it will replace the existing letter c.
You'll need to open the file before the loop and close it after the loop. This will make the file retain the position (check that with file.tell()):
message = "aaa"
file = open('f.txt', 'w')
for alpha in message:
num = ord(alpha) + 2
ans = chr(num)
print(ans)
file.write(ans)
file.close()
Or, even better, use a context manager:
message = "aaa"
with open('f.txt', 'w') as file:
for alpha in message:
num = ord(alpha) + 2
ans = chr(num)
print(ans)
file.write(ans)