烧瓶重构

Flask refactoring

我正在尝试在 Flask 中创建一个 Web 项目。简而言之,这是一个 HTML/CSS 站点,您可以在其中输入一些数据,然后显示矩形的面积或周长。

我的问题是我几乎为圆周和面积部分重复了相同的代码。我已经设法在另一个 .py 文件中进行了输入验证和计算 (web_rectangle.py),但现在我卡住了。

这是两个输入 HTML 文件之一(它们几乎相同):

<!doctype html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="/static/grids.css">
    <link rel="stylesheet" type="text/css" href="/static/styles.css">
    <script src="http://use.edgefonts.net/expletus-sans:n4,n7,n5,i7,i4,n6,i6,i5:all;nova-square:n4:all;trykker:n4:all.js"></script>
    <title>Omkredsen af et rektangel</title>
</head>

<body>

    <header>
        <table>
            <tr>
                <td class="hdfo_td_side" background="static/header_left.png">
                </td>
                <td class="td_center" background="static/header_center.png">
                    <h1>Rektangel - areal</h1>
                </td>
                <td class="hdfo_td_side" background="static/header_right.png">
                </td>
            </tr>
        </table>
    </header>

    <div class="line"></div>
    <nav>
        <div class="nav_bg"></div>
        <div class="nav_text">
            <a href="/">Forside</a>
        </div>
    </nav>
    <div class="line"></div>

    <div class="grid">
        <div class="section group">
            <div class="main_left col grid_3">
                <p>Formel for arealet af et rektangel:</p>
                <p class="formula">A = l * b</p>
                <p>(A) står for areal, (l) for rektanglets længde og (b) for rektanglets bredde.</p>
                <p>Husk at i geometri skal det man finder (her arealet) skrives med stort bogstav, mens de variabler man bruger (for eksempel 'længde'), skal skrives med små bogstaver.</p>
            </div>
            <div class="main_right col grid_5">
                <h3>Indtast data</h3>

                <form action="/rect_area" method="GET">
                    Længde
                    <br>
                    <input {% if error_l %} class="error_l" {% endif %} type="text" name="length" value="{{ length }}">
                    <br>
                    <br>Bredde
                    <br>
                    <input {% if error_w %} class="error_w" {% endif %} type="text" name="width" value="{{ width }}">
                    <br>
                    <input type="submit" value="Se svar">
                    <br>
                    <br>
                </form>
                <div>
                    {% if input_text %}
                    <p>{{ input_text }}</p>
                    {% endif %}
                    {% if input_error %}
                    <p>{{ input_error }}</p>
                    {% endif %}
                </div>
                <div>
                    {% if result %}
                    <p>Omkredsen er: {{ result }}</p>
                    {% endif %}
                </div>
            </div>
        </div>
    </div>
    </div>

    <footer>
        <table>
            <tr>
                <td class="hdfo_td_side" background="static/footer_left.png">
                </td>
                <td class="td_center" background="static/footer_center.png">
                    <p class="footer_text">(C) Copyright 2015, Daniel Holm Hansen</p>
                </td>
                <td class="hdfo_td_side" background="static/footer_right.png">
                </td>
            </tr>
        </table>
    </footer>

    <img class="footer_logo" src="../static/logo_dhh_white_xs.png" width="120" alt="Made by DHH">
</body>

index.py:

from flask import Flask, render_template, request
from web_rectangle import rect_area, rect_circ, test_val

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')


