0

我正在做我的第一个项目,我正在使用 Pygal 可视化数据库中的一些数据。

我正在使用最新版本的 Python (3.6.5)、Flask、Pygal,我的 IDE 是 Pycharm

该项目是一个简单的预算应用程序,其中输入每月支出的计划预算,然后输入该费用/项目的实际金额(例如每月汽车费用,如汽油)。

我使用 Pygal 显示 2 个条形图。第一个(按预期工作)显示总计划金额与总实际金额:

在此处输入图像描述

第二张图表显示了每项费用/项目的计划与实际(例如每月的汽车费用,如汽油)

我面临的问题是图表混淆了标签和数量。它们根据输入的顺序显示在图表中,而不是项目类型。

例如:

在此处输入图像描述

在上图中,有 3 个项目:Masina(汽车)、Salariu(工资)和 Economii(储蓄)。

蓝色栏所代表的金额(实际金额)应显示在标签 Economii 下,而不是 Masina 下,并且我已将其作为数据库中的第一个实际值输入并不重要。

此外,在数据库中为相同的费用项目(在我们的例子中为经济型)添加更多的实际金额只会添加更多的列,并且不会在同一列上汇总:

在此处输入图像描述

这是我正在使用的数据库查询功能:

def GraphData():
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
db_path = os.path.join(BASE_DIR, 'budget_db.db')
with sqlite3.connect(db_path) as db:
    c = db.cursor()
    d = db.cursor()
    c.execute('SELECT title, category, name, planned_amount_month FROM Post')
    d.execute('SELECT title_actual, category_actual, actual_amount_name, actual_amount FROM ActualPost')
    data_planned = c.fetchall()
    data_actual = d.fetchall()
return data_planned, data_actual

下面是我为这两个图表创建的路线。标签是从title_planned列表中拉出的,我感觉我面临的问题是因为我正在创建列表并附加它们。我认为我应该创建字典,但我不知道如何不搞乱其他一切:

 @posts.route("/home")
def graphing():
data_planned, data_actual = GraphData()
title_planned = []
value_planned = []
title_actual = []
value_actual = []
for planned_row in data_planned:
    title_planned.append(planned_row[2])
    value_planned.append(planned_row[3])
for actual_row in data_actual:
    title_actual.append(actual_row[2])
    value_actual.append(actual_row[3])

graph = pygal.Bar(title=u'Total Planned Values vs Total Actual Values')
graph.add('Planned', [{'value': sum(value_planned), 'label': 'Total for Planned Budget:'}])
graph.add('Actual', [{'value': sum(value_actual), 'label': 'Total for Actual Amounts:'}])
graph_data = graph.render_data_uri()

graph_all = pygal.Bar(title=u'Planned Budget per item vs Actual Amounts per item')
graph_all.x_labels = title_planned
graph_all.add('Planned', value_planned)
graph_all.add('Actual', value_actual)
graph_all_data = graph_all.render_data_uri()

return render_template('home.html', graph_data=graph_data, graph_all_data=graph_all_data)

编辑:

我一直在尝试在路线中使用 2 个字典,其中费用项目作为字典键(title_planned_sum/ title_actual_sum),金额作为字典值(value_planned_sum/ value_actual_sum):

tv_planned = dict(zip(title_planned, value_planned))
tv_planned_sum = {title_planned_sum: sum(value_planned_sum) for title_planned_sum, value_planned_sum in tv_planned.items()}

tv_actual = dict(zip(title_actual, value_actual))
tv_actual_sum = {title_actual_sum: sum(value_actual_sum) for title_actual_sum, value_actual_sum in tv_actual.items()}

这是完整的路线:

