How to automatically update a list of filenames in Python - python

I have a list of filenames: files = ["untitled.txt", "example.txt", "alphabet.txt"]
I also have a function to create a new file:
def create_file(file):
"""Creates a new file."""
with open(file, 'w') as nf:
is_first_line = True
while True:
line = input("Line? (Type 'q' to quit.) ")
if line == "q":
# Detects if the user wants to quuit.
time.sleep(5)
sys.exit()
else:
line = line + "\n"
if is_first_line == False:
nf.write(line)
else:
nf.write(line)
is_first_line = False
I want the list to update itself after the file is created. However, if I just filenames.append() it,
I realized that it would only update itself for the duration of the program. Does anybody know how to do this? Is this possible in Python?

"Is this possible in Python?" -> This has nothing to do with limitations of the language you chose to solve your problem. What you want here is persistence. You could just store the list of files in a text file. Instead of hardcoding the list in your code your program would then read the content every time it is run.
This code could get you started:
with open("files.txt") as infile:
files = [f.strip() for f in infile.readlines()]
print(f"files: {files}")
# here do some stuff and create file 'new_file'
new_file = 'a_new_file.txt'
files.append(new_file)
###
with open("files.txt", "w") as outfile:
outfile.write("\n".join(files))

Related

any way to print a specific string based off of a line of a file?

so I'm currently trying to print a list of cards in a text based card battler I'm making for a school project, and I'm wondering if I can get some help. I'm trying to print something different if a line in a file is 0 or 1, but I can't figure it out. thanks if you can help
def mainfunc():
while i<cardlist:
#if it's zero, do this
print("the card this line represents")
#if it's one, do this
print("locked")
#else, becasue if it's else then you're at the end of the file
print("your deck:")
#print your current deck
print("which card do you want to add?")
print(filelinecount("RIPScards"))
This is what I would do (UPDATED):
# For preventing unwanted behavior if this file ever gets imported in another:
if __name__ == "__main__":
with open(**insert file path here**, 'r') as f:
for line in f:
if line.strip() == "0":
print("the card this line represents")
elif line.strip() == "1":
print("locked")
else:
print("your deck")
print("which card do you want to add?")
print(filelinecount("RIPScards"))
You can read a file line-by-line with it open like so:
with open(**file path**, 'r') as f:
for line in f:
# Do stuff with the line here
Or you can read all the lines one time and close the file, then do stuff with the lines, like so:
f = open(**file name here**, 'r')
$lines = f.readlines()
f.close() # Make sure to close it, 'with open' method automatically does that for you, but manually opening it (like in this example) will not do it for you!
# Do stuff with it:
for line in lines:
# Do something with the line
Hopefully that helps!

Unable to write variables (input) to text file

I'm currently writing a simple text editor in python 3.8, I am unable to write the contents of the user input into a file though. When I open the text file in notepad++ a message pops up saying - "This file has been modified by another program, would you like to reload it?". I've tried writing the input to the file as an array but that does not work.
loop = True
#Getting file name
filename = input('Filename(Include file extensions) : ')
#Getting What To Write To File
while loop == True:
text = input('>> ')
if "EXIT" in text:
loop = False
while loop == False:
#writing to file
saveFile = open(filename, 'w')
saveFile.write(text)
saveFile.close()
Your loop structure is a bit off. There is no need for using "flag" variables. A more pythonic way is while True: ... break. So your code should look more like this:
#Getting file name
filename = input('Filename(Include file extensions) : ')
#Getting What To Write To File
while True:
text = input('>> ')
if "EXIT" in text:
break
#writing to file
with open(filename, 'w') as saveFile:
saveFile.write(text)
Of course this will only write the last input with the EXIT, so you might want to make text a list or a queue to perform as a buffer, or just dump directly to the file:
#Getting file name
filename = input('Filename(Include file extensions) : ')
#Getting What To Write To File
with open(filename, 'w') as saveFile:
while True:
text = input('>> ')
saveFile.write(text)
if "EXIT" in text:
break

Python, checking a .txt file for a filename

