Writing strings to a text file in python - python-3.x

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 😀

Related

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.

Python deleting input line

I would like to have an input loop in python 3 where the information which gets typed in gets deleted from terminal automatically (f.eks. after 3 seconds)
I know the function with \r to go back in line, but struggle with the automatic new line after input.
while True:
inputStr = (input("Add the hidden word: ")).lower()
processingTheInput(inputStr) #some sort of function using the input word
Ansi escape codes will not work the same on all terminals but this might suit your needs. The ‘\033’ is the escape character. The ‘[1A’ says go up one line and the ‘[K’ says erase to the end of this line.
prompt = 'Add the hidden word: '
inputStr = input(prompt).lower()
print ('\033[1A' + prompt + '\033[K')
You want to clear the terminal with a function
# import only system from os
from os import system, name
# import sleep to show output for some time period
from time import sleep
# define our clear function
def clear():
# for windows
if name == 'nt':
_ = system('cls')
# for mac and linux(here, os.name is 'posix')
else:
_ = system('clear')
Now you need to have a function that adds your word into a list then runs the clear function, then finally can pick a word at the end

I'm trying to 'shuffle' a folder of music and there is an error where random.choice() keeps choosing things that it is supposed to have removed

I'm trying to make a python script that renames files randomly from a list and I used numbers.remove(place) on it but it keeps choosing values that are supposed to have been removed.
I used to just use random.randint but now I have moved to choosing from a list then removing the chosen value from the list but it seems to keep choosing chosen values.
'''python
from os import chdir, listdir, rename
from random import choice
def main():
chdir('C:\\Users\\user\\Desktop\\Folders\\Music')
for f in listdir():
if f.endswith('.mp4'):
numbers = [str(x) for x in range(0, 100)]
had = []
print(f'numbers = {numbers}')
place = choice(numbers)
print(f'place = {place}')
numbers.remove(place)
print(f'numbers = {numbers}')
while place in had:
input('Place has been had.')
place = choice(numbers)
had.append(place)
name = place + '.mp4'
print(f'name = {name}')
print(f'\n\nRenaming {f} to {name}.\n\n')
try:
rename(f, name)
except FileExistsError:
pass
if __name__ == '__main__':
main()
'''
It should randomly number the files without choosing the same value for a file twice but it does that and I have no idea why.
When you call listdir() the first time, that's the same list that you're iterating over the entire time. Yes, you're changing the contents of the directory, but python doesn't really care about that because you only asked for the contents of the directory at a specific point in time - before you began modifying it.
I would do this in two separate steps:
# get the current list of files in the directory
dirlist = os.listdir()
# choose a new name for each file
to_rename = zip(
dirlist,
[f'{num}.mp4' for num in random.sample(range(100), len(dirlist))]
)
# actually rename each file
for oldname, newname in to_rename:
try:
os.rename(oldname, newname)
except FileExistsError:
pass
This method is more concise than the one you're using. First, I use random.sample() on the iterable range(100) to generate non-overlapping numbers from that range (without having to do the extra step of using had like you're doing now). I generate exactly as many as I need, and then use the built-in zip() function to bind together the original filenames with these new numbers.
Then, I do the rename() operations all at once.

add new row to numpy using realtime reading

I am using a microstacknode accelerometer and intend to save it into csv file.
while True:
numpy.loadtxt('foo.csv', delimiter=",")
raw = accelerometer.get_xyz(raw=True)
g = accelerometer.get_xyz()
ms = accelerometer.get_xyz_ms2()
a = numpy.asarray([[raw['x'],raw['y'],raw['z']]])
numpy.savetxt("foo.csv",a,delimiter=",",newline="\n")
However, the saving is only done on 1 line. Any help given? Still quite a noobie on python.
NumPy is not the best solution for this type of things.
This should do what you intend:
while True:
raw = accelerometer.get_xyz(raw=True)
fobj = open('foo.csv', 'a')
fobj.write('{},{},{}\n'.format(raw['x'], raw['y'], raw['z']))
fobj.close()
Here fobj = open('foo.csv', 'a') opens the file in append mode. So if the file already exists, the next writing will go to the end of file, keeping the data in the file.
Let's have look at your code. This line:
numpy.loadtxt('foo.csv', delimiter=",")
reads the whole file but doe not do anything with the at it read, because you don't assign to a variable. You would need to do something like this:
data = numpy.loadtxt('foo.csv', delimiter=",")
This line:
numpy.savetxt("foo.csv",a,delimiter=",",newline="\n")
Creates a new file with the name foo.csv overwriting the existing one. Therefore, you see only one line, the last one written.
This should do the same but dos not open and close the file all the time:
with open('foo.csv', 'a') as fobj:
while True:
raw = accelerometer.get_xyz(raw=True)
fobj.write('{},{},{}\n'.format(raw['x'], raw['y'], raw['z']))
The with open() opens the file with the promise to close it even in case of an exception. For example, if you break out of the while True loop with Ctrl-C.

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