@app.route('/rect_circ')
def circ_input():
    #Inputs from web
    length = request.args.get('length')
    width = request.args.get('width')

    #Predefined values
    error_l = ''
    error_w = ''
    input_text = '''Indtast værdierne for længde og bredde. Du må kun bruge tal.
                 Brug punktum i stedet for komma før decimaltal.'''
    input_error = '''Brug kun tal større end nul og punktum i stedet for komma 
                  før decimaltal.'''

    #Test length and width for valid inputs
    if length and width:
        return_val_l = test_val(length)
        length = return_val_l[0]
        error_l = return_val_l[1]

        return_val_w = test_val(width)
        width = return_val_w[0]
        error_w = return_val_w[1]
    #Test length for valid inputs when width == ''
    elif length:
        return_val_l = test_val(length)
        length = return_val_l[0]
        error_l = return_val_l[1]
        error_w = 'Indtast tal'
    #Test width for valid inputs when length == ''
    elif width:
        return_val_w = test_val(width)
        width = return_val_w[0]
        error_w = return_val_w[1]
        error_l = 'Indtast tal'
    #Both length and width == ''
    else:
        return render_template(
            'rectangle_area.html',
            input_text = input_text
        )

    #Final outputs depending on error types from input tests - if any 
    if  error_l == '' and error_w == '':        
        return render_template(
            'rectangle_circ.html',
            result = rect_circ(length, width),
            length = length,
            width = width
        )
    elif error_l == '' and error_w != '':
        return render_template(
            'rectangle_circ.html',
            length = length,
            width = error_w,
            error_w = error_w,
            input_error = input_error
        )
    elif error_l != '' and error_w == '':
        return render_template(
            'rectangle_circ.html',
            length = error_l,
            width = width,
            error_l = error_l,
            input_error = input_error
        )
    elif error_l != '' and error_w != '':
        return render_template(
            'rectangle_circ.html',
            length = error_l,
            width = error_w,
            error_l = error_l,
            error_w = error_w,
            input_error = input_error
        )
    else:
        return render_template(
            'rectangle_circ.html',
            input_text = input_text
        )


@app.route('/rect_area')
def area_input():
    #Inputs from web
    length = request.args.get('length')
    width = request.args.get('width')

    #Predefined values
    error_l = ''
    error_w = ''
    input_text = '''Indtast værdierne for længde og bredde. Du må kun bruge tal.
                 Brug punktum i stedet for komma før decimaltal.'''
    input_error = '''Brug kun tal større end nul og punktum i stedet for komma 
                  før decimaltal.'''

    #Test length and width for valid inputs
    if length and width:
        return_val_l = test_val(length)
        length = return_val_l[0]
        error_l = return_val_l[1]

        return_val_w = test_val(width)
        width = return_val_w[0]
        error_w = return_val_w[1]
    #Test length for valid inputs when width == ''
    elif length:
        return_val_l = test_val(length)
        length = return_val_l[0]
        error_l = return_val_l[1]
        error_w = 'Indtast tal'
    #Test width for valid inputs when length == ''
    elif width:
        return_val_w = test_val(width)
        width = return_val_w[0]
        error_w = return_val_w[1]
        error_l = 'Indtast tal'
    #Both length and width == ''
    else:
        return render_template(
            'rectangle_area.html',
            input_text = input_text
        )

    #Final outputs depending on error types from input tests - if any 
    if  error_l == '' and error_w == '':        
        return render_template(
            'rectangle_area.html',
            result = rect_area(length, width),
            length = length,
            width = width
        )
    elif error_l == '' and error_w != '':
        return render_template(
            'rectangle_area.html',
            length = length,
            width = error_w,
            error_w = error_w,
            input_error = input_error
        )
    elif error_l != '' and error_w == '':
        return render_template(
            'rectangle_area.html',
            length = error_l,
            width = width,
            error_l = error_l,
            input_error = input_error
        )
    elif error_l != '' and error_w != '':
        return render_template(
            'rectangle_area.html',
            length = error_l,
            width = error_w,
            error_l = error_l,
            error_w = error_w,
            input_error = input_error
        )
    else:
        return render_template(
            'rectangle_area.html',
            input_text = input_text
        )

if __name__ == '__main__':
    app.run(debug=True)

web_rectangle.py:

#This script is for WEB use only.
#It is used by another script calling its funtions.


def rect_area(length, width):
    return length * width

def rect_circ(length, width):
    return 2 * length + 2 * width

def test_val(val):
    try:
        val = float(val)
        if val <= 0:
            error = 'Indtast et tal større end 0'
        else:
            error = ''
    except ValueError:
        error = 'Fejl i indtastning'
    return val, error

希望有人能给我一两个提示。

如果我没看错,那么您正在寻求通过消除重复代码来使代码更加模块化。在这里您可以充分利用 BLUEPRINTS -http://flask.pocoo.org/docs/0.10/blueprints/ .

您可以编写通用代码 shape_input.py 并为其定义一个方法 (def)。圆形或矩形可以作为参数传递给 def。这样,您最终将消除重复代码。虽然调用不同的 HTML 模板 - 视图 - 可能会助您一臂之力。

希望对您有所帮助。