I,m a extreme noobie...
I making a dowsing program.
I have code that randomly picks a image file from a directory. (I can do this)
i need to know how to write the file path of the image to a txt file. (simple database)
Then next time read the txt file to see if that file has been selected in the last 100 entries, if it has been selected, how to make it go back to the random module and try again until it gets one that has yet to be selected in the 100 times.
Thanks
sample
os.chdir('C:\landscapes\pics')
left1 = random.choice(os.listdir("C:\landscapes\pics"))
# TEST FILE
print(left1)
os.chdir('C:\landscapes')
logfile = open('test.txt', 'r')
loglist = logfile.readlines()
logfile.close()
found = False
for line in loglist:
if str(left1) in line:
print ("Found it")
found = True
if not found:
logfile = open('test.txt', 'a')
logfile.write(str(left1)+"\n")
logfile.close()
print ("Not Found!")
I,m able to tell if the file is found or not.
I,m just at a loss of what to do next, I think I need kind of While loop?
You don't need a while loop. Instead, this can be achieved with self referencing methods, which create a sort-of, infinite loop, until a certain condition is met (i.e.: found = False). Also, I took out the references to os.chdir as you don't need those if you specify the directory you are attempting to search in the path of os.listdir, and open().
def choose_random_file():
return random.choice(os.listdir("C:\landscapes\pics"))
def validate_randomness( random_file ):
logfile = open('C:\landscapes\test.txt', 'r')
loglist = logfile.readlines()
logfile.close()
found = False
for line in loglist:
if str( random_file ) in line:
print ("Found it")
found = True
# we found the file, now break out of the for loop
break
# Check if we found the file
if found:
# If we found the file name, then circle-back to pick another file
random_file = choose_random_file()
# Now validate that the new pick is in the test.txt file again
validate_randomness( random_file )
if not found:
logfile = open('test.txt', 'a')
logfile.write(str( random_file )+"\n")
logfile.close()
print ("Not Found!")
random_file = choose_random_file()
validate_randomness( random_file )
Hope this helps point you in the right direction. Let me know if something doesn't work.

Read and write data to new file Python

I have to write substrings to a new file by reading from another file. The problem I am facing is that it only writes the last found substring.
Here is what I've tried.
def get_fasta(site):
with open('file1.txt', 'r') as myfile:
data=myfile.read()
site = site-1
str1 = data[site:site+1+20]
temp = data[site-20:site]
final_sequence = temp+str1
with open('positive_results_sequences.txt', 'w') as my_new_file:
my_new_file.write(final_sequence + '\n')
def main():
# iterate over the list of IDS
for k,v in zip(site_id_list):
get_fasta(v)
if __name__ == '__main__':
main()
That's because you've opened the inner file in w mode which recreates the file each time. So the end result is that only last write persists. You want to use a mode (which stands for "append").
Also there are some other issues with your code. For example you open and close both files in each loop iteration. You should move file opening code outside and pass them as parameters:
def main():
with open('file1.txt', 'r') as myfile:
with open('positive_results_sequences.txt', 'a') as my_new_file:
for k,v in zip(site_id_list):
get_fasta(v, myfile, my_new_file)

Write to file python - Linebreak issue (\n)

