3
\$\begingroup\$

I have a script that converts a text file to html. The text file is an output of a program (needle). The function takes the text file as an input. I am aware the script is awful. I use this function in Django. I would like to improve it. Can you help me with it?. Here is the result file from the script.

def write_html(result):
    sequence_1 = ''
    sequence_2 = ''
    identity = ''
    similarity = ''
    gaps = ''
    html_string = ''
    with open("/Users/catuf/Desktop/needle_align.txt", "w") as e:
        e.write('{% extends "database/base_table.html" %}' + "\n")
        e.write('\n')
        e.write("{% block content %}"+"\n")
        table1 = '''
        <!DOCTYPE html>
        <html>
        <head>
        <style>
        table, th, td {
          border: 1px solid black;
        }
        </style>
        </head>
        <body>

        <table>
          <tr>
            <th>Query Sequence </th>
            <th>Matched Sequence </th>
            <th>Identity </th>
            <th>Similarity </th>
            <th>Gaps </th>
          </tr>
          <tr>
        '''

        table2 = """
          </tr>
        </table>

        </body>
        </html>
        """
        for line in result.splitlines():
            #s = html.unescape(lines)
            #print(line)
            if line.startswith('# 1:'):
                line = line.split()
                sequence_1 = line[2]
            elif line.startswith('# 2:'):
                line = line.split()
                #print(line)
                sequence_2 = line[2]

            elif line.startswith('# Identity:'):
                identity = re.search(r"\d{1,3}\.\d*\%", line)
                identity = identity.group()
                identity = identity.replace('%', '')
                #identity = float(identity)* 100
                #identity = str(identity)

            elif line.startswith('# Similarity:'):
                similarity = re.search(r"\d{1,3}\.\d*\%", line)
                similarity = similarity.group()
                similarity = similarity.replace('%', '')

            elif line.startswith('# Gaps:'):
                line = line.split()
                gaps = line[2]

            elif line.startswith('#'):
                pass
            else:
                s = "<pre>" + line + "</pre>"
                html_string += s

        e.write(table1)
        e.write("<td>" + sequence_1 + '</td>' + '\n')
        e.write("<td>" + sequence_2 + '</td>'+ '\n')
        e.write("<td>"+ identity + "%" + '</td>'+ '\n')
        e.write("<td>"+ similarity+ "%" +'</td>'+ '\n')
        e.write("<td>"+ gaps+ '</td>'+ '\n')
        e.write(table2)
        e.write(html_string)
        e.write("</head>" + "\n")
        e.write("{% endblock content %}"+"\n")
\$\endgroup\$
  • \$\begingroup\$ Could you show us how the output html is rendered? \$\endgroup\$ – dfhwze Sep 14 at 18:33
  • 2
    \$\begingroup\$ Sure I will add rendered one in couple of minutes. \$\endgroup\$ – catuf Sep 14 at 19:17
  • 1
    \$\begingroup\$ What he meant is, how and when do you call this function? It is odd that you are programatically creating a template with data in it. There seems to be a fundamental misunderstanding here. Anyhow, first thing I'd do is separating the parsing from the rendering. \$\endgroup\$ – Holli Sep 14 at 23:01
  • \$\begingroup\$ As you can see in this script. I receive the result file as a string from the needle program and call this function. \$\endgroup\$ – catuf Sep 15 at 0:42
1
\$\begingroup\$

Functions

Right now, write_html manages both parsing and writing to a file. Separate this function into two functions, perhaps parse_data and write_data.

String Formatting

This

s = "<pre>" + line + "</pre>"
e.write("<td>" + sequence_1 + '</td>' + '\n')

can be written like this

s = f"<pre>{line}></pre>"
e.write(f"<td>{sequence_1}</td>\n")

The f"" allows you to directly implement variables into your strings.

Simplification

This

elif line.startswith('# Gaps:'):
    line = line.split()
    gaps = line[2]

can be written like this

elif line.startswith('# Gaps:'):
    gaps = line.split()[2]

The same with these two:

if line.startswith('# 1:'):
    sequence_1 = line.split()[2]
elif line.startswith('# 2:'):
    sequence_2 = line.split()[2]

Variable Assignments

This

sequence_1 = ''
sequence_2 = ''
identity = ''
similarity = ''
gaps = ''
html_string = ''

can be written like this

sequence_1, sequence_2, identity, gaps, similarity, html_string = '', '', '', '', '', ''

Type Hints

You can use type hints to make it clear what is being accepted as parameters, and what is being returned by the function.

From this

def write_html(result):

to this

def write_html(result: str) -> None:

Docstrings

You should include a docstring at the beginning of every function, method, class, and module you write. This will allow documentation to identify what these are supposed to do.

def write_html(result: str) -> None:
    """
    (Description about this method here)
    """
    ... code here ...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.