Автоматические вычисления в Notion

С глобальными переменными, синхронизацией значений между страничками и прочими классными штуками

Эта история началась несколько месяцев назад, когда я начал высчитывать бизнес-план своего стартапа.

Знаете, иногда бывает слишком много вычислений. Иногда вы должны повторно использовать результат вычислений с первой страницы на второй странице, а затем на третьей, и это превращается в ад.

Вероятность ошибки возрастает: можно просто забыть где-то исправить число, и все вычисления слетят.

Так мне пришла в голову идея: а что, если бы это все считалось автоматически, а я бы просто один раз кнопочку жмякал? Ленивая такая мысль, но приятная. И я это сделал!

Для тех, кому не особо интересны технические подробности реализации: в конце есть ссылка на Deepnote с кодом.

Как это работает?

Есть страничка, которая называется "Пересчет":

Сорре, что на английском, я просто перевожу свою статью с медиума

Она состоит из нескольких смысловых блоков:

  • Некоторые глобальные переменные: например, курс доллара
  • Ссылки на страницы, которые нам нужно пересчитать. Внутренние страницы внутри этих страниц (и так далее) также будут пересчитаны, поскольку алгоритм рекурсивен.
  • Таблица с логами на случай ошибок в расчетах

А вот страница с условными обозначениями:

Алгоритм будет перебирать все блоки страниц и искать в них $recalculate. Если он его найдет, он будет пересчитывать математические блоки строго под этим флагом, пока там не появится какой-нибудь нематематический блок.

Давайте возьмем пример того, что мы тут пытаемся вычислить:

Вы можете видеть, что мы будем экранировать переменные с помощью \$ : это потому, что $ — это специальный символ в Latex.

Latex — это такой язык описания всякой математической шняги, который Notion использует в своих математических блоках.

Что мы будем использовать

Давайте посмотрим, что мы здесь используем:

  • SymPy: библиотека для символических вычислений. Поскольку математика в Notion описывается через Latex, то мы оттуда этот Latex вытянем и будем использовать SymPy для вычисления уравнения.
  • Notion-py: неофициальная библиотека для API Notion. Пока что Notion не выкатил официальный API, ждем.
  • Os: просто пакет для взаимодействия с вашей системой
  • RECALCULATION_KEY — это штука, которая вызовет пересчет математического блока
  • ROUNDING — это точность наших вычислений: например, если у нас есть что-то вроде 0.8333882483482384, оно округлит его
  • TOKEN — это штука, которая нужна для подключения к API: чтобы получить его, перейдите на вкладку Application консоли разработчика в Chrome и скопируйте оттуда token_v2
  • BASE_PAGE — это ссылка на ту страницу “Пересчета”, которую мы обсуждали ранее
  • LOG_LINK — это ссылка на базу данных, в которой будет храниться лог выполнения

Инициализация API

  • Мы инициализируем API Notion с помощью токена
  • Затем мы получаем все блоки нашей базовой страницы

Некоторые основные функции

MATH — это все математические символы, которые мы используем.

\\ используется в Notion в наших математических блоках для экранирования переменных.

Следующее, что нужно сделать — это функцию обновления блока.

Представьте себе следующее уравнение: $HAHA = $LOL + $ROFL = 100500

Что мы здесь делаем — это удаляем 100500 отсюда (это результат уже, его нам обновить надо) и затем мы добавляем новый результат.

Предположим, что это 100501: итоговая формула выглядит как
$HAHA = $LOL + $ROFL = 100501

Работа с глобальными переменными

  • Нам нужно хранить всякие штуки типа результата подстановки вот таким образом, чтобы у нас логгирование правильно работало
  • variables будет хранить все глобальные переменные
  • default() сотрет все, кроме переменных

А вот и код для задавания глобальной переменной подъехал.

Мы совершаем такие странные телодвижения с индексами и другими штуками из-за проблем интерпретации Latex в SymPy. Если в уравнении есть что-то вроде HELLO, то SymPy воспринимает это не как цельную переменную, а как H*E*L*L*O: то есть умножение переменных, названных одиночными буквами.

Логгирование

Здесь мы подключаемся к базе данных с логом и очищаем ее.

Затем тут задана функция, которая создает новую строку в таблице и добавляет содержимое.

Сложная часть № 1: обработка страницы

is_recalculating_next — это просто флаг для пересчета следующего блока. Он должен быть True в 2 ситуациях:

  • Если предыдущий блок содержал $recalculate
  • Если предыдущий был математическим блоком, а блок в верхней его части содержал $recalculate

Мы перебираем дочерние элементы страницы, получая ссылку для каждого блока и перебираем дочерние блоки (поскольку этот блок может быть страницей или ссылкой на страницу).

Если детишек у блока нет, то это одинокий блок, и мы можем перейти в следующий.

Сложная часть № 2: обработка блока

  • Мы проверяем, че это вообще за блок такой. Нам нужна математика.
  • Если нет title (title внутри Notion обозначает текст), тогда ничо сделать нельзя
  • А если title есть, тогда мы проверяем флаг для пересчета
  • Если тут есть уравнение а-ля $HGHGHG = без результата и с одной переменной, то мы скипаем его
  • Дальше мы совершаем странные телодвижения, чтобы SymPy нас понял
  • Потом парсим наше уравнение
  • Если в уравнении есть какие-то переменные (то есть уравнение выглядит как $HEHE = $HOHO / $HIHI = ), то мы вычисляем его и затем перезадаем глобальную переменную $HEHE
  • Если нет других глобальных переменных (то есть уравнение выглядит как $HAHA = 3), то мы просто перезадаем этот $HAHA

Коды

Помните, я вам обещал коды? Вот они!

Вы можете просто дублировать код там: получите рабочий калькулятор буквально через 30 секунд.

Кстати, Deepnote — очень полезный инструмент для всяких вот таких штук. Я бы рекомендовал вам полностью заменить им Jupyter, так как у него классный UX по сравнению с другими решениями.

Что за стартап-то, кстати

Мы разрабатываем Facel: устройство и софт для мониторинга параметров здоровья (усталость организма, усталость глаз, стресс, эффективность и уровень концентрации) и управления гаджетами (например, вы моргаете 3 раза и ваша музыка останавливается) на основе сигнала с 2 точек за ушами.

Мы классифицируем 12 мимических жестов (моргание, движение бровей и т. Д.) с точностью 98% и используем эти данные для наших функций.

Мы представили проект на AI Journey 2020, одной из крупнейших мировых конференций по ИИ.

Мы выставляемся на GlobalGradShow, одной из главных программ Dubai Design Week, где представлены 100 самых инновационных проектов выпускников со всего мира, так что это довольно круто.

Ещё выиграли российский этап Alibaba GET Challenge, а также приняли участие в мировом этапе James Dyson Award: одном из главных конкурсов промышленного дизайна в мире.

Минутка самопиара

Вот тут наш телеграм канал, подписывайтесь.

Тоже здесь мой линкедин и мой телеграм, обращайтесь.

А вот мой Medium, где была опубликована английская версия этой статьи.

Еще одно объявление: мы сейчас расширяемся и ищем на работу инженера-схемотехника и айосника. Если вы хотите с нами поработать или знаете кого-нибудь, кто хочет, то пишите :)

0
3 комментария
Angry Beard

global local - это сильно

Ответить
Развернуть ветку
Alex Einarsson
Ответить
Развернуть ветку
Денис Шилов
Автор

бывает

Ответить
Развернуть ветку
0 комментариев
Раскрывать всегда