Python not reading file/ executing code properly - python-3.x

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.

Related

Is there a function from terminal that removes repetition and concatenates the output on the same line?

With this input
x 1
x 2
x 3
y 1
y 2
y 3
I'd like to have this output
x 1;2;3
y 1;2;3
Thank you in advance,
Simone
If by terminal you mean something natively built in you might not be in much luck, however you could run a python file from the terminal which could do want you want and more. If having a standalone file isn't possible then you can always run python in REPL mode for purely terminal usage.
If you have python installed all you would need to do to access REPL would be "py" and you could manually setup a processor. If you can use a file then something like this below should be able to take any input text and output the formatted text to the terminal.
file = open("data.txt","r")
lines = file.readlines()
same_starts = {}
#parse each line in the file and get the starting and trailing data for sorting
for line in lines:
#remove trailing/leading whitesapce and newlines
line_norm = line.strip()#.replace('\n','')
#splits data by the first space in the line
#formatting errors make the line get skipped
try:
data_split = line_norm.split(' ')
start = data_split[0]
end = data_split[1]
except:
continue
#check if dictionary same_starts already has this start
if same_starts.get(start):
same_starts[start].append(end)
else:
#add new list with first element being this ending
same_starts[start] = [end]
#print(same_starts)
#format the final data into the needed output
final_output = ""
for key in same_starts:
text = key + ' '
for element in same_starts[key]:
text += element + ";"
final_output += text + '\n'
print(final_output)
NOTE: final_output is the text in the final formatting
assuming you have python installed then this file would only need to be run with the current directory being the folder where it is stored along with a text file called "data.txt" in the same folder which contains the starting values you want processed. Then you would do "py FILE_NAME.ex" ensuring you replace FILE_NAME.ex with the exact same name as the python file, extension included.

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.

Python writing to text-file does not work sometimes

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.

Put a character at the start of a line in a file?

I am making a song title guessing game, where the songs are fetched from a file, one is selected at random and only the first letter of each word is printed. I am at the stage where this works but I am unsure as to how you stop one of the songs repeating without removing it altogether from the file together. My idea was the print a hashkey in front of the line, and then when it goes back round to the start check if there is a hash. if there is a hashkey, it will select another song from the list. And then at the end of the program when the user gets a guess wrong, I will strip the file of all hashkeys. I am stuck on the part where you actually insert the hashkey. So far the code goes like this:
file.replace(random_song, ("#") + random_song)
When I use this code, Python doesn't display any errors but it also doesn't change the code.
If someone can give me a pointer or suggest a more efficient way of doing it then I would be grateful
I am assuming that the flow of inserting # is as follows:
def insertHash(filepath, song):
with open(filepath, 'r') as f:
lines = f.read()
lines.replace(song, ('#') + song)
with open(filepath, 'w') as f:
f.write(lines)
I think you are missing assigning the replace() back to the string. Replacing the replace line with lines = lines.replace(song, ('#') + song) should solve the issue.
Besides, you can use a set to store the songs that are already displayed to the user. Whenever you select a song, check if it already in the set. If it is, choose another. If not, insert it and display. That way, you won't be writing to a file every time.
shown_songs = set()
def isSongShown(song):
return song in shown_songs
def insertSong(song):
shown_songs.add(song)
if not isSongShown(song):
insertSong()
# display the song
else:
# select a new song
Hope this helps!

for loop and file saving

I am using Jupyter and which is working on pyspark(python).
I have used "for" loop to iterate the process and trying to save the file after each iteration.
for example:
name = "mea"
for i in range(2):
print "name[i]"
i +=1
and output is:
name[i]
name[i]
this above algorithm is the short explaination related to the main algorithm that i am working on.
the problem is it is giving an output name[i] and I want it to give me name1 and for second iteration name[2].
I need to use " " because i wanted to save my file to specific folder and i need to speacify the path in " ". So after firsdt iteration it should save the file as name1 and after second iteration it should save the file as name[2].
enter image description here
so from image in my actual algorithm, result is the output that i am getiing after each for loop iteration and for each output, i wanted to save it in new files like result[0],result1,result[2] instead of result[i],result[i],result[i]. because the latter one, it is replacing the file to the old one.
I guess it has nothing specific to pyspark that you are trying to achieve. As per your example, what you need is - use of variable in strings,
so this will suffice for your example:
name = "mea"
for i in range(2):
print "name[%s]" % i
i +=1
You can modify your print statement as follows
print "name[" + str(i) + "]"

Resources