Example #1
0
 def make_areas_m_or_n_compare_ans(self, qt: str, answer: Answer, builder: AnswerBuilder,
                                   chain: TranslationChain, result: Result):
     data = self._search_direct(chain)
     operator = truediv if qt == 'areas_m_compare' else sub
     builder.feed_data(data)
     for (x, y), (n1, n2) in builder.product_data_with_binary(
             result['area'], result['index'],
             if_x_is_none=lambda _1, _2, na: f'无{na[0].subject()}数据记录,无法比较',
             if_y_is_none=lambda _1, _2, na: f'无{na[1].subject()}数据记录,无法比较'
     ):
         # 单位检查
         ux, uy = x.unit or '无', y.unit or '无'
         if builder.add_if_is_equal_or_not(ux, uy,
                                           no=f'{n1.subject()}的单位({ux})与{n2.subject()}的单位({uy})不同,无法比较'):
             answer.begin_sub_answers()
             n1.repr, n2.repr = x.repr, y.repr
             answer.add_sub_answers(f'{n1.subject()}为{x.val()},{n2.subject()}为{y.val()}')
             res1 = builder.binary_calculation(x.value, y.value, operator)
             if builder.add_if_is_not_none(res1,
                                           no=f'{n1.subject()}或{n2.subject()}非数值类型,无法比较'):
                 if qt == 'areas_m_compare':
                     answer.add_sub_answers(f'前者是后者的{res1}倍')
                 else:
                     answer.add_sub_answers(f'前者比后者{sign(res1)}{abs(res1)}{ux}')
             if qt == 'areas_m_compare':
                 res2 = builder.binary_calculation(y.value, x.value, truediv)
                 if builder.add_if_is_not_none(res2,
                                               no=f'{n1.subject()}或{n2.subject()}非数值类型,无法比较'):
                     answer.add_sub_answers(f'后者是前者的{res2}倍')
             answer.end_sub_answers()
Example #2
0
 def make_index_or_area_overall_ans(self, qt: str, answer: Answer, builder: AnswerBuilder,
                                    chain: TranslationChain, result: Result):
     if qt == 'index_overall':
         gen = [result['index']]
         tag = '指标'
     else:
         gen = [result['area'], result['index']]
         tag = ''
     data = self._search_double_direct_then_feed(chain)
     builder.feed_data(data)
     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()}的父级{tag}数据记录,无法比较'
     ):
         f.life_check(result['year'][0])
         if not f:
             answer.add_answer(f'无{n.subject()}父级{tag}数据记录,无法比较')
             return
         answer.begin_sub_answers()
         unit_x, unit_y = x.unit, y[0].unit
         if qt == 'area_overall':  # 交换值域
             f.area, f.name = f.name, n.name
         n.repr = f.repr = x.repr
         answer.add_sub_answers(f'{n.subject()}为{x.val()}')
         answer.add_sub_answers(f'其父级{tag}{f.subject()}为{y[0].val()}')
         if unit_x != unit_y:
             answer.add_sub_answers('两者单位不同,无法比较')
             answer.end_sub_answers()
             return
         res1 = builder.binary_calculation(x.value, y[0].value, truediv, percentage=True)
         if builder.add_if_is_not_none(res1, no=f'无效的{n.subject()}值类型,无法比较'):
             answer.add_sub_answers(f'前者占后者的{res1}%')
         res2 = builder.binary_calculation(y[0].value, x.value, truediv)
         if builder.add_if_is_not_none(res2, no=f'无效的{n.subject()}值类型,无法比较'):
             answer.add_sub_answers(f'后者是前者的{res2}倍')
         answer.end_sub_answers()
Example #3
0
 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')
Example #4
0
 def make_areas_g_compare_ans(self, answer: Answer, builder: AnswerBuilder,
                              chain: TranslationChain, result: Result):
     data = self._search_direct(chain)
     builder.feed_data(data)
     for item, name in builder.product_data_with_name(result['area'], result['index']):
         x, y = item
         if builder.binary_decision(
                 x, y,
                 not_x=f'无{result["year"][0]}年关于{name.subject()}的数据',
                 not_y=f'无{result["year"][0]}前一年关于{name.subject()}的数据'
         ):
             res = builder.growth_calculation(y.value, x.value)
             if builder.add_if_is_not_none(
                     res, to_sub=False,
                     no=f'{result["year"][0]}年{name.subject()}的记录非数值类型,无法计算'
             ):
                 answer.add_answer(f'{result["year"][0]}年的{name.subject()}为{y.val()},'
                                   f'其去年的为{x.val()},同比{sign(res, ("减少", "增长"))}{abs(res)}%')
