def make_catalogs_or_indexes_change_ans(self, qt: str, answer: Answer, chain: TranslationChain, result: Result): tag = '目录' if qt == 'catalogs_change' else '指标' data = self._search_direct(chain) y = [len(item) for item in data] line = self.painter.paint_line(result['year'], f'{tag}个数', y, result.raw_question) answer.save_chart(line) answer.add_answer(f'该问题的回答已渲染为图像,详见:{CHART_RENDER_DIR}/{result.raw_question}.html')
def make_indexes_or_areas_trend_ans(self, qt: str, answer: Answer, builder: AnswerBuilder, chain: TranslationChain, result: Result, mark_point: bool = False): if qt == 'areas_trend': unpack = True gen = [result['area'], result['index']] else: unpack = False gen = [result['index']] # collect data = self._search_direct(chain, unpack=unpack) builder.feed_data(data) collects = [] # 根据不同单位划分数据 for item, name in builder.product_data_with_name(*gen): collect = [] units = set([n.unit for n in item if n.unit != '']) ys = builder.group_mapping_to_float(item) if builder.add_if_is_equal_or_not(sum(ys), 0, equal=False, no=f'指标“{name.subject()}”无任何值记录,无法比较'): for unit in units: tmp = [] for y, n in zip(ys, item): tmp.append(y if n.unit == unit else 0) collect.append((name.subject(), unit, tmp)) collects.append(collect) # paint if len(collects) != 0: bar = self.painter.paint_bar(result['year'], collects, title=result.raw_question, mark_point=mark_point) answer.save_chart(bar) answer.add_answer(f'该问题的回答已渲染为图像,详见:{CHART_RENDER_DIR}/{result.raw_question}.html')
def make_indexes_or_areas_overall_trend_ans(self, qt: str, answer: Answer, builder: AnswerBuilder, chain: TranslationChain, result: Result): if qt == 'areas_overall_trend': unpack = True gen = [result["area"], result["index"]] else: unpack = False gen = [result["index"]] data = self._search_double_direct_then_feed(chain, unpack) builder.feed_data(data) parents = {} children = {} for x, y, f, n in builder.product_data_with_feed( *gen, if_x_is_none=lambda _1, _2, _3, na: f'无关于”{na.subject()}“的记录', if_y_is_none=lambda _1, _2, _3, na: f'无关于”{na.subject()}“的父级记录' ): xs = builder.group_mapping_to_float(x) if not builder.add_if_is_not_none(xs, to_sub=False, no=f'{n.subject()}的记录非数值类型,无法比较'): return parent = f.name + n.name if qt == 'areas_overall_trend' else f.name ys = builder.group_mapping_to_float(y) if not builder.add_if_is_not_none(ys, to_sub=False, no=f'{n.subject()}的父级记录({parent})非数值类型,无法比较'): return overall = [round(i / j, 3) if j != 0 else 0 for i, j in zip(xs, ys)] # 同一个父级指标将其子孙合并 parents[parent] = ys children.setdefault((parent, x[-1].unit), []).append((n.subject(), xs, overall)) # paint if len(parents) != 0: for bar in self.painter.paint_bar_stack_with_line(result['year'], children, parents, result.raw_question): answer.save_chart(bar) answer.add_answer(f'该问题的回答已渲染为图像,详见:{CHART_RENDER_DIR}/{result.raw_question}.html')
def make_index_compose_ans(self, answer: Answer, builder: AnswerBuilder, chain: TranslationChain, result: Result): data = self._search_direct(chain) builder.feed_data(data) collect = [] units = [] sub_titles = [] # for overall sqls_overall = [sql for sql in chain.iter(3)] data_overall = self._search_direct(sqls_overall) # collect for total, (item, name) in zip( data_overall, builder.product_data_with_name(result['index']) ): # 为使两可迭代对象同步迭代和collect不用做判空,此处不使用if_is_none参数 if not item: answer.add_answer(f'指标“{name.name}”没有任何组成') continue indexes, areas = [], [] for n in item: n.life_check(result['year'][0]) if n: if n.label == 'Index': indexes.append(n.name) else: areas.append(n.name) if len(indexes) == 0 and len(areas) == 0: answer.add_answer(f'指标“{name.name}”没有任何组成') continue # for indexes sqls1 = [sql.format(i) for sql in chain.iter(1) for i in indexes] data1 = self._search_direct(sqls1) # for areas sqls2 = [sql.format(name.name, a) for sql in chain.iter(2) for a in areas] data2 = self._search_direct(sqls2) # make data pairs final_data = {} for k, v in zip(indexes + areas, data1 + data2): if not v: continue if v.child_id is None: continue try: final_data.setdefault(v.child_id, []).append((k, float(v.value))) except ValueError or TypeError: answer.add_answer(f'{name.name}中{k}的记录非数值类型,无法比较') return # make other for k, v in final_data.items(): op1 = sum([x[1] for x in v]) op2 = float(total.value) if op1 < int(op2): # 舍弃一些误差,避免图中出现极小的部分 final_data[k].append(('其他', round(op2 - op1, 2))) collect.append(final_data) units.append(total.unit) sub_titles.append(f'{name.subject()}为{total.val()},其构成分为:') # paint for pie in self.painter.paint_pie(collect, units, title=result.raw_question, sub_titles=sub_titles): answer.save_chart(pie) answer.add_answer(f'该问题的回答已渲染为图像,详见:{CHART_RENDER_DIR}/{result.raw_question}.html')