Python writing to text-file does not work sometimes - python-3.x

I have a function that writes log-texts into a text-file:
from time import strftime, localtime
def log(Text):
with open("Log.txt", 'a') as log_file:
log_file.write(strftime('%H:%M:%S',localtime()) + ' -- ' + Text + '\n')
On the first run, when Log.txt is not yet created, this code works: it creates a file with called 'Log.txt' and when I open it I can see the text that I gave as input.
After that however it doesn't work anymore. When this file exists and I give a new text as input to write to it, it does not do that. I also checked the time of last modification of the file itself: the code doesn't even touch the text-file, since the modicification time remains the same.
I hope someone shows what's wrong here.
Regards, Ganesh

If your code worked before saving the txt file, I'm not sure but, because I had a problem simulating yours, take a look at your txt file and see if there was any change in the file format, UTF-8 or similar. Perhaps this is the reason for the problem. Hope this helps. Good luck.

This code works perfect, I test it in 2 ways:
1st way: example1.py :
from time import strftime, localtime
def log(Text):
with open("Log.txt", 'a') as log_file:
log_file.write(strftime('%H:%M:%S',localtime()) + ' -- ' + Text + '\n')
log("Hello world!")
I just change the message added at the last line every time I test it.
2nd way: example2.py :
from time import strftime, localtime
def log(Text):
with open("Log.txt", 'a') as log_file:
log_file.write(strftime('%H:%M:%S',localtime()) + ' -- ' + Text + '\n')
while True:
try:
info = input("enter your information: ")
log(info)
except KeyboardInterrupt:
break
input("\nEnter to close")
In this case I add information to the .txt file many times without closing the python script using exceptions and KeyboardInterrupt to close the python script. It works fine too.
Be sure to use your script having closed the previous same script because could exists a files conflict problem. specially when you are using open() funcion.

I found the problem: I define multiple paths in the code where certain files have to be saved (DataFrames and images). Somehow, the code puts the Log-file in the dictionary currently open, so the Log-file was spread over these folder-paths with bits of pieces of information.
I solved this by defining a path for the Log-file itself:
def log(Text):
current_dir = os.path.dirname(os.path.realpath(__file__))
with open(current_dir + "\\" + "Log.txt", 'a') as log_file:
log_file.write(strftime('%H:%M:%S',localtime()) + ' -- ' + Text + '\n')
Now the current dictionary is always the same and it works.

Related

Writing strings to a text file in python

I am generating some random strings in python using the following code:
import string
import random
import os
passphrases = []
pass_file = open("Passphrases2.txt","w")
os.chmod("Passphrases2.txt",0o777)
for _ in range(100):
st = "".join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for i in range(random.randint(8,16)))
passphrases.append(st)
print(st)
for p in passphrases:
pass_file.write("\n"%p)
I want these strings to be stored in a text file in the same directory as the python code.
When I execute this code, a file named Passphrases2.txt gets created but it is empty in the first execution.
When I execute the same code for the second time, the file gets updated with the strings that were generated during the first execution, then on running the third time, it gets updated with the strings generated in the second execution and so on. I am unable to figure out why this is happening.
You need to .close() file or use with statement.
This is including some optimizations:
import os
from random import choice, randint
import string
alphabet = string.ascii_lowercase + string.ascii_uppercase + string.digits
with open("Passphrases2.txt", "w") as pass_file:
for _ in range(1000):
st = "".join(choice(alphabet) for i in range(randint(8, 16)))
print(st)
pass_file.write(f"{st}\n")
os.chmod("Passphrases2.txt", 0o777)
import string
import random
import os
passphrases = []
for _ in range(100):
st = "".join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for i in range(random.randint(8,16)))
passphrases.append(st)
print(st)
with open("Passphrases2.txt","w") as pass_file:
for p in passphrases:
pass_file.write("%s\n" %p)
It's because you are missing pass_file.close() at the end to properly close the file handle after finishing to write. Without properly closing, the write to file was not fully flushed and saved. It's like you are typing something in Notepad but have not yet hit the save button.
Then on the 2nd run, pass_file = open("Passphrases2.txt","w"), reopening the file handle will close the previous handle; this will act like pass_file.close() for the previous run and thus you are seeing previous data on 2nd run and so on.
You may add pass_file.close() after the last for loop or use the Python with statement to ensure file handle open is being closed properly after it is done.
You need to close the file in the end 😀

Updating values in an external file only works if I restart the shell window

Hi there and thank you in advance for your response! I'm very new to python so please keep that in mind as you read through this, thanks!
So I've been working on some code for a very basic game using python (just for practice) I've written out a function that opens another file, selects a variable from it and adjusts that variable by an amount or if it's a string changes it into another string, the funtion looks like this.
def ovr(file, target, change):
with open(file, "r+") as open_file:
opened = open_file.readlines()
open_file.close()
with open(file, "w+") as open_file:
position = []
for appended_list, element in enumerate(opened):
if target in element:
position.append(appended_list)
if type(change) == int:
opened[position[0]] = (str(target)) + (" = ") + (str(change)) + (str("\n"))
open_file.writelines(opened)
open_file.close()
else:
opened[position[0]] = (str(target)) + (" = ") + ("'") + (str(change)) + ("'") + (str("\n"))
open_file.writelines(opened)
open_file.close()
for loop in range(5):
ovr(file = "test.py", target = "gold", change = gold + 1)
At the end I have basic loop that should re-write my file 5 times, each time increasing the amount of gold by 1. If I write this ovr() funtion outside of the loop and just run the program over and over it works just fine increasing the number in the external file by 1 each time.
Edit: I should mention that as it stands if I run this loop the value of gold increases by 1. if I close the shell and rerun the loop it increases by 1 again becoming 2. If I change the loop to happen any number of times it only ever increases the value of gold by 1.
Edit 2: I found a truly horrific way of fixing this isssue, if anyone has a better way for the love of god please let me know, code below.
for loop in range(3):
ovr(file = "test.py", target = "gold", change = test.gold + 1)
reload(test)
sleep(1)
print(test.gold)
The sleep part is because it takes longer to rewrite the file then it does to run the full loop.
you can go for a workaround and write your new inforamtion into a file called: file1
So you can use ur working loop outside of the write file. Anfter using your Loop you can just change the content of your file by the following steps.
This is how you dont need to rewrite your loop and still can change your file content.
first step:
with open('file.text', 'r') as input_file, open('file1.txt', 'w') as output_file:
for line in input_file:
output_file.write(line)
second step:
with open('file1.tex', 'r') as input_file, open('file.tex', 'w') as output_file:
for line in input_file:
if line.strip() == '(text'+(string of old value of variable)+'text)':
output_file.write('text'+(string of new value of variable)+' ')
else:
output_file.write(line)
then you have updated your text file.

