在控制台中构建功能。 第2部分(时间表)

开始开始

图片

上一次我决定建立函数值表。 制定时间表本身的时机已经到了,所有这些实际上已经开始了。

因此,主要思想如下。 将坐标轴顺时针旋转90度。 为了简化构造而不在任何工作表中存储有关每个点的数据,这是必需的。

接下来,我们将游戏的坐标轴限制为82个字符,以提高图表的可读性。 显然,这样做会使我们失去准确性,并且日程安排会更加示意图化(过于紧凑),尤其是对于“酷”功能,但仍然如此。

此后,我们计算x轴相对于玩家轴的位置,也就是说,我们看一下将有一个点(x,0)的位置。 好了,此时我们将逐行分配x函数y1的值。

走吧

首先,我们需要以下公式:

=y1y1/80



我们将为日程表本身分配80个职位,剩下的两个职位将纯粹用于装饰。 通过此公式,我们可以找到哪个值范围对应于图表中的一个位置。 然后,我们可以在其上正确标记当前点。

概述了主要思想,因此让我们继续进行代码本身

dial_length = 12 label = "  y1 = x**3 - 2*x**2 + 4*x - 8" print("{1:>{0}}".format(len(label) + dial_length, label), '\n') print("{aux[1]:>{aux[0]}}\n {aux[2]:>{aux[0]}}>\n".format(aux = [dial_length + 82, 'y' , 82*'-'])); 

包括感谢第一部分的注释,我了解了诸如format之类的东西。 在我看来,这真的比带铃鼓的舞蹈要方便得多,因此,通过计算缩进的大量代码变成了几行

 print("{1:>{0}}".format(len(label) + dial_length, label), '\n') 

单位负责作为格式函数的参数传递的元素编号,即它是实际上在屏幕上显示的label变量的“链接”(不是字面意义)。 编号与图纸完全相同-从头开始。

一对字符:>用于在右侧对齐显示的文本。 好了,需要在>字符后加上{0}以确定所需的行位置数。

也就是说,在这种情况下,我们为行标签len(label)+ dial_length保留位置,标签本身仅接受len(label),并且在这些位置的集合内的右侧对齐文本。

 print("{1:>{0}}".format(len(label) + dial_length, label), '\n') print(dial_length*' ' + label, '\n') 

这些线是等效的


是的,对于字符串,使用第二个选项可能更容易,但是将第一个选项应用于一般开发不会有任何伤害)

 print("{aux[1]:>{aux[0]}}\n {aux[2]:>{aux[0]}}>\n".format(aux = [dial_length + 82, 'y' , 82*'-'])); 

甚至r_value类型的数组(在C ++中)也可以塞入格式,即在传递参数时直接创建的格式。

我们可以固定不变的变量,即它们不依赖于函数的当前值。

在python中,没有用于指定常量的条件const ,因此习惯上以大写字母调用此类变量,只是不要更改它们。

 MAX_Y1_VALUE_DIFFERENCE = (max_y1_value - min_y1_value) + \ (max_y1_value == min_y1_value) RATIO = MAX_Y1_VALUE_DIFFERENCE / 80 AXIS_X_POS = abs(int((- min_y1_value) / RATIO)) if (AXIS_X_POS > 80): AXIS_X_POS = 81 

由于明显的原因RATIO不能等于0,因此MAX_Y1_VALUE_DIFFERENCE应该为正数。 这就是第二项在作业右侧的原因。

我们通过公式计算的x轴位置

80y1xy1/y1y1



这个公式来自哪里? 我们只需计算从轴的起点(min(y1))到函数的当前值(y1(x))的分段(在游戏轴上)的比率以及从轴的起点到其末端的分段(max(y1))的比率。 好吧,我们将此比率乘以80即可找到从轴的起点到当前值的距离(以空格为单位)(因此,您只能使用整数),这将在图表上反映比率公式。

由于我们对y1(x)= 0处的位置感兴趣,因此将必要的值替换为公式。

现在您可以直接打印值

 while (is_sequence_decreasing and from_x >= to_x) or \ (not is_sequence_decreasing and from_x <= to_x): y1_cur_value = y1(from_x) cur_y1_value_and_min_difference = (y1_cur_value - min_y1_value) + \ (y1_cur_value == min_y1_value) * \ ((max_y1_value == min_y1_value)) pos_of_y = int(cur_y1_value_and_min_difference * 80 / \ MAX_Y1_VALUE_DIFFERENCE) 

这个周期已经为我们所熟悉。 我们将不得不第二次计算函数的每个值,以免将其存储在工作表或其他内容中。

游戏的位置由上述公式计算得出。

