简单的算术示例生成器,不仅用于

你好

在这篇“文章”中,或者说在本文中,我将展示一种非常简单的方法来使人们了解乳胶和python的基础知识。




怎么了


好吧,您可以生成简单的表达式供孩子们计数。 或者就是那样。 是的,如果您像我一样狂热,至少要穿上墙纸。

这应该如何工作?


这个想法真的很简单,绝对任何人都可以编写这样的程序。 我们想要生成一个等于数字n(用户输入)的表达式。 任何数字都可以用算术表达式替换,例如3 = 1 +2。2是4 /2。这就是我们生成3 = 1 + 4/2的方式。 同样,我们引入了几种不同的操作,并将其包装在公式语言LaTeX中。

您将需要...
一周的python和matplotlib经验。 我是认真的

主要机制


我们需要解析该表达式,以便从中获取数字。 让我们把我们的班级称为问题产生器(我们都非常想念它!)

import random from math import log import math import sys sys.setrecursionlimit(1000) #       class ProblemGenerator: def extract_nums(self, exp): symbols = list(exp) NUM = "1234567890." for i in range(len(symbols)): symbols[i] = "N" if symbols[i] in NUM else "T" begins = [] ends = [] for i in range(len(symbols) - 1): fn = symbols[i] + symbols[i + 1] if fn == "TN": begins.append(i) elif fn == "NT": ends.append(i) if exp[-1] in NUM: ends.append(len(exp) - 1) if exp[0] in NUM: begins = [-1] + begins return [(x + 1, y + 1) for x, y in zip(begins, ends)] 

extract_nums函数的含义是获取n对数字(a,b),其中a是第一个字符的位置,b是最后一个+ 1的位置。

例如,如果我们运行以下代码:

 gen = ProblemGenerator() print(gen.extract_nums("13+256/355+25")) 

我们将看到:

 [(0, 2), (3, 6), (7, 10), (11, 13)] 

也就是说,它是一个元组数组。 (0,2)表示介于0(含)和2(不含)之间的数字。

现在我们要制作不同的运算符,让我们从乘法和求和开始。 声明三个功能

 def unmin(*args, acc=2): r = [] for arg in args: f = round(arg, acc) if f > 0: f = str(f) else: f = "(" + str(f) + ")" r.append(f) return r def __c_sum(num): a = round(random.random() * 100, 3) b = num - a a, b = unmin(a, b) return a + " + " + b def __c_mul(num): a = num / (random.random() * 100 + 10) if a == 0.0: b = random.random() else: b = num / a a, b = unmin(a, b) return a + " * " + b 

unmin函数的本质不仅在于将所有参数都简单地转换为字符串,而且如果其小于零,则将其括在括号中。 例如,我们得到数字a = 3,b = -4。 如果我们写

 a = 3 b = -4 a, b = unmin(a, b) 

然后a =“ 3”,b =“(-4)”

好了,其余函数都很清楚:__c_sum返回形式为“ 13 + 4”的字符串,而__c_mul返回“ 13 * 4”的形式。
剩下的是将这两部分结合起来,并用表达式替换表达式中的每个数字。
将以下代码添加到ProblemGenerator:

 class ProblemGenerator: ... def __init__(self): self.funcs = [] def add_expander(self, func): self.funcs.append(func) def complexify(self, num): return random.choice(self.funcs)(num) def __rxp__(self, exp): x, y = random.choice(self.extract_nums(exp)) exp = exp[:x] + "(" + self.complexify(float(exp[x:y])) + ")" + exp[y:] return exp def randexpr(self, ans, steps): e = str(ans) for i in range(steps): e = self.__rxp__(e) return e 

complexify需要一些数字,并返回一个字符串-一个复杂的表达式。 例如,如果我们写:

 gen = ProblemGenerator() gen.add_expander(__c_sum) print(gen.complexify(13)) 

我们得到:

 31.2 + (-18.2) 

__rxp__如何工作? 我们从一个表达式中随机选择一个数字的位置(例如,如果有一个表达式“ 13 + 35/45”,那么假设我们选择了(3,5)),然后用等于该数字的表达式替换该数字。 也就是说,我想:

“ 13 + 35/45”-随机数(3,5)
“ 13+” +“(12 + 23)” +“ / 45”
“ 13+(12 + 23)/ 45”

这就是__rxp__的工作方式
好吧,randexpr的工作非常简单。 例如,如果我们有四个步骤,则表达式将像这样打开:

 13 (5.62 + 7.38) ((20.63 + (-15.01)) + 7.38) ((20.63 + (-(67.5 + (-52.49)))) + 7.38) ((20.63 + (-((15.16 + 52.34) + (-52.49)))) + 7.38) 

让我们尝试运行:

 gen = ProblemGenerator() gen.add_expander(__c_sum) gen.add_expander(__c_mul) exp = gen.randexpr(1, 5) print(exp) 

结果:

 ((6.63 + (56.62 + 16.8)) + (-((60.53 + 3.61) + 14.91))) 

乳胶