@posts.route("/home")
def graphing():
    data_planned, data_actual = GraphData()

    title_planned = []
    value_planned = []
    title_actual = []
    value_actual = []

    for planned_row in data_planned:
        title_planned.append(planned_row[2])
        value_planned.append(planned_row[3])

    for actual_row in data_actual:
        title_actual.append(actual_row[2])
        value_actual.append(actual_row[3])

    tv_planned = dict(zip(title_planned, value_planned))
    tv_planned_sum = {title_planned_sum: sum(value_planned_sum) for title_planned_sum, value_planned_sum in tv_planned.items()}

    tv_actual = dict(zip(title_actual, value_actual))
    tv_actual_sum = {title_actual_sum: sum(value_actual_sum) for title_actual_sum, value_actual_sum in tv_actual.items()}

    graph = pygal.Bar(title=u'Total Planned Values vs Total Actual Values')
    graph.add('Planned', [{'value': sum(value_planned), 'label': 'Total for Planned Budget:'}])
    graph.add('Actual', [{'value': sum(value_actual), 'label': 'Total for Actual Amounts:'}])
    graph_data = graph.render_data_uri()

    graph_all = pygal.Bar(title=u'Planned Budget per item vs Actual Amounts per item')
    graph_all.x_labels = title_planned
    graph_all.add('Planned', tv_planned_sum)
    graph_all.add('Actual', tv_actual_sum)
    graph_all_data = graph_all.render_data_uri()

    return render_template('home.html', graph_data=graph_data, graph_all_data=graph_all_data)

但是,当然,现在我收到了这个调试错误:

TypeError: 'float' object is not iterable

这是因为,在我尝试使用的 2 个字典中,我试图将接收多个值的每个键的值与 sum(value_planned_sum).

4

1 回答 1

0

我让它工作了!

最后我意识到我的问题过于复杂了,所以我拿出笔和纸开始做一些伪代码,看看我的代码中的第一步在哪里,我可以轻松地计算导致我的浮点数总和头痛。

第 1 步:在我的路线中,我可以创建一个包含嵌套元组的列表(每个有 2 个元素:str 和 float)

第 2 步:现在,如果某些元组在索引 [0] 上具有相同的元素,我如何对索引 [1] 上的浮点元素求和?

所以,我在 reddit.com/r/learnpython 上问了这个问题,用户diesch给了我一个可以成功使用的想法:导入itertools包并从中使用groupby().

这是我的路线代码现在的样子:

@posts.route("/home")
def graphing():
    data_planned, data_actual = GraphData()

    title_planned = []
    value_planned = []
    title_actual = []
    value_actual = []
    planned = []
    actual = []

    for planned_row in data_planned:
        title_planned.append(planned_row[2])
        value_planned.append(planned_row[3])
        planned_list = zip(title_planned, value_planned)
        for key, group in itertools.groupby(sorted(planned_list), lambda  x: x[0]):
            asum = 0
            for i in group:
                asum += i[1]
            planned.append((key, asum))

    planned_dict = dict(planned)

    for actual_row in data_actual:
        title_actual.append(actual_row[2])
        value_actual.append(actual_row[3])
        actual_list = zip(title_actual, value_actual)
        for key, group in itertools.groupby(sorted(actual_list), lambda  x: x[0]):
            asum = 0
            for i in group:
                asum += i[1]
            actual.append((key, asum))

    actual_dict = dict(actual)

    graph = pygal.Bar(title=u'Total Planned Values vs Total Actual Values')
    graph.add('Planned', [{'value': sum(value_planned), 'label': 'Total for Planned Budget:'}])
    graph.add('Actual', [{'value': sum(value_actual), 'label': 'Total for Actual Amounts:'}])
    graph_data = graph.render_data_uri()

    graph_all = pygal.Bar(title=u'Planned Budget per item vs Actual Amounts per item')
    graph_all.x_labels = title_planned
    graph_all.add('Planned', planned_dict)
    graph_all.add('Actual', actual_dict)
    graph_all_data = graph_all.render_data_uri()

    return render_template('home.html', graph_data=graph_data, graph_all_data=graph_all_data)    
于 2018-06-10T12:27:25.040 回答