我们将必须修正与公式的上限差,前提是公式中的不确定性为零乘以零的情况。 如果出现这种不确定性,则意味着当前值为y1(x)= max(y1),这意味着游戏的当前值将与y轴的末端重合。

  print("{1:^{0}.6g}".format(dial_length, from_x), end='') if (negative_value_exists): if y1_cur_value <= 0 - RATIO / 2: req_aux = AXIS_X_POS - pos_of_y if (req_aux != 0): print(pos_of_y * ' ' + '*' + (req_aux - 1) * ' ' + '|') else: print((AXIS_X_POS - 1) * ' ' + '*' + '|') elif y1_cur_value >= 0 + RATIO / 2: req_aux = pos_of_y - AXIS_X_POS if (req_aux != 0): print(AXIS_X_POS * ' ' + '|' + (req_aux - 1) * ' ' + '*') else: print((AXIS_X_POS) * ' ' + '|*') else: print(AXIS_X_POS * ' ' + '*') else: print('|' + pos_of_y* ' ' + '*') AXIS_X_POS = 0 from_x += pace_x print((dial_length + AXIS_X_POS) * ' ' + '|\n', (dial_length + AXIS_X_POS - 3) * ' ' + 'x V') 

这部分代码直接负责打印图形本身。

 print("{1:^{0}.6g}".format(dial_length, from_x), end='') 

在这里,格式非常有用,可以简化代码。 ^使我们可以将数字对准所选区域的中心(在这种情况下为12个位置)。 g负责数字-如果没有小数部分,则不会打印(数字为int),否则-6个小数位

由于我们的图沿y轴限制为80个字符的空间,因此在我们的图上,不仅在y1(x)= 0的情况下,而且在附近[0-RATIO / 2,0 + RATIO时,该点处的函数的值都将与x轴重合。 / 2]。

总的来说,我们有星号(即点)和垂直杆(即x轴)位置的三种情况:'* |' (y1(x)<= 0-比率/ 2),'*'(0-比率/ 2 <y1(x)<0 +比率/ 2),'| *'(y1(x)> = 0 +比率/ 2),我们将考虑这三种情况。

  1. y1(x)<= 0-比率/ 2
    在这种情况下,该点位于x轴上,因此我们在空间中寻找从该点到该轴的距离。 由于四舍五入,可能发生变量AXIS_X_POS和pos_of_y的值可能重合的情况。 但这不可能,因为在这种情况下,我们将处于第三种情况。 在我们的情况下,该点与x轴不一致,因此需要附加条件,在相等的情况下,变量pos_of_y将减少1。
  2. y(x)> = 0 +比率/ 2
    这种情况与第一种情况相同,只有该点位于x轴的另一侧,并且为此调整了所有上述操作
  3. 其余的
    最简单的情况-只需在轴上打印一个星号

那就是如果我们有负值(y1(x)<0)。 如果不是,则只需键入“ |” 并确定该点的位置。

好吧,我们以一个额外的x轴结束了该程序。

因此,最终的代码:

 dial_length = 12 label = "  y1 = x**3 - 2*x**2 + 4*x - 8" print("{1:^{0}.6f}".format(dial_length, x_copy)) print("{1:>{0}}".format(len(label) + dial_length, label), '\n') print("{aux[1]:>{aux[0]}}\n {aux[2]:>{aux[0]}}>\n".format(aux = [dial_length + 81, 'y' , 82*'-']), end=''); MAX_Y1_VALUE_DIFFERENCE = (max_y1_value - min_y1_value) + \ (max_y1_value == min_y1_value) RATIO = MAX_Y1_VALUE_DIFFERENCE / 80 AXIS_X_POS = abs(int((- min_y1_value) / RATIO)) if (AXIS_X_POS > 80): AXIS_X_POS = 81 while (is_sequence_decreasing and from_x >= to_x) or \ (not is_sequence_decreasing and from_x <= to_x): y1_cur_value = y1(from_x) cur_y1_value_and_min_difference = (y1_cur_value - min_y1_value) + \ (y1_cur_value == min_y1_value) * \ ((max_y1_value == min_y1_value)) pos_of_y = int(cur_y1_value_and_min_difference * 80 / \ MAX_Y1_VALUE_DIFFERENCE) print("{1:^{0}.6g}".format(dial_length, from_x), end='') if (negative_value_exists): if y1_cur_value <= 0 - RATIO / 2: req_aux = AXIS_X_POS - pos_of_y if (req_aux != 0): print(pos_of_y * ' ' + '*' + (req_aux - 1) * ' ' + '|') else: print((AXIS_X_POS - 1) * ' ' + '*' + '|') elif y1_cur_value >= 0 + RATIO / 2: req_aux = pos_of_y - AXIS_X_POS if (req_aux != 0): print(AXIS_X_POS * ' ' + '|' + (req_aux - 1) * ' ' + '*') else: print((AXIS_X_POS) * ' ' + '|*') else: print(AXIS_X_POS * ' ' + '*') else: print('|' + pos_of_y* ' ' + '*') AXIS_X_POS = 0 from_x += pace_x print((dial_length + AXIS_X_POS) * ' ' + '|\n', (dial_length + AXIS_X_POS - 3) * ' ' + 'x V') 

在多个测试上运行程序

图片
图片
图片
图片

可行)

图片

Source: https://habr.com/ru/post/zh-CN426519/


All Articles