Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import turtle
- import enum
- import math
- class SumMethods(enum.Enum):
- LEFT = 0
- MIDPOINT = 1
- RIGHT = 2
- TRAPEZOID = 3
- GRAPH_START = (-320, -300) # to scale the graphics
- HEIGHT = 500
- WIDTH = 500
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def f(x):
- return math.pow(2, x)
- X_MIN = 1.0
- X_MAX = 2.0
- N = 7
- M = 2.883
- TASK = 7
- ACCURACY = 25
- SCALE = 50
- METHOD = SumMethods.MIDPOINT
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- grapher = turtle.Turtle()
- finder = turtle.Turtle()
- status = turtle.Turtle()
- sum_txt = turtle.Turtle()
- axes = turtle.Turtle()
- screen = grapher.getscreen()
- screen.screensize(WIDTH, HEIGHT)
- screen.title('Riemann Sum Calculator by @SchrodZzz')
- grapher.penup()
- grapher.speed(0)
- grapher.hideturtle()
- grapher.goto(GRAPH_START)
- finder.penup()
- finder.speed(0)
- finder.hideturtle()
- finder.goto(GRAPH_START)
- status.penup()
- status.hideturtle()
- status.goto(WIDTH / 2 - 50, -1 * HEIGHT / 2 + 15)
- axes.hideturtle()
- axes.penup()
- sum_txt.hideturtle()
- sum_txt.penup()
- sum_txt.goto(WIDTH / 2 - 55, -1 * HEIGHT / 2)
- def draw_axes():
- grapher.goto(GRAPH_START[0], HEIGHT)
- grapher.pendown()
- grapher.goto(GRAPH_START[0], -1 * HEIGHT)
- grapher.penup()
- grapher.goto(WIDTH, GRAPH_START[1])
- grapher.pendown()
- grapher.goto(-1 * WIDTH, GRAPH_START[1])
- grapher.penup()
- grapher.goto(GRAPH_START)
- for x in range(0, math.ceil(WIDTH / SCALE) + 1):
- axes.goto(GRAPH_START[0] + x * SCALE, GRAPH_START[1] - 5)
- axes.write(str(x))
- for y in range(1, math.ceil(HEIGHT / SCALE) + 1):
- axes.goto(GRAPH_START[0] - 5, GRAPH_START[1] + y * SCALE)
- axes.write(str(y))
- grapher.goto(GRAPH_START)
- def draw_func(color='red'):
- grapher.goto(X_MIN * SCALE + GRAPH_START[0], f(X_MIN) * SCALE + GRAPH_START[1])
- old_color = grapher.pencolor()
- grapher.pencolor(color)
- grapher.pendown()
- for x in [X_MIN + i * (X_MAX - X_MIN) / ACCURACY for i in range(ACCURACY + 1)]:
- status.clear()
- y = f(x)
- status.write('({0:.2f}, {1:.2f})'.format(x, y))
- grapher.goto(SCALE * x + GRAPH_START[0], SCALE * y + GRAPH_START[1])
- grapher.penup()
- grapher.pencolor(old_color)
- grapher.goto(GRAPH_START)
- def draw_trapezoid(x, y, w, h1, h2):
- finder.goto(x * SCALE + GRAPH_START[0], y * SCALE + GRAPH_START[1])
- finder.pendown()
- finder.goto(x * SCALE + GRAPH_START[0], (y + h1) * SCALE + GRAPH_START[1])
- finder.goto((x + w) * SCALE + GRAPH_START[0], (y + h2) * SCALE + GRAPH_START[1])
- finder.goto((x + w) * SCALE + GRAPH_START[0], y * SCALE + GRAPH_START[1])
- finder.goto(x * SCALE + GRAPH_START[0], y * SCALE + GRAPH_START[1])
- finder.penup()
- def draw_rect(x, y, w, h):
- draw_trapezoid(x, y, w, y + h, y + h)
- def find_n(): # doesn't work for non monotonic functions
- left = 0
- right = math.ceil((X_MAX - X_MIN) * ACCURACY)
- cur = 0
- global N
- while right - left > 1:
- finder.clear()
- sum_txt.clear()
- N = int((left + right) / 2)
- cur = draw_riemann_sum()
- if cur > M:
- right = N
- else:
- left = N
- if cur < M:
- finder.clear()
- sum_txt.clear()
- status.clear()
- sum_txt.write('Impossible to get {0:.3f}\nHighest value is {1:.3f}'.format(M, cur),
- font=('Arial', 16, 'normal'))
- print('N = {0}\n{1} < {2} : {3}'.format(N, M, cur, M < cur))
- def calc_rect(method, x, dx):
- if method == SumMethods.LEFT:
- y = f(x)
- draw_rect(x, 0, dx, y)
- return dx * y
- elif method == SumMethods.RIGHT:
- y = f(x + dx)
- draw_rect(x + dx, 0, -dx, y)
- return dx * y
- elif method == SumMethods.MIDPOINT:
- y = f(x + dx / 2)
- draw_rect(x, 0, dx, y)
- return dx * y
- elif method == SumMethods.TRAPEZOID:
- y1 = f(x)
- y2 = f(x + dx)
- draw_trapezoid(x, 0, dx, y1, y2)
- if y2 > y1:
- return (dx * y1) + (0.5 * dx * (y2 - y1))
- else:
- return (dx * y2) + (0.5 * dx * (y1 - y2))
- return -1
- def draw_riemann_sum(color='green'):
- finder.goto(GRAPH_START)
- old_color = finder.pencolor()
- finder.pencolor(color)
- dx = (X_MAX - X_MIN) / N
- total = 0
- for x in [X_MIN + i * dx for i in range(N)]:
- sum_txt.clear()
- total += calc_rect(METHOD, x, dx)
- sum_txt.write('Sum: {0:.3f}...'.format(total))
- finder.pencolor(old_color)
- sum_txt.clear()
- sum_txt.write('Riemann Sum is {0:.3f}'.format(total), font=('Arial', 16, 'normal'))
- return total
- def get_scale():
- global SCALE
- SCALE = int(max(HEIGHT, WIDTH) / max(f(X_MAX), X_MAX, f(X_MIN), X_MIN))
- def define_inf():
- global X_MAX, X_MIN
- try:
- f(X_MIN)
- except:
- X_MIN += 0.1
- define_inf()
- try:
- f(X_MAX)
- except:
- X_MAX -= 0.1
- define_inf()
- return
- if __name__ == '__main__':
- define_inf()
- get_scale()
- draw_axes()
- draw_func()
- if TASK == 5:
- draw_riemann_sum()
- elif TASK == 7:
- find_n()
- else:
- sum_txt.goto(0, 0)
- sum_txt.write('Unknown task - select 5 or 7 :'
- '\n\t*5 - Find sum by number of split points(N)'
- '\n\t*7 - Find closest sum that more than M', font=('Arial', 16, 'normal'))
- turtle.done()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement