I have just finished writing a simple Python3 program which converts a custom input file (or multiple files within the same folder) to an XML template.
It works as it is, but I think that I somehow messed up the code as I had to open several files, append to them, close them, loop through their lines and so on.
I thought of splitting my code into methods, but I wasn't able to come up with a nicer solution. I'm sure there are better ways of doing what I just did, but I couldn't come up with any.
Here is the code:
import datetime
import os
import random
import string
import sys
from time import strftime
'''
The program is:
- verifying if a path exists (user input)
- if the path exists, loop through each files from that folder, else exit
- there are two types of files, and the only difference between them is a line which starts with ":23B:FCY"
- because there are two type of files, there will be two XML templates.
'''
# ask ouser for path
input_file = input('Please insert the path of the folder that holds all the files (e.g: D:/files_to_be_converted): ')
# some constants
LEN_OF_RANDOM_MSG_ID = 26
FIRST_PART_MSG_ID = 'RO000IO'
# playing with strings
random_msg_id = FIRST_PART_MSG_ID + ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(LEN_OF_RANDOM_MSG_ID))
random_pmt_inf_id = FIRST_PART_MSG_ID + ''.join(random.choice(string.digits + string.ascii_uppercase) for _ in range(LEN_OF_RANDOM_MSG_ID))
if not os.path.isdir(input_file):
print("Inserted file path (" + input_file + ") does not exist !")
print("Will exit now...")
sys.exit()
# Do we even need two different templates?
template_one = """<tag1>%(msg_id)s</tag1>
<tag2>%(cre_dt_tm)s</tag2>
<tag3>%(nb_of_txs)s</tag3>
<tag4>%(ctrl_sum)s</tag4>
<tag5>%(nm)s</tag5>
<tag6>%(pmt_inf_id)s</tag6>
<tag7>%(reqd_exctn_dt)s</tag7>
"""
template_two = """<tag1>%(msg_id)s</tag1>
<tag2>%(cre_dt_tm)s</tag2>
<tag3>%(nb_of_txs)s</tag3>
<tag4>%(ctrl_sum)s</tag4>
<tag5>%(nm)s</tag5>
<tag6>%(pmt_inf_id)s</tag6>
<tag7>%(reqd_exctn_dt)s</tag7>
"""
for each_mt_file in os.listdir(input_file):
with open(os.path.join(input_file, each_mt_file)) as mt_file:
for line in mt_file:
line = line.rstrip()
if ":07:" in line:
output_file = line[4:12] # this will be part of each generated xml file
if ":23B:FCY" in open(os.path.join(input_file, each_mt_file)).read(): # if there is a line which contains :23BFCY
the_output_file = open("template1_" + output_file + ".xml", "a") # name of the XML file
template = template_one
else:
the_output_file = open("template2_" + output_file + ".xml", "a")
template = template_two
with open(os.path.join(input_file, each_mt_file)) as my_file: # open each_file and start processing the lines
for line in my_file: # going through each line of each file
if ":32A:" in line: # if this field exists process it
final_date = datetime.datetime.strptime(line[5:11], '%y%m%d').strftime('%Y-%m-%d')
ctrlSum = line[14:]
break # break here, because there are multiple lines that start with ":32A:" and I want only the first
if ":03:" in line:
NbOfTxs = line[4:]
if ":05:" in line:
Nm = line[4:]
CreDtTm = str(final_date) + "T" + str(strftime("%H:%M:%S"))
ReqdExctnDt = str(final_date)
the_output_file.write(template % {
'msg_id': random_msg_id,
'cre_dt_tm': CreDtTm,
'nb_of_txs': NbOfTxs,
'ctrl_sum': ctrlSum,
'nm': Nm,
'pmt_inf_id': random_pmt_inf_id,
'reqd_exctn_dt': ReqdExctnDt
})
And here is the custom format of the file:
:03:value1
:05:value2
junk
junk
:51:junk
junk
:07:OB25E294.jjj
:32A:160225val10.00
:99:junk
junkjunk
junk
and the second one, which is slightly different:
:03:value6
:05:value7
:*23B:FCY*
junk
junk
:51:junk
junk
:07:OB25E294.jjj
:32A:160225val10.00
:99:junk
junkjunk
junk
I'm asking for some code improvements / design patterns and mistakes that I surely did. I just feel like this code can be also split up in several files like template_1.py
and template_2.py
and then to import those in my main file but I'm not sure this is good practice.