Как увидеть производную

от автора

АПД судя по комментариям, эта статья нуждается в некоторой мотивировке. Что именно и зачем мы делаем. Коротко говоря, производную все, кто её как-то запоминает (а запоминают немногие) помнят в дальнейшем как «другой график». Это «ещё одна функция», которая описывает исходную. Мы никогда почти не интересуемся производной поточечно. А между тем производная изначально — не столько отдельная функция, сколько характеристика исходного графика в разных точках. Именно эту привязку мы и проявим в статье. КОНЕЦ АПД

ВТОРОЙ АПД о касательной как пределе секущих и другой возможной питонизации темы см. в длинном комментарии под статьёй вот тут: https://habr.com/ru/post/599051/#comment_23894499 . КОНЕЦ ВТОРОГО АПД

Начнём с повторения математических терминов и нескольких опций питона. В питоне мы будем использовать черепашку, а также модуль математических функций math. От черепашки понадобятся:

  • shape(), color(), speed(), radians() — функции общей настройки

  • xcor(), ycor() — функции, сообщающие положение

  • goto() — для перемещения черепашки в точку

  • setheading() — для изменения направления головы черепашки

  • done() — функция замораживания экрана (нужна при работе в трезвом редакторе вроде VSCode. Если вы пишете в IDLE, она не нужна)

Кроме того, заметим, что поле у черепашки в пикселях. Если она побежит по параболе — убежит моментально за край листка. Так что введём какую-нибудь единицу UNIT = 100 пикселей, например, ну и вот это вот всё отнормируем в наших юнитах.

Из модуля math возьмём функцию atan() — арктангенс. Она возвращает радианную меру угла, не градусы. Дальше мы либо там же берём число pi — константу модуля math, тихо на неё делим, умножив потом на 180, либо мы повторяем, что значит «радианная мера угла», вернее — проходим её. Ваши ученики, скорее всего, про радианы не слышали.

А «производная» в данном случае — «тангенс угла наклона касательной», вот, что нам требуется. Очень похоже на канцелярит, «нанизывание родительных падежей» — «зам. главы отдела контроля качества цеха упаковки (и др.)». Будем эту конструкцию разбирать с конца:

  • есть у нас график функции y = f(x)

  • есть на нём точка, (a, f(a))

  • если туда пришла черепаха, если она (черепаха) бежит по графику, ей в этой точке надо смотреть… по касательной к графику, так что нам требуется уравнение этой касательной. Если последнее записать как y = kx+b, то это k как раз и есть производная: k = f'(a)

  • функция перенаправления головы черепашки умеет в углы, не в прямые. Чтобы сказать «посмотри в направлении этой прямой» мы должны передать не прямую, а «угол между прямой, по которой надо смотреть, и лучом Ox». И если k в пункте выше — тангенс того угла, тут нам понадобится арктангенс k: atan(f'(a))

Получим что-то такое вот для параболы:

from turtle import Turtle, done from math import atan  UNIT = 100  alice = Turtle() alice.color('green') alice.shape('turtle') alice.speed(1) alice.radians()  for step in range(2 * UNIT):     x = alice.xcor() + 1     y = x**2 / UNIT     alice.goto(int(x), int(y))     k = 2*x / UNIT     alpha = atan(k)     alice.setheading(alpha)  done()

Что-то подобное я уже делала с несколькими +/- старшеклассниками. В целом неплохо: это можно прочесть, и код работает (проверьте сами). В чём тут проблемы:

  • не вполне ясно, где мы тут делим на юнит, как выбраны эти места

  • что нам придётся делать с юнитами, когда мы заменим график

  • можно ли всю картинку сдвинуть из точки (0, 0)?

  • как пересадить это в браузер с джаваскриптом и стилями?

В браузере мы можем создать картинку с помощью трёх div-ов: внешний со срезанными углами и глазками (это два вложенных div). Глазки куда-нибудь смещены, надо их перенаправить по курсу. Перемещать можно с помощью javascript:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta http-equiv="X-UA-Compatible" content="IE=edge">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <style>         body {             background: gray;         }         .beast {             position: absolute;             background: green;             width: 20px;             height: 20px;             border-radius: 50%;         }         .eye {             background: white;             width: 5px;             height: 5px;             border-radius: 2px;             transform: translateY(5px);         }     </style> </head> <body>     <div class="beast">         <div class="eye"></div>         <div class="eye"></div>     </div>      <script>         const UNIT = 100                  const beast = document.getElementsByClassName('beast')[0]         let x = 0         let y = 0         let k = 0         let alpha = 0          let id = setInterval(             function() {                 x++                 y = x * x / UNIT                 beast.style.left = x + 'px'                 beast.style.top = y + 'px'                 k = 2 * x / UNIT                 alpha = Math.atan(k) * 180 / Math.PI + 180                 beast.style.transform = 'rotate(' + alpha + 'deg)'                 if (x > 2 * UNIT) clearInterval(id)             }, 50         )     </script> </body> </html>

С этого места код хочется разделить на файлы. Собственно, и питоновский код тоже хочется, и мы делили его: файл с основной логикой + файл отрисовка + файл калькулятор. В браузере, соответственно, плюс ещё два файла: разметка и стили.

Бонусом станет возможность на этом же материале пройти наследование. Или даже уже интерфейсы. Вы пишете интерфейс для воплощения функции и производной. Функционал отрисовки юзает интерфейс. А ваши классы с разными калькуляторами обсчитывают разные функции.

Пример с наследованием, примерно в таком вот виде пройденный с восьмиклассником в начале учебного года (парень — сын программиста, и увлекается программированием давно). У нас есть главный файл с основной логикой, рисовалка и папка с разными калькуляторами: базовым и наследующими под разные функции.

main.py

from painter import Painter from calculators.calculatorSquare import CalculatorSquare  painter = Painter() calculator = CalculatorSquare()  for x in range(200):     calculator.nextStep()     y = calculator.getY()     alpha = calculator.getAngleInRadians()     painter.showState(x, y, alpha)  painter.freeze()

painter.py

class Painter:      def __init__(self):         from turtle import Turtle, Screen         self.__beast = Turtle()         self.__beast.shape('turtle')         self.__beast.speed(10)         self.__beast.radians()      def showState(self, x, y, alpha):         self.__beast.goto(x,y)         self.__beast.setheading(alpha)      def freeze(self):         from turtle import done         done()

и папка calculators с файлами calculator.py

from math import atan  class Calculator:      def __init__(self):         self._UNIT = 100         self._x = 0         self._y = 0         self._alpha = 0      def nextStep(self):         self._x += 1      def getY(self) -> float:         pass      def getDerivative(self) -> float:         pass      def getAngleInRadians(self) -> float:         return atan(self.getDerivative()) 

и calculatorSquare.py

from .calculator import Calculator  class CalculatorSquare(Calculator):      def getY(self):         return self._x ** 2 / self._UNIT        def getDerivative(self):         return self._x * 2 / self._UNIT


ссылка на оригинал статьи https://habr.com/ru/post/599051/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *