Print and file.write giving different outputs, Python - python

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)

Related

Python If/Else Logic with File I/O

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".

How to only print or get the second result

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

Nested loops slowing down program. How can I make it faster?

import re
file=input("What is the name of your file? ")
def words_from_file(filename):
try:
f = open(filename, "r")
words = re.split(r"[,.;:?\s]+", f.read())
f.close()
return [word for word in words if word]
except IOError:
print("Error opening %s for reading. Quitting" % (filename))
exit()
dictionary_file=words_from_file("big_word_list.txt")
newfile=words_from_file(file)
def dictionary_check(scores, dictionary_file, full_text):
count=0
for item in full_text:
if item in dictionary_file:
count+=1
scores.append(count)
def decoder(item,shiftval):
decoded = ""
for c in item:
c=c.upper()
if c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
num = ord(c)
num += shiftval
if num > ord("Z"):
num=num-26
elif num < ord("A"):
num=num+26
decoded+=chr(num)
else:
decoded = decoded + c
return decoded
shiftval=0
scores=[]
while shiftval<=26:
full_text=[]
for item in newfile:
result=decoder(item,shiftval)
full_text.append(result)
shiftval+=1
print(full_text)
dictionary_check(scores, dictionary_file, full_text)
highest_so_far=0
for i in range(len(scores)):
if scores[i]>highest_so_far:
i=highest_so_far
i+=1
else:
i+=1
fully_decoded=""
for item in newfile:
test=decoder(item,highest_so_far)
fully_decoded+=test
print(fully_decoded)
Hey everybody.
I have this assignment where I had to make a program that decodes a shift cipher. Right now it works, but it's incredibly slow. I suspect it's probably because of the nested loops. I'm not really sure where to go from this point.
Some explanation of the code: The program reads in an encrypted file where each letter is shifted by a certain amount (i.e With a shift of 5, every A would now be an F. This would be done for every letter). The program reads in a dictionary file as well. There are only 26 possible shifts so for each shift it will decode the file. The program will take the file for each possible shift and compare it to the dictionary file. The one that has the most in common with the dictionary file will be reprinted as the final decrypted file.
Thank you everybody!
https://drive.google.com/file/d/0B3bXyam-ubR2U2Z6dU1Ed3oxN1k/view?usp=sharing
^ There is a link to the program, dictionary, encrypted and decrypted files.
Just change line 16 :
dictionary_file=set(words_from_file("big_word_list.txt"))
So the if item in dictionary_file: is executed in constant time instead of linear time. The program runs now in 4 seconds, disabling print statements,
and changing i=highest_so_far in highest_so_far=i, and capitalizing dictionary.

Python textwrap and Reset count after everyline

Hello everyone i have an issue with this problem, the problem is i need to reset the count after every line in the file, i put a comment so you can see where i want to reset the count.
The program is suppose to cut each line after every specified lineLength.
def insert_newlines(string, afterEvery_char):
lines = []
for i in range(0, len(string), afterEvery_char):
lines.append(string[i:i+afterEvery_char])
string[:afterEvery_char] #i want to reset here to the beginning of every line to start count over
print('\n'.join(lines))
def main():
filename = input("Please enter the name of the file to be used: ")
openFile = open(filename, 'r')
file = openFile.read()
lineLength = int(input("enter a number between 10 & 20: "))
while (lineLength < 10) or (lineLength > 20) :
print("Invalid input, please try again...")
lineLength = int(input("enter a number between 10 & 20: "))
print("\nYour file contains the following text: \n" + file + "\n\n") # Prints original File to screen
print("Here is your output formated to a max of", lineLength, "characters per line: ")
insert_newlines(file, lineLength)
main()
Ex. If a file has 3 lines like this with each line having 20 chars
andhsytghfydhtbcndhg
andhsytghfydhtbcndhg
andhsytghfydhtbcndhg
after the lines are cut it should look like this
andhsytghfydhtb
cndhg
andhsytghfydhtb
cndhg
andhsytghfydhtb
cndhg
i want to RESET the count after every line in the file.
I'm not sure I understand your problem, but from your comments it appears you simply want to cut the input string (file) to lines lineLength long. That is already done in your insert_newlines(), no need for the line with comment there.
However, if you want to output lines meaning strings ending with newline char that should be no more than lineLength long, then you could simply read the file like this:
lines = []
while True:
line = openFile.readline(lineLength)
if not line:
break
if line[-1] != '\n':
line += '\n'
lines.append(line)
print(''.join(lines))
or alternatively:
lines = []
while True:
line = openFile.readline(lineLength)
if not line:
break
lines.append(line.rstrip('\n'))
print('\n'.join(lines))
I don't understand the issue here, the code seems to work just fine:
def insert_newlines(string, afterEvery_char):
lines = []
# if len(string) is 100 and afterEvery_char is 10
# then i will be equal to 0, 10, 20, ... 90
# in lines we'll have [string[0:10], ..., string[90:100]] (ie the entire string)
for i in range(0, len(string), afterEvery_char):
lines.append(string[i:i+afterEvery_char])
# resetting i here won't have any effect whatsoever
print('\n'.join(lines))
>>> insert_newlines('Beautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\n..', 10)
Beautiful
is better
than ugly.
Explicit
is better
than impli
cit.
Simpl
e is bette
r than com
plex.
..
isn't that what you want?

Counting a string within a file in python

I have 10 files with 100 random numbers named randomnumbers(1-10).py. I want to create a program which says "congratulations" when a string of 123 is found and count the number of times 123 shows up as well. I have the "congratulations" part and I have written code for the counting part but I always get zero as a result. What's wrong?
for j in range(0,10):
n = './randomnumbers' + str(j) + '.py'
s='congradulations'
z='123'
def replacemachine(n, z, s):
file = open(n, 'r')
text=file.read()
file.close()
file = open(n, 'w')
file.write(text.replace(z, s))
file.close()
print "complete"
replacemachine(n, z, s)
count = 0
if 'z' in n:
count = count + 1
else:
pass
print count
if 'z' in n is testing to see if the literal string 'z' is in the filename n. Since you only open the file within replacemachine, you can't access the file contents from outside.
Best solution would be to just count the occurrences from within replacemachine:
def replacemachine(n, z, s):
file = open(n, 'r')
text=file.read()
file.close()
if '123' in text:
print 'number of 123:', text.count('123')
file = open(n, 'w')
file.write(text.replace(z, s))
file.close()
print "complete"
Then you don't need that code after replacemachine(n, z, s).
consider:
some_file_as_string = """\
184312345294839485949182
57485348595848512493958123
5948395849258574827384123
8594857241239584958312"""
num_found = some_file_as_string.count('123')
if num_found > 0:
print('num found: {}'.format(num_found))
else:
print('no matches found')
Doing an '123' in some_file_as_string is a little wasteful, because it still needs to look through the entire string. You might as well count anyway and do something when the count returns more than 0.
You also have this
if 'z' in n:
count = count + 1
else:
pass
print count
Which is asking if the string 'z' is present, you should be checking for z the variable instead (without the quote)

Categories