奇怪的是,最简单的仍然存在。 我们将宣布许多不同的LaTeX运营商:

 def __l_sum(num): a = 100 ** (random.random() * 2) b = num - a a, b = unmin(a, b) return a + " + " + b def __l_div(num): a = num * (random.random() * 100 + 10) if a == 0.0: b = random.random() else: b = a / num a, b = unmin(a, b) return "\\frac{" + a + "}{" + b + "}" def __l_pow(num): if num == 0: return str(random.randint(2, 7)) + "^{-\\infty}" a = random.randint(0, 10) + 3 b = math.log(abs(num), a) a, b = unmin(a, b) return ("-" if num < 0 else "") + a + "^{" + b + "}" def __l_sqrt(num): a = num ** 0.5 a = unmin(a)[0] return "\\sqrt{" + a + "}" def __l_int(num): patterns = [ ("x^{2}", (3 * num) ** (1/3), "dx"), ("y^{3}", (4 * num) ** (1/4), "dy"), ("\sqrt{t}", (1.5 * num) ** (2/3), "dt") ] p, b, f = random.choice(patterns) b = str(round(b, 3)) return "\\int_{0}^{" + b + "} " + p + " " + f def __l_sig(num): a = random.randint(1, 10) b = random.randint(1, 10) + a s = sum([i for i in range(a, b + 1)]) c = num / s a, b, c = unmin(a, b, c) return "\\sum_{i=" + a + "}^{" + b + "} i*" + c 

将所有功能添加到gen中:

 gen = ProblemGenerator() gen.add_expander(__l_sum) #    gen.add_expander(__l_div) #  gen.add_expander(__l_pow) #  gen.add_expander(__l_sqrt) #   gen.add_expander(__l_int) #   gen.add_expander(__l_sig) #   

最后,添加结果的输出:

 import matplotlib.pyplot as plt plt.axis("off") latex_expression = gen.randexpr(1, 30) # 30  .    1 plt.text(0.5, 0.5, "$" + latex_expression + "$", horizontalalignment='center', verticalalignment='center', fontsize=20) plt.show() 

仅此而已。

整个代码
 import random from math import log import math import sys sys.setrecursionlimit(1000) class ProblemGenerator: def extract_nums(self, exp): symbols = list(exp) NUM = "1234567890." for i in range(len(symbols)): symbols[i] = "N" if symbols[i] in NUM else "T" begins = [] ends = [] for i in range(len(symbols) - 1): fn = symbols[i] + symbols[i + 1] if fn == "TN": begins.append(i) elif fn == "NT": ends.append(i) if exp[-1] in NUM: ends.append(len(exp) - 1) if exp[0] in NUM: begins = [-1] + begins return [(x + 1, y + 1) for x, y in zip(begins, ends)] def __init__(self): self.funcs = [] def add_expander(self, func): self.funcs.append(func) def complexify(self, num): return random.choice(self.funcs)(num) def __rxp__(self, exp): x, y = random.choice(self.extract_nums(exp)) exp = exp[:x] + "(" + self.complexify(float(exp[x:y])) + ")" + exp[y:] return exp def randexpr(self, ans, steps): e = str(ans) for i in range(steps): e = self.__rxp__(e) return e def unmin(*args, acc=2): r = [] for arg in args: f = round(arg, acc) if f > 0: f = str(f) else: f = "(" + str(f) + ")" r.append(f) return r def __c_sum(num): a = round(random.random() * 100, 3) b = num - a a, b = unmin(a, b) return a + " + " + b def __c_mul(num): a = num / (random.random() * 100 + 10) if a == 0.0: b = random.random() else: b = num / a a, b = unmin(a, b, acc=5) return a + " * " + b def __c_sub(num): a = num + 100 ** (random.random() * 2) b = (a - num) a, b = unmin(a, b) return a + " - " + b def __c_log(num): fr = random.randint(300, 500) a = math.e ** (num / fr) a, fr = unmin(a, fr, acc=5) return "log(" + a + ") * " + fr def __l_sum(num): a = 100 ** (random.random() * 2) b = num - a a, b = unmin(a, b) return a + " + " + b def __l_div(num): a = num * (random.random() * 100 + 10) if a == 0.0: b = random.random() else: b = a / num a, b = unmin(a, b) return "\\frac{" + a + "}{" + b + "}" def __l_pow(num): if num == 0: return str(random.randint(2, 7)) + "^{-\\infty}" a = random.randint(0, 10) + 3 b = math.log(abs(num), a) a, b = unmin(a, b) return ("-" if num < 0 else "") + a + "^{" + b + "}" def __l_sqrt(num): a = num ** 0.5 a = unmin(a)[0] return "\\sqrt{" + a + "}" def __l_int(num): patterns = [ ("x^{2}", (3 * num) ** (1/3), "dx"), ("y^{3}", (4 * num) ** (1/4), "dy"), ("\sqrt{t}", (1.5 * num) ** (2/3), "dt") ] p, b, f = random.choice(patterns) b = str(round(b, 3)) return "\\int_{0}^{" + b + "} " + p + " " + f def __l_sig(num): a = random.randint(1, 10) b = random.randint(1, 10) + a s = sum([i for i in range(a, b + 1)]) c = num / s a, b, c = unmin(a, b, c) return "\\sum_{i=" + a + "}^{" + b + "} i*" + c gen = ProblemGenerator() gen.add_expander(__l_sum) gen.add_expander(__l_div) gen.add_expander(__l_pow) gen.add_expander(__l_sqrt) gen.add_expander(__l_int) gen.add_expander(__l_sig) import matplotlib.pyplot as plt plt.axis("off") latex_expression = gen.randexpr(1, 30) # 30  .    1 plt.text(0.5, 0.5, "$" + latex_expression + "$", horizontalalignment='center', verticalalignment='center', fontsize=15) plt.show() 


结果(3个屏幕截图)






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


All Articles