Advertisement
SchrodZzz

matan_04.01

Apr 1st, 2019
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.45 KB | None | 0 0
  1. import turtle
  2. import enum
  3. import math
  4.  
  5.  
  6. class SumMethods(enum.Enum):
  7.     LEFT = 0
  8.     MIDPOINT = 1
  9.     RIGHT = 2
  10.     TRAPEZOID = 3
  11.  
  12.  
  13. GRAPH_START = (-320, -300)  # to scale the graphics
  14. HEIGHT = 500
  15. WIDTH = 500
  16.  
  17.  
  18. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  19. def f(x):
  20.     return math.pow(2, x)
  21.  
  22.  
  23. X_MIN = 1.0
  24. X_MAX = 2.0
  25. N = 7
  26. M = 2.883
  27.  
  28. TASK = 7
  29.  
  30. ACCURACY = 25
  31.  
  32. SCALE = 50
  33.  
  34. METHOD = SumMethods.MIDPOINT
  35.  
  36. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  37.  
  38. grapher = turtle.Turtle()
  39. finder = turtle.Turtle()
  40. status = turtle.Turtle()
  41. sum_txt = turtle.Turtle()
  42. axes = turtle.Turtle()
  43.  
  44. screen = grapher.getscreen()
  45. screen.screensize(WIDTH, HEIGHT)
  46. screen.title('Riemann Sum Calculator by @SchrodZzz')
  47.  
  48. grapher.penup()
  49. grapher.speed(0)
  50. grapher.hideturtle()
  51. grapher.goto(GRAPH_START)
  52.  
  53. finder.penup()
  54. finder.speed(0)
  55. finder.hideturtle()
  56. finder.goto(GRAPH_START)
  57.  
  58. status.penup()
  59. status.hideturtle()
  60. status.goto(WIDTH / 2 - 50, -1 * HEIGHT / 2 + 15)
  61.  
  62. axes.hideturtle()
  63. axes.penup()
  64. sum_txt.hideturtle()
  65. sum_txt.penup()
  66. sum_txt.goto(WIDTH / 2 - 55, -1 * HEIGHT / 2)
  67.  
  68.  
  69. def draw_axes():
  70.     grapher.goto(GRAPH_START[0], HEIGHT)
  71.     grapher.pendown()
  72.     grapher.goto(GRAPH_START[0], -1 * HEIGHT)
  73.     grapher.penup()
  74.     grapher.goto(WIDTH, GRAPH_START[1])
  75.     grapher.pendown()
  76.     grapher.goto(-1 * WIDTH, GRAPH_START[1])
  77.     grapher.penup()
  78.     grapher.goto(GRAPH_START)
  79.     for x in range(0, math.ceil(WIDTH / SCALE) + 1):
  80.         axes.goto(GRAPH_START[0] + x * SCALE, GRAPH_START[1] - 5)
  81.         axes.write(str(x))
  82.     for y in range(1, math.ceil(HEIGHT / SCALE) + 1):
  83.         axes.goto(GRAPH_START[0] - 5, GRAPH_START[1] + y * SCALE)
  84.         axes.write(str(y))
  85.     grapher.goto(GRAPH_START)
  86.  
  87.  
  88. def draw_func(color='red'):
  89.     grapher.goto(X_MIN * SCALE + GRAPH_START[0], f(X_MIN) * SCALE + GRAPH_START[1])
  90.     old_color = grapher.pencolor()
  91.     grapher.pencolor(color)
  92.     grapher.pendown()
  93.     for x in [X_MIN + i * (X_MAX - X_MIN) / ACCURACY for i in range(ACCURACY + 1)]:
  94.         status.clear()
  95.         y = f(x)
  96.         status.write('({0:.2f}, {1:.2f})'.format(x, y))
  97.         grapher.goto(SCALE * x + GRAPH_START[0], SCALE * y + GRAPH_START[1])
  98.     grapher.penup()
  99.     grapher.pencolor(old_color)
  100.     grapher.goto(GRAPH_START)
  101.  
  102.  
  103. def draw_trapezoid(x, y, w, h1, h2):
  104.     finder.goto(x * SCALE + GRAPH_START[0], y * SCALE + GRAPH_START[1])
  105.     finder.pendown()
  106.     finder.goto(x * SCALE + GRAPH_START[0], (y + h1) * SCALE + GRAPH_START[1])
  107.     finder.goto((x + w) * SCALE + GRAPH_START[0], (y + h2) * SCALE + GRAPH_START[1])
  108.     finder.goto((x + w) * SCALE + GRAPH_START[0], y * SCALE + GRAPH_START[1])
  109.     finder.goto(x * SCALE + GRAPH_START[0], y * SCALE + GRAPH_START[1])
  110.     finder.penup()
  111.  
  112.  
  113. def draw_rect(x, y, w, h):
  114.     draw_trapezoid(x, y, w, y + h, y + h)
  115.  
  116.  
  117. def find_n():  # doesn't work for non monotonic functions
  118.     left = 0
  119.     right = math.ceil((X_MAX - X_MIN) * ACCURACY)
  120.     cur = 0
  121.     global N
  122.     while right - left > 1:
  123.         finder.clear()
  124.         sum_txt.clear()
  125.         N = int((left + right) / 2)
  126.         cur = draw_riemann_sum()
  127.         if cur > M:
  128.             right = N
  129.         else:
  130.             left = N
  131.         if cur < M:
  132.             finder.clear()
  133.             sum_txt.clear()
  134.             status.clear()
  135.             sum_txt.write('Impossible to get {0:.3f}\nHighest value is {1:.3f}'.format(M, cur),
  136.                           font=('Arial', 16, 'normal'))
  137.     print('N = {0}\n{1} < {2} : {3}'.format(N, M, cur, M < cur))
  138.  
  139.  
  140. def calc_rect(method, x, dx):
  141.     if method == SumMethods.LEFT:
  142.         y = f(x)
  143.         draw_rect(x, 0, dx, y)
  144.         return dx * y
  145.     elif method == SumMethods.RIGHT:
  146.         y = f(x + dx)
  147.         draw_rect(x + dx, 0, -dx, y)
  148.         return dx * y
  149.     elif method == SumMethods.MIDPOINT:
  150.         y = f(x + dx / 2)
  151.         draw_rect(x, 0, dx, y)
  152.         return dx * y
  153.     elif method == SumMethods.TRAPEZOID:
  154.         y1 = f(x)
  155.         y2 = f(x + dx)
  156.         draw_trapezoid(x, 0, dx, y1, y2)
  157.         if y2 > y1:
  158.             return (dx * y1) + (0.5 * dx * (y2 - y1))
  159.         else:
  160.             return (dx * y2) + (0.5 * dx * (y1 - y2))
  161.     return -1
  162.  
  163.  
  164. def draw_riemann_sum(color='green'):
  165.     finder.goto(GRAPH_START)
  166.     old_color = finder.pencolor()
  167.     finder.pencolor(color)
  168.     dx = (X_MAX - X_MIN) / N
  169.     total = 0
  170.     for x in [X_MIN + i * dx for i in range(N)]:
  171.         sum_txt.clear()
  172.         total += calc_rect(METHOD, x, dx)
  173.         sum_txt.write('Sum: {0:.3f}...'.format(total))
  174.     finder.pencolor(old_color)
  175.     sum_txt.clear()
  176.     sum_txt.write('Riemann Sum is {0:.3f}'.format(total), font=('Arial', 16, 'normal'))
  177.     return total
  178.  
  179.  
  180. def get_scale():
  181.     global SCALE
  182.     SCALE = int(max(HEIGHT, WIDTH) / max(f(X_MAX), X_MAX, f(X_MIN), X_MIN))
  183.  
  184.  
  185. def define_inf():
  186.     global X_MAX, X_MIN
  187.     try:
  188.         f(X_MIN)
  189.     except:
  190.         X_MIN += 0.1
  191.         define_inf()
  192.     try:
  193.         f(X_MAX)
  194.     except:
  195.         X_MAX -= 0.1
  196.         define_inf()
  197.     return
  198.  
  199.  
  200. if __name__ == '__main__':
  201.     define_inf()
  202.     get_scale()
  203.     draw_axes()
  204.     draw_func()
  205.     if TASK == 5:
  206.         draw_riemann_sum()
  207.     elif TASK == 7:
  208.         find_n()
  209.     else:
  210.         sum_txt.goto(0, 0)
  211.         sum_txt.write('Unknown task - select 5 or 7 :'
  212.                       '\n\t*5 - Find sum by number of split points(N)'
  213.                       '\n\t*7 - Find closest sum that more than M', font=('Arial', 16, 'normal'))
  214.     turtle.done()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement