The ask is to sort and save a csv file in a new csv file. With the code below(below1), I seem to get the result when I open the new csv file. However, when I run the code on the homework interface, it prints out wrong (below2). Can anyone identify why it doesn't work? I have the correct solution to the ask as well (below3). I don't understand why mine doesn't work.
Below1:
import csv
def sort_records(csv_filename, new_filename):
file = open(csv_filename)
lines = file.readlines()
newfile = open(new_filename, "w")
header = lines[0]
newfile.write(header)
lines.remove(header)
lines.sort(key=lambda x: x[0])
for item in lines:
newfile.write(item)
file.close()
newfile.close()
Below2:
city/month,Jan,Feb,Mar,Apr
Brisbane,31.3,40.2,37.9,29
Darwin,34,34,33.2,34.5Melbourne,41.2,35.5,37.4,29.3
Below3:
import csv
def sort_records(csv_filename, new_filename):
csv_file = open(csv_filename)
reader = csv.reader(csv_file)
header = next(reader)
data2d = list(reader)
data2d.sort()
csv_file.close()
new_file = open(new_filename, "w")
writer = csv.writer(new_file)
writer.writerow(header)
writer.writerows(data2d)
new_file.close()
The original csv file:
city/month,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
Melbourne,41.2,35.5,37.4,29.3,23.9,16.8,18.2,25.7,22.3,33.5,36.9,41.1
Brisbane,31.3,40.2,37.9,29,30,26.7,26.7,28.8,31.2,34.1,31.1,31.2
Darwin,34,34,33.2,34.5,34.8,33.9,32,34.3,36.1,35.4,37,35.5
Perth,41.9,41.5,42.4,36,26.9,24.5,23.8,24.3,27.6,30.7,39.8,44.2
Adelaide,42.1,38.1,39.7,33.5,26.3,16.5,21.4,30.4,30.2,34.9,37.1,42.2
Canberra,35.8,29.6,35.1,26.5,22.4,15.3,15.7,21.9,22.1,30.8,33.4,35
Hobart,35.5,34.1,30.7,26,20.9,15.1,17.5,21.7,20.9,24.2,30.1,33.4
Sydney,30.6,29,35.1,27.1,28.6,20.7,23.4,27.7,28.6,34.8,26.4,30.2
There is no need for additional modules in this case. Open the input file for reading (readonly) and the output file for writing.
Write the first line (column descriptions) from input to output. Then sort the list returned from readlines and write to output.
Like this:
ORIGINAL = 'original.csv'
NEW = 'new.csv'
with open(ORIGINAL) as original, open(NEW, 'w') as new:
new.write(next(original))
new.writelines(sorted(original.readlines(), key=lambda x: x.split(',')[0]))
I've run your code on my machine and it works as it's supposed to. Is it possible to print out the CSV file from this homework interface before sorting?
I am working on a attendance system using face recognition code. I wanted to save the face recognition output(Name of the recognized people) in a .csv file.
So, I tried this:
def Attendance(name):
moment=time.strftime("%Y-%b-%d",time.localtime())
open('Attendance'+moment+'.csv','w')
with open ('Attendance'+moment+'.csv','a+',newline="\n") as f:
DataList = f.readlines()
knownNames = []
for data in DataList:
ent = data.split(',')
knownNames.append(ent[0])
if name not in knownNames:
curr=_datetime.date.today()
dt=curr.strftime('%d%m%Y_%H:%M:%S')
f.writelines(f'\n{name}, {dt}, P'+'\n')
It creates a .csv file by date.
But the issue is - this function I created, makes new data replace the older data in the .csv file, instead of appending the newer data in the next lines.
I need to append new data and eliminate re-entry of already existing data.
Kindly help!
Regards,
Vishwesh V Bhat
Use the opening mode 'a' for append:
with open("filename.csv", "a") as f:
...
You are opening the file in write mode. This overwrites your file. Remove that line and your code should work.
Fixed Code:
def Attendance(name):
moment=time.strftime("%Y-%b-%d",time.localtime())
with open ('Attendance'+moment+'.csv','a+',newline="\n") as f:
DataList = f.readlines()
knownNames = []
for data in DataList:
ent = data.split(',')
knownNames.append(ent[0])
if name not in knownNames:
curr=datetime.date.today()
dt=curr.strftime('%d%m%Y_%H:%M:%S')
f.writelines(f'\n{name}, {dt}, P'+'\n')
Also, make sure to follow PEP 8. f-string can also help make your code more readable.
Fixed Code that follows PEP 8 and is cleaner:
def Attendance(name):
moment = time.strftime("%Y-%b-%d",time.localtime())
with open(f'Attendance{moment}.csv', 'a+') as f:
knownNames = [data.split(',')[0] for data in f.readlines()]
if name not in knownNames:
dt = datetime.date.today().strftime('%d%m%Y_%H:%M:%S')
print(f'\n{name}, {dt}, P', file=f)
Issue solved!
Mistake I was making was, I was opening the .csv with w mode. So everytime I run the code, even if the .csv created on that date existed already it would overwrite the newer data to the first row.
So I used if os.path.exists('Attend'+moment+'.csv'):
This solved the issue.
Solution:
def Attendance(name):
moment=time.strftime("%Y-%b-%d",time.localtime())
if os.path.exists('Attend'+moment+'.csv'):
with open('Attend'+moment+'.csv','r+',newline="\n") as f:
DataList = f.readlines()
knownNames = []
for data in DataList:
ent = data.split(',')
knownNames.append(ent[0])
with open('Attend'+moment+'.csv','a',newline="\n") as f:
if name not in knownNames:
curr=_datetime.date.today()
dt=curr.strftime('%d%m%Y_%H:%M:%S')
f.writelines(f'\n{name}, {dt}, P')
else:
open('Attend'+moment+'.csv','w')
I need to load data to my python program from a file. Could you tell me what is the easiest way?
the file is user_id.txt and content is :
['1668938807', '8646077542', '2926881681', '634754486']
also what I tried but did not work is:
with open('user_id.txt', 'r') as f:
data = f.readlines()
lines = []
for line in data:
content = line.split(',')
for el in content:
new_el = el.strip('\'')
print(new_el)
Below (using the fact that the file content can be directly loaded into a list using ast)
import ast
with open('user_id.txt') as f:
lst = ast.literal_eval(f.read())
print(lst)
output
['1668938807', '8646077542', '2926881681', '634754486']
If you want to load numbers to array you can try this:
numbers = []
with open("user_id.txt","r") as f:
data = f.readlines()
for line in data:
stripped = ex[1:-1] #stripped bracelets
numbers.append([ int(''.join(filter(str.isdigit, num))) for num in stripped.split(",") ] )
Anyway you should consider using json
Hope i answered your question
I'm currently using Python 3 on Ubuntu 18.04. I'm not a programmer by any means and I'm not asking for a code review, however, I'm having an issue that I can't seem to resolve.
I have 1 text file named content.txt that I'm reading lines from.
I have 1 text file named standard.txt that I'm reading lines from.
I have 1text file named outfile.txt that I'm writing to.
content = open("content.txt", "r").readlines()
standard = open("standard.txt", "r").readlines()
outfile = "outfile.txt"
outfile_set = set()
with open(outfile, "w") as f:
for line in content:
if line not in standard:
outfile_set.add(line)
f.writelines(sorted(outfile_set))
I'm not sure where to put the following line though. My for loop nesting may all be off:
f.write("\nNo New Content")
Any code examples to make this work would be most appreciated. Thank you.
if i understand good you whant to add outfile_set if this is not empty to the outfile or add the string "\nNo New Content"
Replace the line
f.writelines(sorted(outfile_set))
to
if any(outfile_set):
f.writelines(sorted(outfile_set))
else:
f.write("\nNo New Content")
I'm assuming that you want to write "No new content" to the file if every line in content is in standard. So you might do something like:
with open(outfile, "w") as f:
for line in content:
if line not in standard:
outfile_set.add(line)
if len(outfile_set) > 0:
f.writelines(sorted(outfile_set))
else:
f.write("\nNo New Content")
Your original code was almost there!
You can reduce your runtime a lot by using set/frozenset:
with open("content.txt", "r") as f:
content = frozenset(f.readlines()) # only get distinct values from file
with open("standard.txt", "r") as f:
standard = frozenset(f.readlines()) # only get distinct values from file
# only keep whats in content but not in standard
outfile_set = sorted(content-standard) # set difference, no loops or tests needed
with open ("outfile.txt","w") as outfile:
if outfile_set:
outfile.writelines(sorted(outfile_set))
else:
outfile.write("\nNo New Content")
You can read more about it here:
set operator list (python 2 - but valid for 3 - can't find this overview in py3 doku
set difference
Demo:
# Create files
with open("content.txt", "w") as f:
for n in map(str,range(1,10)): # use range(1,10,2) for no changes
f.writelines(n+"\n")
with open("standard.txt", "w") as f:
for n in map(str,range(1,10,2)):
f.writelines(n+"\n")
# Process files:
with open("content.txt", "r") as f:
content = set(f.readlines())
with open("standard.txt", "r") as f:
standard = set(f.readlines())
# only keep whats in content but not in standard
outfile_set = sorted(content-standard)
with open ("outfile.txt","w") as outfile:
if outfile_set:
outfile.writelines(sorted(outfile_set))
else:
outfile.write("\nNo New Content")
with open ("outfile.txt") as f:
print(f.read())
Output:
2
4
6
8
or
No New Content
I know I can read the line by line with
dataFile = open('myfile.txt', 'r')
firstLine = dataFile.readline()
secondLine = dataFile.readline()
...
I also know how to read all the lines in one go
dataFile = open('myfile.txt', 'r')
allLines = dataFile.read()
But my question is how to read one particular line from .txt file?
I wish to read that line by its index.
e.g. I want the 4th line, I expect something like
dataFile = open('myfile.txt', 'r')
allLines = dataFile.readLineByIndex(3)
Skip 3 lines:
with open('myfile.txt', 'r') as dataFile:
for i in range(3):
next(dataFile)
the_4th_line = next(dataFile)
Or use linecache.getline:
the_4th_line = linecache.getline('myfile.txt', 4)
From another Ans
Use Python Standard Library's linecache module:
line = linecache.getline(thefilename, 33)
should do exactly what you want. You don't even need to open the file -- linecache does it all for you!
You can do exactly as you wanted with this:
DataFile = open('mytext.txt', 'r')
content = DataFile.readlines()
oneline = content[5]
DataFile.close()
you could take this down to three lines by removing oneline = content[5] and using content[5] without creating another variable (print(content[5]) for example) I did this just to make it clear that content[5] must be a used as a list to read the one line.