I'm writing a program which has the user enter some names and it creates a file with these names. I'm using Python 3.2.
number = eval(input("How many names are there? "))
#Say the user enters 2
outfile = open('names.txt', 'w')
for i in range(number):
name = input("Enter a name >> ")
#Say the user first enters Bob
#Then the user enters Joe
print (name, file=outfile)
outfile.close()
print ("Names have been written to file")
It works but there's one problem. The file that now shows up only reads one line: "Joe". None of the other names appear, only the last one.
You have this code: -
for i in range(number):
name = input("Enter a name >> ")
#Say the user first enters Bob
#Then the user enters Joe
print (name, file=outfile)
You print statment should be inside the loop..
for i in range(number):
name = input("Enter a name >> ")
print (name, file=outfile)
Indentation! As your code is written now, the statement print (name, file=outfile) is executed once, and outside of the loop. So the last time name was set to anything is the one which remains.
To fix this, make sure that statement writing to the file is called right after it is input, and for that to happen, you should indent it as deep as the input statement, to be called as much times as the input is being taken.
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")
I have to create a game that gives the artist and the first letter of each word of the title of the song in python. The songs have to be chosen from random from an external file and the user has to guess the song.
I have made a text file with all the names and have used the readlines() function to get the songs from the text file.
The problem I have is that the input does not equal to the line of the file even when it the exact same.
Here is the code:
random_number = random.randint(0,10)
name_of_songs = open("Names of songs.txt", "r")
song = str(name_of_songs.readlines()[random_number])
name_of_songs.close()
answer = input("what is the name of the song: ")
if answer == song:
print("well done you got 3 points")
The problem of your code is here:
str(name_of_songs.readlines()[random_number])
The readlines() method will return a list of lines from the file, with a trailing '\n' at the end of all but the last lines. For example, file:
Apple
Banana
Cherry
will be returned like:
['Apple\n', 'Banana\n', 'Cherry']
So if the user inputs 'Apple', the result is 'Apple' does not equal 'Apple\n'.
You can fix the problem by using .read().splitlines(), which will return a list without '\n's.
Also, using open() and then close() is a bad practice. Instead, use a with statement:
random_number = random.randint(0,10)
with open("Names of songs.txt", "r") as name_of_songs:
song = name_of_songs.read()splitlines()[random_number] # Note that since read returns strings, there is no need to convert it to a string again
answer = input("What is the name of the song: ")
if answer == song:
print("well done you got 3 points")
code like this:
import csv
name_of_songs = open("Names of songs.txt", "r")
reader=csv.reader(name_of_songs)
for eachRow in reader:
//you will get each line here (eachRow)
import linecache
f = open("database.txt" , "r+")
password = input("What is your password? ")
for loop in range(3):
line = f.readline()
data = line.split(",")
if data[1] == password:
print(data[1]) #These are too help me understand the code
print(data[0])
b = data[0]
newpass = "Hi"
a = data[1]
line1 = linecache.getline("database.txt" ,loop+1)
print(line)
print("Password Valid\n")
write = (line1.replace(a, newpass))
write = f.write(line1.replace(a, newpass))
f.close()
I have a file which stores data separated by columns. Each new line is a different users data:
username,password,Recovery1,Answer1,Recovery2,Answer2,Recovery3,Answer3,Recovery4,Answer4,
Recovery5,Answer5,o,o,o,o,o,o,o,o,o,o,
happy,bye,o,o,o,o,o,o,o,o,o,o,
bye,happy,o,o,o,o,o,o,o,o,o,o,
THIS IS THE WANTED FILE:
username,password,Recovery1,Answer1,Recovery2,Answer2,Recovery3,Answer3,Recovery4,Answer4,
Recovery5,Answer5,o,o,o,o,o,o,o,o,o,o,
happy,Hi,o,o,o,o,o,o,o,o,o,o,
bye,happy,o,o,o,o,o,o,o,o,o,o,
I want the user to enter their password and then be able to change it. Which is the second column (e.g. data[1]). The program should then change the users password to a different one. "Hi" in this case. However, IT MUST NOT AFFECT ANOTHER USERS USERNAME AS THE PASSWORDS AND USERNAMES COULD BE THE SAME. EG. changing bye to HI in third line, should not change bye in the fourth line to Hi.
The code can append the new line, but the previous line still exists. Is this the write way to go about it? Could you help? The code should be able to change other lines password according to the users input.
Thanks in advance.
I'm trying to make a cash machine simulation.
This is my code so far:
print ("Cash Machine\n")
input("Press Enter to begin...")
card_number = int(input("Enter your card number... "))
f = open((card_number + ".txt"),"r")
lines = f.readlines()
x = lines[1]
print(x)
Currently I have a text file called 123 in my folder. Inside the file is how much money the bank account 123 has, but I am having trouble trying to open the file.
Specifically with the line 6. I get an error saying
"No such file or directory: 'card_number.txt'"
How can I make it work?
Thanks
You have to run this program in the same directory that contains the file or use the full path name.
If running in the same directory, you can use the code you have. If not, you can tweak the code like this:
Edit: you are casting your input as an integer when it needs to be a string:
input("Press Enter to begin...")
card_number = input("Enter your card number... ")
f = open(card_number + ".txt","r")
lines = f.readlines()
x = lines[1]
print(x)
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.