How to open a file only for appending in python 3

I want a try/except clause to take different actions if a file has not yet been created, versus if something's going to be appended to it. I've tried writing the following code:
try:
print("Appended!")
dip_line = "|".join(DATA)
dip_line = "|" + dip_line + "\n"
with open(OUTPUT_LOCATION, "a") as filey: # also tried "a+", no luck
filey.write(dip_line)
except:
print("Created!")
DATA.insert(0, SYS_COMMENT)
dip_line = "|".join(DATA)
dip_line += "\n"
with open(OUTPUT_LOCATION, "w") as filey:
filey.write(dip_line)
How can I ensure that the except clause gets run when no [OUTPUT_LOCATION] exists? Thanks for your consideration!
You can open the file in r+ (read-write) mode instead so it would raise an exception if the file does not already exist, and then use the seek method to point the file position to the end of the file for appending:
with open(OUTPUT_LOCATION, "r+") as filey:
filey.seek(0, 2)
filey.write(dip_line)

Python not reading file/ executing code properly

I have a strange problem which I'm not sure why is occurring.
In a game, I type a command (::pos) which writes the positional coords to a .txt file. When I try automate this process (using win32com to type the command) and read the file, the previous coords are displayed instead of the current ones. This makes no sense as I update the coords before displaying them:
def add(self):
id = self.myTextInput.text()
shell.AppActivate('App title')
# Update position file
shell.SendKeys('::pos')
shell.SendKeys('{ENTER}')
# Add object
shell.SendKeys('::object ' + id + ' 0')
shell.SendKeys('{ENTER}')
# Read position
with open('.txt file path', 'r') as f:
f = f.read().split()
self.listWidget.addItem(id + ' ' + f[1] + ' ' + f[3] + ' 0')
The code is executed upon pressing a button 'add'. The weird thing is that it all works fine if I create a separate button and function called 'updatePos' (which I press before pressing 'add') but doesn't work if I just call the updatePos() function within add. I have also tried using sleeps to stagger commands but that seems to work strangely too (sleeps block of code before it, not sure if its the shell commands messing with it?).
I think the code is executing in an abnormal order perhaps? E.g. opening and reading text file before the position is updated - but not sure why this is happening.
You need to close the file before you can read in the changes.
try adding f.close() to the end of this.

F.write doesn't work

import os,sys
import time
from colorama import Fore,Back,Style,init
init(autoreset=True)
appdata_path = os.path.join(os.getenv("APPDATA"), os.pardir)
subpath = "Local/sieosp/filesav2292.sav"
f = open(os.path.join(appdata_path, subpath), "r+")
lines=f.readlines()
a1=int (lines[116])
a2=int (lines[120])
a3=int (lines[124])
b4=int (lines[128])
c5=int (lines[132])
d6=int (lines[136])
e7=int (lines[140])
d8=int (lines[144])
d9=int (lines[148])
d10=int (lines[152])
d11=int (lines[156])
d12=int (lines[160])
total=int (a1+a2+a3+b4+c5+d6+e7+d8+d9+d10+d11+d12)
if (total)==(12):
print("You already own every character")
else:
with f:
userinputvalue=int (input("Type 1 if you want to unlock every character,or 0 if you would like to close this \n"))
if(userinputvalue)==1:
lines[156]=f.write("1\n")
lines[116]=f.write("1\n")
lines[120]=f.write("1\n")
lines[124]=f.write("1\n")
lines[128]=f.write("1\n")
lines[132]=f.write("1\n")
lines[136]=f.write("1\n")
lines[140]=f.write("1\n")
lines[144]=f.write("1\n")
lines[148]=f.write("1\n")
lines[152]=f.write("1\n")
lines[160]=f.write("1\n")
else:
print("Closing")
time.sleep(1)
So this should work,right? Don't know why f.write doesn't write 1 to my file. am i using it very wrong? Searched around google for some more info but I didnt understand a thing :/ tried to use f.write as f.readlines but no luck. thanks
It looks like you dont open the file in write mode, only in read mode.
f = open(os.path.join(appdata_path, subpath), "r+")
Change the "r" to a "w"
You have opened the file with "r+", so the file is even writable, the problem is that if you open a file with "r+" you have to manage the pointer in the file, otherwise the string will be append at the end.
In order to manage it you have to use the function f.seek(offset, from_what) like described here Input and Output.
For example in this code I change only the first line of the file:
f = open("File/Path/file.txt", "r+")
f.seek(0,0)
f.write("something")
f.close()
You also use line[N] = f.write("something"), careful to use it in this way, because it returns the number of characters wrote, not the characters wrote ;)

Resources