I am trying to add a permanent header for a text file and along with the headers there should be the corresponding information i.e:
My code snippet:
name = input ("Name: ")
age = input("Age: ")
BirthYear = input("Birth Year: ")
file = open ("info.txt", "a")
file.write ("Name Age Grade\n")
file.write ("{} / {} / {}\n".format(name, age, birthYear))
file.close()
So far the code just outputs the following into a text file :
Name Age BirthYear
name / 16 / 1999
the header is not permanently on the top of the page. The corresponding information of each header should align to the headers;
I would like it to look something like the following:
Name Age BirthYear
Sam 22 1993
Bob 21 1992
it has to be in a text file.
What about just opening the file and writing in the header and then using a new with block to loop through and write in the individual records? I came across your question as I also needed to print a header into my csv text file. Eventually I just did the following (using your example):
header = "Name, Age, BirthYear"
with open('results.txt', 'a') as f:
f.write(header + "\n")
f.close
with open('results.txt', 'a') as f:
for x in rows_sub:
f.write(str(x) + ", " + c + "\n") #the line I needed to have printed via a loop
text files do not have a header. If you want a true header, you'll need a more complex format. Alternatively, if you just need something that acts like a header, then you need to figure out how many characters fit on your page vertically, and print the header every N lines.
For horizontal alignment, make use of the extra tokens you can use with format(). As an example:
>>> print('{a:^8}{b:^8}{c:^8}'.format(a='this', b='that', c='other'))
this that other
where ^8 says I want the string centered across 8 characters. Obviously you have to choose (or derive) the value that works for your data.
Check to see if the header row already exists, write it in to the file if it doesn't exist in the first line.
name = input ("Name: ")
age = input("Age: ")
BirthYear = input("Birth Year: ")
filename = "info.txt"
header = "Name Age Grade\n"
def WriteHeader(filename, header):
"""
;param filename: a file path
;param header: a string representing the file's "header" row
This function will check if the header exists in the first line
and inserts the header if it doesn't exist
"""
file = open(filename, 'r')
lines = [line for line in file]
file.close()
if lines and lines[0] == header:
# There are some lines in the file, and first line is the header
return True
else:
# The first line is NOT the header
file = open(filename, w)
# Rewrite the file: append header if needed, and all lines which previously were there
# excluding any misplaced header lines which were not at row 1
file.write(header + ''.join([line for line in lines if not line == header]))
file.close()
return True
if __name__ == '__main__':
if WriteHeader(filename, header):
file = open(filename, 'a')
file.write("{} / {} / {}\n".format(name, age, BirthYear))
file.close()
else:
print 'there was some problems...'
On second thought, this is simpler:
def WriteHeader2(filename, header):
# Always writes the header.
file = open(filename, 'r')
# remove any matching 'header' from the file, in case ther are duplicate header rows in the wrong places
lines = [line for line in file if not line == header]
file.close()
# rewrite the file, appending the header to row 1
file = open(filename, w)
file.write(''.join([line for line in lines].insert(0,header))
file.close()
Related
I am trying to make a contact book application with command-line arguments. This is the code written so far to update the new contact details of a particular contact. args.name has the name of the contact. And args.number has the new number which needs to be updated.
How can I update the entire line? When I run this, it replaces the entire file, contacts.txt, with an empty string. This functionality will also help in the delete function.
thefile = open("contacts.txt","w+")
lines = thefile.readlines()
for line in lines:
if name in line:
line.replace(line,"Name: "+ args.name + " Number: "+args.number+ "\n")
You could firstly read the data from the file, create an empty string, append each line to the newly created string conditionally, and write(replace) the newly obtained string onto the existing file.
f1 = open('contacts.txt','r')
data = f1.readlines()
f1.close()
new_data = ""
for line in data:
if name in line:
update = line.replace(line,"Name: "+ args.name + " Number: "+args.number+ "\n")
new_data += update
else:
new_data += line
f2 = open('contacts.txt','w')
f2.write(new_data)
f2.close()
When you open a file with "w+" python erase the file !
First you whoud write two function: One that writes data and the other read data
def reader():
f = open("MYFILE.txt", "r")
lines = f.readlines()
f.close()
return lines
def writer(data):
f = open("MYFILE.txt", "w")
for i in data:
f.write(i)
f.close()
Then you can actualise lines how you want:
lines = reader()
for i in range(len(lines)):
if lines[i] == "Something\n":
lines[i] = "New_Value\n"
writer(lines)
I have a file which contains my passwords like this:
Service: x
Username: y
Password: z
I want to write a method which deletes one of these password sections. The idea is, that I can search for a service and the section it gets deleted. So far the code works (I can tell because if you insert print(section) where I wrote delete section it works just fine), I just don't know how to delete something from the file.
fileee = '/home/manos/Documents/python_testing/resources_py/pw.txt'
def delete_password():
file = open(fileee).read().splitlines()
search = input("\nEnter Service you want to delete: ")
if search == "":
print("\nSearch can't be blank!")
delete_password()
elif search == "cancel":
startup()
else:
pass
found = False
for index, line in enumerate(file):
if 'Service: ' in line and search in line:
password_section = file[index-1:index+3]
# delete password_section
found = True
if not found:
print("\nPassword for " + search + " was not found.")
delete_password()
Deleting a line from the file is the same as re-writing the file minus that matching line.
#read entire file
with open("myfile.txt", "r") as f:
lines = f.readlines()
#delete 21st line
del lines[20]
#write back the file without the line you want to remove
with open("myfile.txt", "w") as f:
f.writelines(lines)
This question already has answers here:
Why can't I call read() twice on an open file?
(7 answers)
Closed last month.
I'm trying to write a script that will take an input file with an unknown number of columns separated by commas and create a new file (name specified by user) where columns are separated by tabs.
The test input file I'm working with looks like this:
Data 1,35,42,7.34,yellow,male
Data 2,41,46,8.45,red,female
Here is the code I have so far:
# Read input file
infile = open("input_file.txt", "r")
line_count = 0
# Read as a collection, removing end line character
for line in infile:
print(line, end = "")
print("The input file contains", line_count, "lines.")
# Request user input for output file name
filename = input("Enter a name for the output file: ")
# Prompt for file name if entry is blank or only a space
while filename.isspace() or len(filename) == 0:
filename = input("Whoops, try again. Enter a name for the output file: ")
# Complete filename creation
filename = filename + ".txt"
filename = filename.strip()
# Write output as tab-delim file
for line in infile:
outfile = open(filename, "w")
outfile.write(line,"\t")
outfile.close()
print("Success, the file", filename, "has been written.")
# Close input file
infile.close()
The part that writes the output isn't working - it doesn't produce an error, but the output is blank.
You can split the lines by commas and write while adding tab(\t) chars :
with open('input_file.txt','r') as f_in, open('output_file.txt', 'w') as f_out:
for line in f_in:
s = line.strip().split(',')
for i in s:
f_out.write(i+'\t')
f_out.write('\n')
or briefly as #martineau suggested :
with open('input.txt','r') as f_in, open('output.txt', 'w') as f_out:
for line in f_in:
s = line.strip().split(',')
f_out.write('\t'.join(s) + '\n')
You may use pandas:
import pandas as pd
df = pd.read_csv("input_file.txt", sep=',',header=None)
print("The input file contains", df.shape[0], "lines.")
filename = input("Enter a name for the output file: ").strip()
# Prompt for file name if entry is blank or only a space
while filename.isspace() or len(filename) == 0:
filename = input("Whoops, try again. Enter a name for the output file: ")
#Saving to csv with | separator
df.to_csv(f'{filename}.txt', sep="\t", header=None, index=None)
print("Success, the file", filename, "has been written.")
I have a multiline string, which needs to be pasted and saved into a .txt file. I need also use some characters from the string as file name.
Here is an input example:
ABCD 0000/20/02
Q) abc/yxz/IV/A /000/999
A) XYZ B) 2008311600 C) 2009301559
E) texttexttext
texttext
File name should contain 6 numbers after B) : 200831 and the extension txt.
That's what I have:
print ('Paste new NOTAM starting with AXXXX/20: ') ##paste notam
lines = []
while True:
line = input()
if line:
lines.append(line)
else:
break
file_name= line[line.find("B) ")[6]:]
print (file_name)
with open(input(file_name + '.txt', "w+")) as f:
for line in lines:
f.write(line)
f.write('\n')
You could use regex to find out file name:
import re
string = '''ABCD 0000/20/02<br />
Q) abc/yxz/IV/A /000/999<br />
A) XYZ B) 2008311600 C) 2009301559<br />
E) texttexttext<br />
texttext<br />'''
filename = re.findall('B\) (\d\d\d\d\d\d\d)', string)[0]
with open(f'{filename}.txt', 'w') as f:
f.write(string)
Output file is 2008311.txt
so here i'm pasting my input, which is multiline string:
print ('Paste new NOTAM starting with AXXXX/20: ') ##paste notam
lines = []
while True:
line = input()
if line:
lines.append(line)
else:
break
Now i need to simply use those 6 characters from already pasted input in file name
In your code, all lines need to be checked, not only one line, so:
for line in lines:
if "B)" in line:
file_name = line[line.find("B) ")[6]:]
print (file_name)
Then, it is not really clear from your question whether you keep all multiline strings in memory or in separate files. Either way, you can write a function so that you can use it in different scenarios:
def parse_lines(lines):
for line in lines:
if "B)" in line:
file_name = line[line.find("B) ")[6]:]
print (file_name)
with open(file_name + '.txt', "w+") as f:
for line in lines:
f.write(line)
f.write('\n')
So your code will look like this:
print ('Paste new NOTAM starting with AXXXX/20: ') ##paste notam
lines = []
while True:
line = input()
if line:
lines.append(line)
else:
break
parse_lines(lines):
Or if you plan to parse batch files with this method:
import sys
with open(sys.argv[0], 'r') as f:
lines = f.readlines()
parse_lines(lines)
I have a text file with names and results. If the name already exists, only the result should be updated. I tried with this code and many others, but without success.
The content of the text file looks like this:
Ann, 200
Buddy, 10
Mark, 180
Luis, 100
PS: I started 2 weeks ago, so don't judge my bad code.
from os import rename
def updatescore(username, score):
file = open("mynewscores.txt", "r")
new_file = open("mynewscores2.txt", "w")
for line in file:
if username in line:
splitted = line.split(",")
splitted[1] = score
joined = "".join(splitted)
new_file.write(joined)
new_file.write(line)
file.close()
new_file.close()
maks = updatescore("Buddy", "200")
print(maks)
I would suggest reading the csv in as a dictionary and just update the one value.
import csv
d = {}
with open('test.txt', newline='') as f:
reader = csv.reader(f)
for row in reader:
key,value = row
d[key] = value
d['Buddy'] = 200
with open('test2.txt','w', newline='') as f:
writer = csv.writer(f)
for key, value in d.items():
writer.writerow([key,value])
So what needed to be different mostly is that when in your for loop you said to put line in the new text file, but it's never said to Not do that when wanting to replace a score, all that was needed was an else statement below the if statement:
from os import rename
def updatescore(username, score):
file = open("mynewscores.txt", "r")
new_file = open("mynewscores2.txt", "w")
for line in file:
if username in line:
splitted = line.split(",")
splitted[1] = score
print (splitted)
joined = ", ".join(splitted)
print(joined)
new_file.write(joined+'\n')
else:
new_file.write(line)
file.close()
new_file.close()
maks = updatescore("Buddy", "200")
print(maks)
You can try this, add the username if it doesn't exist, else update it.
def updatescore(username, score):
with open("mynewscores.txt", "r+") as file:
line = file.readline()
while line:
if username in line:
file.seek(file.tell() - len(line))
file.write(f"{username}, {score}")
return
line = file.readline()
file.write(f"\n{username}, {score}")
maks = updatescore("Buddy", "300")
maks = updatescore("Mario", "50")
You have new_file.write(joined) inside the if block, which is good, but you also have new_file.write(line) outside the if block.
Outside the if block, it's putting both the original and fixed lines into the file, and since you're using write() instead of writelines() both versions get put on the same line: there's no \n newline character.
You also want to add the comma: joined = ','.join(splitted) since you took the commas out when you used line.split(',')
I got the result you seem to be expecting when I put in both these fixes.
Next time you should include what you are expecting for output and what you're giving as input. It might be helpful if you also include what Error or result you actually got.
Welcome to Python BTW
Removed issues from your code:
def updatescore(username, score):
file = open("mynewscores.txt", "r")
new_file = open("mynewscores2.txt", "w")
for line in file.readlines():
splitted = line.split(",")
if username == splitted[0].strip():
splitted[1] = str(score)
joined = ",".join(splitted)
new_file.write(joined)
else:
new_file.write(line)
file.close()
new_file.close()
I believe this is the simplest/most straightforward way of doing things.
Code:
import csv
def update_score(name: str, score: int) -> None:
with open('../resources/name_data.csv', newline='') as file_obj:
reader = csv.reader(file_obj)
data_dict = dict(curr_row for curr_row in reader)
data_dict[name] = score
with open('../out/name_data_out.csv', 'w', newline='') as file_obj:
writer = csv.writer(file_obj)
writer.writerows(data_dict.items())
update_score('Buddy', 200)
Input file:
Ann,200
Buddy,10
Mark,180
Luis,100
Output file:
Ann,200
Buddy,200
Mark,180
Luis,100