FileName = input("Please enter the name of your text file: ")
APPEND = "a"
WRITE = "w"
File = (FileName + ".txt")
List = []
Name = " "
while Name != "DONE" :
Name = input("Please enter the guest name (Enter DONE if there is no more names) : ").upper()
List.append(Name)
List.remove("DONE")
print("The guests list in alphabetical order, and it will save in " + FileName + " :")
List.sort()
for U in List :
print(U)
File = open(FileName , mode = APPEND)
File.write(U)
File.close()
print("File written successfully.")
Ok guys, I am sorry that I am asking this question over and over, but it annoys me. I don't see any bugs through the code, but the list from the text file ONLY APPEARS ONE NAME. Thanks!
I believe what you are looking for is this:
with open(FileName , mode = APPEND) as f:
for U in List :
print(U)
f.write(U)
f.write("\n")
print("File written successfully.")
using with will allow you to open the file, and python with automatically close it for you should an exception occur while it's in use. You want to open the file before you enter your loop, then append within the loop, and finally, print your success message after closing the file (outside the with). Indentation is important! :)
According to the indentation I see above, you are calling the File open, File write, and File close methods after the loop for U in List. So only the last name will get appended to the file.
(Of course, maybe your indentation is wrong above...)
You're printing the iteration variable 'U' each time, not saving it anywhere. Write the 'U' variable each time to a file and it should work.
Related
for i in range(0,5):
f = open("StudentRecords.txt", "a")
try:
f.write(input("Name: ")+"\n")
f.write(str(int(input("ID: ")))+"\n")
f.write(str(float(input("GPA: ")))+"\n")
except ValueError:
print("Error: You entered a String for ID or GPA.")
f.close()
Here for example if I tried to write a string for GPA, I will catch the error and the program will move on, but the Name and ID of the same iteration will still be written
I want it to only write if all the 3 data are valid.
As the comments said, the best approach is to validate all the data before writing anything. But if you really need to undo, you can do it by saving the file position before each record, seeking back to it, and truncating to remove everything written after.
And rather than reopening the file for each record, you should open it once before the loop. Use with to close it automatically when the block is finished.
with open("StudentRecords.txt", "w") as f:
for i in range(0,5):
try:
filepos = f.tell()
f.write(input("Name: ")+"\n")
f.write(str(int(input("ID: ")))+"\n")
f.write(str(float(input("GPA: ")))+"\n")
except ValueError:
print("Error: You entered a String for ID or GPA.")
f.seek(filepos)
f.truncate()
The simple solution is to save the inputs in variables first, and then save to file.
for i in range(0,5):
f = open("StudentRecords.txt", "a")
try:
name = input("Name: ")+"\n"
ID = str(int(input("ID: ")))+"\n"
GPA = str(float(input("GPA: ")))+"\n"
f.write(name + ID + GPA)
except ValueError:
print("Error: You entered a String for ID or GPA.")
f.close()
That being said, I would suggest updating the code a little more:
for i in range(0,5):
name = input("Name: ") + "\n"
try:
ID = str(int(input("ID: "))) + "\n"
GPA = str(float(input("GPA: "))) + "\n"
with open("StudentRecords.txt", "a") as f:
f.write(name + ID + GPA)
except ValueError:
print("Error: You entered a String for ID or GPA.")
Using with means you won't have to deal with the f.close(), among other things, and so you won't forget it. And since the name = ... line doesn't seem to need a try-except block, we can move it outside.
Others have shown you a way to validate your data, but right now the program just stops if the user makes a mistake. You really want some way for them to correct their error and continue.
To put this in your main routine would require a separate loop and try/except structure for each number, which isn't too bad right now with two values, but gets unwieldy as you add more.
So instead of repeating ourselves, let's write a function that repeats until the user enters a valid number. We can pass in the type of number we want (int or float).
def inputnum(prompt, T=float):
while True:
try:
return T(input(prompt))
except ValueError:
print(">>> You entered an nvalid number. Please try again.")
Then call that function to get your numbers (combined with some other small improvements):
with open("StudentRecords.txt", "a") as f:
for i in range(5):
name = input("Name: ")
ID = inputnum("ID: ", int)
GPA = inputnum("GPA: ", float)
f.write(f"{name}\n{ID}\n{GPA}\n")
My code pretty much asks user input and a pre made text which it prints to the .txt file. I want to add the character calculator to print into the file, not as a print. Is it possible?
input = input(str("Type something: "))
file = open("harjoitus.txt", "w")
file.write(str("This code is here automatically.\n"))
file.write(str(input))
file.write(str("\n",))
file.close()
with open("harjoitus.txt", 'r') as file:
text = file.read().strip().split()
len_chars = sum(len(word) for word in text)
print(len_chars)
This pretty much prints the amount of characters as print not to the text file how I want it. Is it possible to edit this somehow that it prints the character amount straight to the file and not as a print?
First before you go into this appending, take a look at how many places you are calling str() its unnecessary most of these values are already stings and ready to be written. Also avoid variable names like input that have preassigned purposes in python. But to add this count to the end, collections.Counter is an option, you should open the file as a append. Then you can add this number to the end of your file.
from collections import Counter
user = input("Type something: ")
with open('harjoitus.txt', 'w') as f:
f.write("This code is here automatically.\n")
f.write(user)
f.write("\n")
with open('harjoitus.txt', 'r') as f:
content = f.read()
c = Counter(content)
tot = sum(c.values())
with open('harjoitus.txt', 'a') as f:
f.write(str(tot))
chrx#chrx:~/python/stackoverflow/10.11$ python3.7 stack.py
Type something: vash
chrx#chrx:~/python/stackoverflow/10.11$ cat harjoitus.txt
This code is here automatically.
vash
38
I am not able to add a number to my list that i have in a text file and don't know how to.
Code so far:
def add_player_points():
# Allows the user to add a points onto the players information.
L = open("players.txt","r+")
name = raw_input("\n\tPlease enter the name of the player whose points you wish to add: ")
for line in L:
s = line.strip()
string = s.split(",")
if name == string[0]:
opponent = raw_input("\n\t Enter the name of the opponent: ")
points = raw_input("\n\t Enter how many points you would like to add?: ")
new_points = string[7] + points
L.close()
This is a sample of a key in the text file. There are about 100 in the file:
Joe,Bloggs,J.bloggs#anemailaddress.com,01269 512355, 1, 0, 0, 0,
^
The value that i would like this number to be added to is the 0 besides the number already in there, indicated by an arrow below it. The text file is called players.txt as shown.
A full code answer would be helpful.
I didn't like what i wrote earlier, and the use case isn't optimal for fileinput. I took a similar piece of code from the sources and suited it for your needs.
Notice that for each line you modify, you are re-writing an entire file. I strongly suggest changing the way you handle data if performance is a concern.
This code works tho.
from tempfile import mkstemp
from shutil import move
from os import remove, close
def add_player_points():
file_path = "test.txt"
name = raw_input("\n\tPlease enter the name of the player whose points you wish to add: ")
#Create temp file
fh, abs_path = mkstemp()
with open(abs_path,'w') as new_file:
with open(file_path) as old_file:
for line in old_file:
stripped_line = line.strip()
split_string = stripped_line.split(",")
print name == split_string[0]
if name == split_string[0]:
opponent = raw_input("\n\t Enter the name of the opponent: ")
points = raw_input("\n\t Enter how many points you would like to add?: ")
temp = int(split_string[5]) + int(points) # fool proofing the code
split_string[5] = str(temp)
stripped_line = ','.join(split_string)# line you shove back into the file.
print stripped_line
new_file.write(stripped_line +'\n')
else:
new_file.write(line)
close(fh)
#Remove original file
remove(file_path)
#Move new file
move(abs_path, file_path)
Search and replace a line in a file in Python
Editing specific line in text file in python
You wouldn't expect it to be that big of an issue, but it is.
Another tip: might wanna check the module csv - it might be smarter for file editing than what i showed here.
2 issues, first you're never saving your changes to the file. You need to build the string and then save it at the end with L.write("your new string"). Second, you need to cast the points to ints before adding them, change
new_points = string[7] + points
to
new_points = int(string[7]) + int(points)
Edit: Fixed the syntax as mentioned in the comments
The following function is a part of my future program, a library program. This particular function is supposed to fetch books from a text file, and if the user desires, "loan" them and thereby adding a string "(LOANED)" after the author of the book. The books are sorted by title first, followed by a comma and a space (, ) and then the author of the book. What I want to do is to just, simply, add a "(LOANED)" string after the author of the book in the text file. However, when I try this the (LOANED) string just ends up on a different line (one line below) from where I want it to be, and it's driving me nuts.
def lend_book(title):
f = open("booksbytitle.txt", "r+")
d={}
#splits the registry up into a dictionary with the book title as key and the book author as value to that key
for i in f:
x=i.split(",")
a=x[0]
b=x[1]
d[a]=b[0:(len(b))]
#checks if the title is in the dictionary, else skips down and quits the function
if title in d:
print("\n", title, "is available in the library and is written by"+d[title])
saved_author = d[title][1:]
while True:
alternative=input("Do you want to lend this book? [y/n] ")
if alternative.lower() == "y":
print("The book is now loaned ")
break
elif alternative.lower() == "n":
print("Okay, going back to main menu.. ")
break
else:
print("That is not a valid choice. Type 'y' or 'n'")
f.close()
loaned="(LOANED)"
f=open("booksbytitle.txt", "r+")
z=f.readlines()
f.seek(0)
for i in z:
if title not in i:
f.write(i)
f.write("\n" + title + ", " + saved_author + loaned)
f.truncate()
f.close()
#clears the program of unintented blank lines
fh = open("booksbytitle.txt", "r")
lines = fh.readlines()
fh.close()
keep = []
for line in lines:
if not line.isspace():
keep.append(line)
fh = open("booksbytitle.txt", "w")
fh.write("".join(keep))
fh.close()
else:
print("There wasnt a book by that name found in the registry")
It's hard to tell with the screwed-up formatting and the meaningless one-letter variable names, but I suspect the problem is this:
When you iterate the lines of a file, like for i in f:, each one ends with a newline character ('\n').
When you split(",") each one, the last split-off string still contains that newline.
So ultimately, when you try to stick that string in the middle of a string, it's got a newline at the end, which means you end up with a newline in the middle of the string.
To fix this, use rstrip on each line as you read them in:
for i in f:
x = i.rstrip().split(",")
This may mean that you're now missing newlines in your output to the file. You were expecting to get them for free, but now you don't. So you may have to do something like this:
f.write("\n" + title + ", " + saved_author + loaned + "\n")
However, maybe not. I notice that for some reason you're putting a "\n" at the start of every line, so this may just mean you end up with extra blank lines between each line (along with the extra blank line at the start of your file, which is inherent in using "\n" +).
You could use rstrip() on the strings to remove the right spaces (newlines),
and then join over "\n" instead of the empty string.
PS: You can write a bit of this code much simpler, by the way. For instance, you can just get the lines in the file all at once, filter out the empty ones and rstrip all at the same time, like this:
with open(filename, "r") as handler:
keep = [line.rstrip() for line in handler if line]
(The 'with' takes care of automatically closing the file after the indented block, then there's a list comprehension, and the open file object "handler" gives you the lines when iterating over it.)
Here's the code for recording victory/defeat:
def guessingTime(answer):
vdfile = open("victorydefeat.txt", "w")
now = time.asctime(time.localtime(time.time()))
print("That's 20! Time to guess.\n")
guess = input("Is it a(n): ")
if guess.lower() == answer:
print("You got it! Congratulations!")
vdfile.write("Victory achieved on ")
vdfile.write(now)
else:
print("Sorry, but the answer was", answer)
vdfile.write("Defeated on ")
vdfile.write(now)
vdfile.close()
Thing is every time it records it just overwrites the first line of the text file. How do I get it to record every victory/defeat the user gets?
Thing is every time it records it just overwrites the first line of
the text file.
This is happening because when you open the file you gave mode "w". On write mode, when you start writing something in the file you start from the beginning, as a result the new text replaces the old one. You need to set append mode "a"
Here is an example:
f = open('myfile','a+')
f.write("a line\n")
f.write("a new line\n")
f.close()
We open the file in append mode,
write the first line and add a new line character , then write second line , finally we close the file