I am new to Python and am using version 2.7.1 as part of Hyperion FDMEE.
I have a file which I need to reorder the columns plus, split one column into 3 as part of the same file.
Source file;
ACCOUNT;UD1;UD2;UD3;PERIOD;PERIOD;AMOUNT
QTY;032074;99953;53;2017.07.31;2017.07.31;40.91
COGS;032074;99953;53;2017.07.31;2017.07.31;-7488.36
TURNOVER;032074;99953;53;2017.07.31;2017.07.31;505.73
QTY;032075;99960;60;2017.07.31;2017.07.31;40.91
COGS;032075;99960;60;2017.07.31;2017.07.31;-7488.36
TURNOVER;032075;99960;60;2017.07.31;2017.07.31;505.73
I have managed to reorder the columns per this script;
infilename = fdmContext["OUTBOXDIR"]+"/Targit_1707.dat"
outfilename = fdmContext["OUTBOXDIR"]+"/TargitExport.csv"
import csv
infile = open(infilename, 'r')
outfile = open(outfilename, 'w+')
for line in infile:
column = line.split(';')
outfile.write(column[1] + ";" + column[2] + ";" + column[3] + ";" + column[4] + ";" + column[0] + ";" + str(column[6].strip('\n')) + ";201701" + "\n")
outfile.close()
infile.close()
Producing the result;
UD1;UD2;UD3;PERIOD;ACCOUNT;AMOUNT;201701
032074;99953;53;2017.07.31;QTY;40.91;201701
032074;99953;53;2017.07.31;COGS;-7488.36;201701
032074;99953;53;2017.07.31;TURNOVER;505.73;201701
032075;99960;60;2017.07.31;QTY;40.91;201701
032075;99960;60;2017.07.31;COGS;-7488.36;201701
032075;99960;60;2017.07.31;TURNOVER;505.73;201701
but I am struggling to transpose the Account column (QTY, COGS, TURNOVER) into seperate columns as in the example below;
UD1;UD2;UD3;PERIOD;QTY;COGS;TURNOVER;201701
032074;99953;53;2017.07.31;40.91;-7488.36;505.73;201701
032075;99960;60;2017.07.31;40.91;-7488.36;505.73;201701
Any suggestions would be very much appreciated.
Use a dict, for instance:
import csv
fieldnames = infile.readline()[:-1]
fieldnames = fieldnames.split(';')[1:5] + ['QTY', 'COGS', 'TURNOVER']
writer = csv.DictWriter(outfile, fieldnames=fieldnames)
writer.writeheader()
record_dict = {}
for i, line in enumerate(infile):
if not line: break
line = line[:-1].split(';')
# Assign column data every 1,2,3 lines
mod_row = (i % 3)+1
if mod_row == 1:
record_dict['QTY'] = line[6]
record_dict['UD1'] = line[1]
# ... and so on
if mod_row == 2:
record_dict['COGS'] = line[6]
if mod_row == 3:
record_dict['TURNOVER'] = line[6]
writer.writerow(record_dict)
record_dict = {}
Output:
UD1,UD2,UD3,PERIOD,QTY,COGS,TURNOVER
032074,,,,40.91,-7488.36,505.73
032075,,,,40.91,-7488.36,505.73
Tested with Python: 3.4.2
Read about:
Python ยป 3.6.1 Documentation csv.DictWriter
Related
My code below create csv file and then adding random data to it.
Somehow, the first part of the code create a blank row below header.
Can anyone please help to fix the code to remove this blank row?
Thank you,
Hary
header_list = ["Firm", "hour", "unit sold", "product code", "dollar value"]
for i in range(3):
# create file with header -----------
with open(f'D:\\2000 transactions\\location_id_' + str(i) + '.csv', 'w', newline='') as file:
dw = csv.DictWriter(file, delimiter=',',fieldnames=header_list)
dw.writeheader() # this line create a blank row below header
# adding data to file ---------------
for j in range(5):
n = random.randint(1, 99)
text = str(str(sp100_list['Name'].loc[n]) + ',' + str(random.randint(5, 20)) + ',' + str(random.randint(200, 1000)) + ',' + str(
random.randint(100, 150)) + ',' + str(int(random.random() * 1000000)))
myfile = open(f'D:\\2000 transactions\\location_id_' + str(i) + '.csv', 'a')
myfile.write('\n' + text)
Actually you add unexpected blank row in the line myfile.write('\n' + text),not dw.writeheader(). You add a \n first, which add a blank row to your file. Move the \n to backwards should solve it.
code:
import csv
header_list = ["Firm", "hour", "unit sold", "product code", "dollar value"]
for i in range(1):
with open(f'test{str(i)}.csv', 'w', newline='') as file:
dw = csv.DictWriter(file, delimiter=',',fieldnames=header_list)
dw.writeheader() # this line create a blank row below header
for j in range(5):
with open(f'test{str(i)}.csv', 'a', newline='') as myfile:
text = "1,1"
myfile.write(text+'\n')
result:
Firm,hour,unit sold,product code,dollar value
1,1
1,1
1,1
1,1
1,1
you can only use csv writer instead of DictWriter.here is example
use csv write to write header and rows
header_list = ["Firm", "hour", "unit sold", "product code", "dollar value"]
for i in range(3):
#create writer here
with open(f'tmp_' + str(i) + '.csv', 'w') as file:
writer = csv.writer(file, delimiter=',')
#write header
writer.writerow(header_list)
# adding data to file ---------------
for j in range(5):
n = random.randint(1, 99)
writer.writerow([sp100_list['Name'].loc[n],random.randint(5, 20),
random.randint(200, 1000),random.randint(100, 150),
int(random.random() * 1000000)])
Is there a way I can use python to take my animals.txt file results and convert it to csv and format it differently?
Currently the animals.txt file looks like this:
ID:- 512
NAME:- GOOSE
PROJECT NAME:- Random
REPORT ID:- 30321
REPORT NAME:- ANIMAL
KEYWORDS:- ['"help,goose,Grease,GB"']
ID:- 566
NAME:- MOOSE
PROJECT NAME:- Random
REPORT ID:- 30213
REPORT NAME:- ANIMAL
KEYWORDS:- ['"Moose, boar, hansel"']
I would like the CSV file to present it as:
ID, NAME, PROJECT NAME, REPORT ID, REPORT NAME, KEYWORDS
Followed by the results underneath each header
Here is a script I have wrote:
import re
import csv
with open("animals.txt") as f: text = f.read()
data = {}
keys = ['ID', 'NAME', 'PROJECT NAME', 'REPORT ID', 'REPORT NAME', 'KEYWORDS']
for k in keys:
data[k] = re.findall(r'%s:- (.*)' % k, text)
csv_file = 'out.csv'
with open(csv_file, 'w') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=keys)
writer.writeheader()
for x in data:
writer.writerow(x)
An easy way to do is parsing using regex and store them in a dict, just before you write the final csv:
import re
# `text` is your input text
data = {}
keys = ['ID', 'NAME', 'PROJECT NAME', 'REPORT ID', 'REPORT NAME', 'KEYWORDS']
for k in keys:
data[k] = re.findall(r'%s:- (.*)' % k, text)
And to CSV:
import csv
csv_file = 'out.csv'
with open(csv_file, 'w') as csvfile:
writer = csv.writer(csvfile, quoting=csv.QUOTE_NONE, escapechar='\\')
writer.writerow(data.keys())
for i in range(len(data[keys[0]])):
writer.writerow([data[k][i] for k in keys])
Output in csv:
ID,NAME,PROJECT NAME,REPORT ID,REPORT NAME,KEYWORDS
512,GOOSE,Random,30321,ANIMAL,['\"help\,goose\,Grease\,GB\"']
566,MOOSE,Random,30213,ANIMAL,['\"Moose\, boar\, hansel\"']
Note that I used re.M multiline mode since there's a trick in your text, preventing matching ID twice! Also the default write rows needed to be twisted.
Also uses \ to escape the quote.
This should work:
fname = 'animals.txt'
with open(fname) as f:
content = f.readlines()
content = [x.strip() for x in content]
output = 'ID, NAME, PROJECT NAME, REPORT ID, REPORT NAME, KEYWORDS\n'
line_output = ''
for i in range(0, len(content)):
if content[i]:
line_output += content[i].split(':-')[-1].strip() + ','
elif not content[i] and not content[i - 1]:
output += line_output.rstrip(',') + '\n'
line_output = ''
output += line_output.rstrip(',') + '\n'
print(output)
That's the code in Autoit (www.autoitscript.com)
Global $values_A = StringRegExp(FileRead("json.txt"), '[ID|NAME|KEYWORDS]:-\s(.*)?', 3)
For $i = 0 To UBound($values_A) - 1 Step +6
FileWrite('out.csv', $values_A[$i] & ',' & $values_A[$i + 1] & ',' & $values_A[$i + 2] & ',' & $values_A[$i + 3] & ',' & $values_A[$i + 4] & ',' & $values_A[$i + 5] & #CRLF)
Next
I know that there are some topics on this that tell us to use .strip() or .rstrip() function to do this but it's not working for me.
I have a programme that appends a new line to the csv file but unfortunately it generates a trailing comma...
I have tried to remove it with the .strip() function in python but it isn't working well, I am doing something wrong?
This is an example of what happen when I input 'T123' for Bike_No and '05/08/2017' for Purchase_Date
from datetime import datetime
td= datetime.now()
initial_bike_detaillist=[]
deBatt =100
deKM = 0.00
deDate = str(td)[8:10] + "/"+ str(td)[5:7] + "/"+ str(td)[0:4]
print("Option 4: Add abicycle \n")
Bike_No=input("Bike No. :")
Purchase_Date=str(input("Purchase Date:"))
initial_bike_detaillist=[str(Bike_No),str(Purchase_Date),str(deBatt),str(deDate),str(deKM)]#because there is no write function for int
filename="Assignment_Data1.csv"
file=open(filepath + filename,"a")
file.write("\n")
for k in initial_bike_detaillist:
file.write("{},".format(k))
print("Bicycle ({}) has been created".format(Bike_No))
file.close()
file=open(filepath + filename,"r")
for line in file:
line.strip()
print(line)
expected output=
Bike No.,Purchase Date,Batt %,Last Maintenance,KM since Last
T101,10/04/2016,55,10/01/2017,25.08
T102,01/07/2016,10,15/05/2017,30.94
T103,15/11/2016,94,13/06/2017,83.16
T104,25/04/2017,58,10/01/2017,25.08
T105,24/05/2017,5,20/06/2017,93.80
T123,04/04/2017,100,05/08/2017,0.0
actual output:
Bike No.,Purchase Date,Batt %,Last Maintenance,KM since Last
T101,10/04/2016,55,10/01/2017,25.08
T102,01/07/2016,10,15/05/2017,30.94
T103,15/11/2016,94,13/06/2017,83.16
T104,25/04/2017,58,10/01/2017,25.08
T105,24/05/2017,5,20/06/2017,93.80
T123,04/04/2017,100,05/08/2017,0.0,
`
Instead of this line :
for k in initial_bike_detaillist:
file.write("{},".format(k))
use following line :
file.write(','.join(initial_bike_detaillist))
Your Code :
from datetime import datetime
td = datetime.now()
initial_bike_detaillist = []
deBatt = 100
deKM = 0.00
deDate = str(td)[8:10] + "/" + str(td)[5:7] + "/" + str(td)[0:4]
print("Option 4: Add abicycle \n")
Bike_No = input("Bike No. :")
Purchase_Date = str(input("Purchase Date:"))
initial_bike_detaillist = [str(Bike_No), str(Purchase_Date), str(deBatt), str(deDate),
str(deKM)] # because there is no write function for int
filename = "Assignment_Data1.csv"
file = open(filepath + filename, "a")
file.write("\n")
# for k in initial_bike_detaillist:
# file.write("{},".format(k))
file.write(','.join(initial_bike_detaillist)) # use this line .
print("Bicycle ({}) has been created".format(Bike_No))
file.close()
file = open(filepath + filename, "r")
for line in file:
# line.strip() # Then, not need this line
print(line)
the code below reads the data.txt file and prints the records in the data.txt file.
text_file = open("data.txt", "r")
lines = text_file.readlines()
print (lines)
print (lines)
text_file.close()
def print_all_records(records):
print("Date" + "\t\t" + "Branch" + "\t\t" + "Daily Sale" + "\t\t" + "Transactions")
for record in records:
parts = record.split(",")
print(parts[0] + "\t" + parts[1] + "\t" + "$" + parts[2] + "\t\t" + parts[3])
example of information in the data.txt file
1-2-2014,Frankton,42305.67,23
12-4-2014,Glenview,21922.22,17
10-2-2015,Glenview,63277.9,32
how do i make it so that i can query the records by date. for example if a user input the date 1 2 2014 it would search the data.txt file to find if that date exists then print that line of the record. and if it doesnt find anything it asks the user try again and again until it finds a date that matches a record.
I'm assuming that you use Python 3.
def print_entries(date):
"""Prints all the entries that match with date"""
with open('a.txt', 'r') as f:
flag = False
content = f.readlines()
content = [line.strip('\n').split(',') for line in content]
for row in content:
if row[0] == date:
flag = True
print(*row, sep='\t')
if not flag:
print('Try again')
return flag
while not print_entries(input("Enter date :")):
pass
If you're using Python 2, replace print(*row, sep = '\t') with print('\t'.join(row)).
Running the program -
Enter date :12-4-2014
12-4-2014 Glenview 21922.22 17
I am new in python, and I need some help. I made a python script that takes two columns from a file and copies them into a "new file". However, every now and then I need to add columns to the "new file". I need to add the columns on the side, not the bottom. My script adds them to the bottom. Someone suggested using CSV, and I read about it, but I can't make it in a way that it adds the new column to the side of the previous columns. Any help is highly appreciated.
Here is the code that I wrote:
import sys
import re
filetoread = sys.argv[1]
filetowrite = sys.argv[2]
newfile = str(filetowrite) + ".txt"
openold = open(filetoread,"r")
opennew = open(newfile,"a")
rline = openold.readlines()
number = int(len(rline))
start = 0
for i in range (len(rline)) :
if "2theta" in rline[i] :
start = i
for line in rline[start + 1 : number] :
words = line.split()
word1 = words[1]
word2 = words[2]
opennew.write (word1 + " " + word2 + "\n")
openold.close()
opennew.close()
Here is the second code I wrote, using CSV:
import sys
import re
import csv
filetoread = sys.argv[1]
filetowrite = sys.argv[2]
newfile = str(filetowrite) + ".txt"
openold = open(filetoread,"r")
rline = openold.readlines()
number = int(len(rline))
start = 0
for i in range (len(rline)) :
if "2theta" in rline[i] :
start = i
words1 = []
words2 = []
for line in rline[start + 1 : number] :
words = line.split()
word1 = words[1]
word2 = words[2]
words1.append([word1])
words2.append([word2])
with open(newfile, 'wb') as file:
writer = csv.writer(file, delimiter= "\n")
writer.writerow(words1)
writer.writerow(words2)
These are some samples of input files:
https://dl.dropbox.com/u/63216126/file5.txt
https://dl.dropbox.com/u/63216126/file6.txt
My first script works "almost" great, except that it writes the new columns at the bottom and I need them at side of the previous columns.
The proper way to use writerow is to give it a single list that contains the data for all the columns.
words.append(word1)
words.append(word2)
writer.writerow(words)