I have a problem where the function just overwrites the line thats already there in a .txt file. The function is supposed to write a highscore to a file when the game quits (I have made a snake game by following a youtube tutorial). I can't quite figure out why it won't start on a new line, can anyone please explain the logic behind it, and how I fix it? I read somewhere that instead of "w" in f.open(), I should type "rb" or something. Since I'm kinda new to this "writing-to-file" thingy, I find it difficult.
Also, I want to sort the highscores from highest to lowest in the file (in other words, sort finalScore from highest to lowest). I have no idea how I should go on and code that, so I'd appreicate some help. You see, I want to print out the current highscores to the console (in order to make a scoreboad)
Heres the code:
import random
import time
name = "Andreas"
finalScore = random.randint(1,10)
def scoreToFile(finalScore):
#Has to be generated here, since we need the exact current time
currentTime = time.strftime("%c")
print("Sucsessfully logged score (finalScore) to highscores.txt")
f = open("highscores.txt", "w")
#fileOutput = [(currentTime, ":", name, "-", finalScore)]
fileOutput = [(finalScore, "-", name, currentTime)]
for t in fileOutput:
line = ' '.join(str(x) for x in t)
f.write(line + "\n")
f.close()
scoreToFile(finalScore)
Anyways, merry christmas my fellow python geeks! :D
1) one option is to open the file in append mode.
replace:
f = open("highscores.txt", "w")
with:
f = open("highscores.txt", "a")
2) another option is to replace this block,
f = open("highscores.txt", "w")
#fileOutput = [(currentTime, ":", name, "-", finalScore)]
fileOutput = [(finalScore, "-", name, currentTime)]
for t in fileOutput:
line = ' '.join(str(x) for x in t)
myfile.write(line + "\n")
f.close()
and use a with style
with open("highscores.txt", "a") as myfile:
#fileOutput = [(currentTime, ":", name, "-", finalScore)]
fileOutput = [(finalScore, "-", name, currentTime)]
for t in fileOutput:
line = ' '.join(str(x) for x in t)
myfile.write(line + "\n")
I prefer the second style as it is more safe and clean.
Mode w overwrites an existing file; mode 'a' appends to it. Also, the best way to handle a file is usually with the with statement, which ensures the closing on your behalf; so:
fileOutput = [(finalScore, "-", name, currentTime)]
with open("highscores.txt", "a") as f:
for t in fileOutput:
line = ' '.join(str(x) for x in t)
f.write(line + "\n")
For sorting, you need be able to extract the final score as a number from a line:
def minus_score(line):
return -int(line.split()[0])
then the total work will be done as:
def sorted_by_score():
with open("highscores.txt", "r") as f:
result = list(f)
return sorted(result, key=minus_score)
This will give you a list lines sorted in ascending order of score (the latter's the reason score is negating the number, though one might also choose to have it just return the number and reverse the sorting), for you to loop on and further process.
Added: so on the OP's request here's how the whole program might be (assuming the existence of a function that either plays a game and returns player name and final score, or else returns None when no more games are to be played and the program must exit).
import time
def play_game():
""" play a game and return name, finalscore;
return None to mean no more games, program finished.
THIS function you'd better code yourself!-)
"""
def scoreToFile(name, finalScore):
""" Add a name and score to the high-scores file. """
currentTime = time.strftime("%c")
fileOutput = finalScore, "-", name, currentTime
line = ' '.join(str(x) for x in fileOutput)
with open("highscores.txt", "a") as f:
f.write(line + "\n")
def minus_score(line):
""" just for sorting purposes, not called directly. """
return -int(line.split()[0])
def sorted_by_score():
""" return list of score lines sorted in descending order of score. """
with open("highscores.txt", "r") as f:
return sorted(f, key=minus_score)
def main():
while True:
game_result = play_game()
if game_result is None: break
scoreToFile(*game_result)
for line in sorted_by_score:
print(line.strip())
As others have mentioned, the problem is you're not opening the file in append mode, so it overwrites it every time rather than adding to it.
However, if you also want to keep the data in the file sorted, you do want to overwrite it each time, since the order of its contents will likely have been changed with the addition. To do that requires first reading it contents in, updating the data, and then writing it back out.
Here's a modified version of your function that does that. I also changed how the data in file is stored to what is known as Comma (or Character) Separated Values (CSV) format, because Python includes acsvmodule which makes it very easy to read, write, and do other things with such files.
import csv
import random
import time
highscores_filename = "highscores.txt"
HighScoresFirst = True # Determines sort order of data in file
def scoreToFile(name, finalScore):
currentTime = time.strftime("%c")
# Try reading scores from existing file.
try:
with open(highscores_filename, "r", newline='') as csvfile:
highscores = [row for row in csv.reader(csvfile, delimiter='-')]
except FileNotFoundError:
highscores = []
# Add this score to the end of the list.
highscores.append([str(finalScore), name, currentTime])
# Sort updated list by numeric score.
highscores.sort(key=lambda item: int(item[0]), reverse=HighScoresFirst)
# Create/rewrite highscores file from highscores list.
with open(highscores_filename, "w", newline='') as csvfile:
writer = csv.writer(csvfile, delimiter='-')
writer.writerows(highscores)
print("successfully logged score (finalScore) to highscores.txt")
# Simulate using the function several times.
name = "Name"
for i in range(1, 4):
finalScore = random.randint(1,10)
scoreToFile(name + str(i), finalScore)
time.sleep(random.randint(1,3)) # Pause so time values will vary.

Categories

Resources