Example #5
0
 def make_index_or_area_2_overall_ans(self, qt: str, answer: Answer, builder: AnswerBuilder,
                                      chain: TranslationChain, result: Result):
     years = '、'.join(result['year'])
     # init
     if qt == 'area_2_overall':
         unpack = True
         gen = [result["area"], result["index"]]
     else:
         unpack = False
         gen = [result["index"]]
     # collect data
     data = self._search_double_direct_then_feed(chain, unpack=unpack)
     builder.feed_data(data)
     # product data
     for x, y, f, n in builder.product_data_with_feed(
             *gen,
             if_x_is_none=lambda _1, _2, _3, na: f'无{years}这几年{na.subject()}的数据记录,无法比较',
             if_y_is_none=lambda _1, _2, _3, na: f'无{years}这几年{na.subject()}的父级数据记录,无法比较'
     ):
         temp = []  # 记录两次计算的结果值
         for i, year in enumerate(result["year"]):
             f.life_check(year)
             if not f:
                 answer.add_answer(f'无{year}年{n.subject()}的父级数据记录,无法比较')
                 continue
             unit_x, unit_y = x[i].unit, y[i].unit
             answer.begin_sub_answers()
             n.repr = x[i].repr
             answer.add_sub_answers(f'{year}年{n.subject()}为{x[i].value}{unit_x}')
             answer.add_sub_answers(f'其总体{f.name}{y[i].repr}为{y[i].value}{unit_y}')
             if unit_x != unit_y:
                 answer.add_sub_answers('两者单位不同,无法比较')
                 answer.end_sub_answers()
                 continue
             res = builder.binary_calculation(x[i].value, y[i].value, truediv, percentage=True)
             if builder.add_if_is_not_none(res, no=f'无效的{n}值类型,无法比较'):
                 answer.add_sub_answers(f'约占总体的{res}%')
                 temp.append(res)
             answer.end_sub_answers()
         if len(temp) == 2:
             num = round(temp[0] - temp[1], 2)
             answer.add_answer(f'前者相比后者{sign(num, ("降低", "提高"))}{abs(num)}%')
Example #6
0
 def make_indexes_or_areas_2m_or_2n_compare_ans(self, qt: str, answer: Answer, builder: AnswerBuilder,
                                                chain: TranslationChain, result: Result):
     # set operator
     if qt in ('areas_2m_compare', 'indexes_2m_compare'):
         operator = truediv
     else:
         operator = sub
     # set gen and flatten
     if qt in ('areas_2m_compare', 'areas_2n_compare'):
         gen = [result['area'], result['index']]
         unpack = True
     else:
         gen = [result['index']]
         unpack = False
     # code begin
     data = self._search_direct(chain, unpack=unpack)
     builder.feed_data(data)
     for item, name in builder.product_data_with_name(*gen):
         x, y = item
         if builder.binary_decision(
                 x, y,
                 not_x=f'无关于{result["year"][0]}年的{name.subject()}的记录',
                 not_y=f'无关于{result["year"][1]}年的{name.subject()}的记录'
         ):
             answer.begin_sub_answers()
             res = builder.binary_calculation(x.value, y.value, operator)
             if builder.add_if_is_not_none(res, no=f'{name.subject()}的记录为无效的值类型,无法比较'):
                 answer.add_sub_answers(f'{result["year"][0]}年的{name.subject()}为{x.val()}')
                 answer.add_sub_answers(f'{result["year"][1]}年的{name.subject()}为{y.val()}')
                 if qt in ('areas_2m_compare', 'indexes_2m_compare'):
                     ux, uy = x.unit, y.unit
                     # 单位为%的数值不支持此类型比较
                     if ux == uy == '%':
                         answer.add_sub_answers(f'它们单位为‘%’,不支持此类型的比较')
                     else:
                         answer.add_sub_answers(f'前者是后者的{res}倍')
                 else:
                     answer.add_sub_answers(f'前者比后者{sign(res, ("减少", "增加"))}{abs(res)}{x.unit}')
             answer.end_sub_answers()