Всё так, автоматическое чтение кода тоже пробовали (из внутренностей Psalm довольно удобно строится граф вызовов, с этой помощью мы находим затронутые пулл-реквестом эндпоинты/очереди), но получается на выходе довольно много мусора, так как количество потенциальных путей существенно превышает количество реальных.
Можно было бы попробовать прогонять какой-то автоматический анализ кода, опирающийся на намайненные данные: не что вообще может вызываться, а что вызывается при таком вот пути исполнения кода, этакий гибридный подход
Дядюшка Боб писал, что фреймворк — это деталь (которую должно быть легко заменить), поэтому я с подозрением отношусь ко всем шаблонам вида «чистая архитектура для...». Кстати, с этой точки зрения и «проверка доступности» — такая же деталь, которая, наверное, имеет значение только для балансировки трафика. Ведь если приложение действительно недоступно, то об этом пользователи узнают при любом запросе.
Но в связи с первым хочу задать вопрос: насколько эта структура поменяется, например, при смене фреймворка с Laravel на Symfony? Придётся ли переписывать что-то, кроме «клея» между бизнес-логикой и фреймворком? И, наверное, самый важный вопрос: как такая структура защищает от «прикипания» к конкретному фреймворку?
Спасибо! Вы написали статью, которую я давно хотел написать! На прошлой работе по заветам Голдратта организовал ретроспективы и удивительным образом проблемы начали решаться так, как никогда не решались до того. Правда, оригинальная нотация Голдратта не очень подходит для Миро (рисовал там), поэтому её слегка модифицировали.
Ещё из интересного: в решении конфликтов хорошо помогает ТРИЗ, ядро которой — снятие противоречие вместо нахождения компромиссов, а в поиске причинно-следственных связей — феноменологическое всматривание, то есть вместо Голдраттовского «да ну?» (Really?) задавать вопрос «а как я понимаю, что из А следует Б?» с рефлексией собственного восприятия
JQ — прекрасный инструмент, его можно эффективно использовать и в связке с R (пакет jqr). Для интерактивного анализа я нахожу R более удобным, в том числе благодаря гибкому и унифицированному синтаксису tidyverse.
DuckDB тоже отлично работает, я как-то загрузил туда 500 млн строк CSV и был приятно удивлён производительностью. А благодаря dbplyr работа с данными в DuckDB вообще ничем не отличается от работы с данными в памяти R.
Что касается интерактивной визуализации, то есть Shiny для построения дашбордов, r2d3 для удобной работы с d3 и другие инструменты, но я скорее про них просто слышал.
В общем, для меня R и RStudio — это удобный «хаб», через который удобно пользоваться самым разным инструментарием.
Если выразить мысль максимально кратко — питон не поддерживает метапрограммирование и ленивые вычисления. R умеет и то и другое, и эти возможности активно используются как в tidyverse, так и во всей экосистеме в целом.
Например, одно и то же выражение dplyr с фильтрацией, агрегацией, мутацией и т. п. превращается в SQL-запрос простым изменением датафрейма на объект dbplyr , или с помощью любых других бекендов к dplyr.
Благодаря метапрограммированию возможен data masking и non-standard evaluation, то есть внутри глаголов мы можем обращаться к столбцам дата-фрейма как к переменным, и делать с ними всё, что угодно. Pandas с его query пытается приблизиться к этому удобству, но в силу самих особенностей питона это невозможно — он не ленив, и сразу пытается вычислить аргументы функции.
В ggplot2 тот же подход с использованием метапрограммирования делает код значительно компактнее, проще для написания и переиспользуемым. Просто оставлю здесь примеры.
Python для меня гораздо менее удобен для ad hoc аналитики такого рода — как минимум, потому что код на R с tidyverse получается короче и удобнее для написания.
Что касается чтения данных не только из файликов — всё отлично работает и с БД (в том числе и с dbplyr), с запросами через REST API, да и с прочими источниками проблем нет.
Если логика для всех трёх случаев имеет мало общего (а, скорее всего, оно так и есть), то можно объявить трейт AsLabelList с единственной функцией has_label реализовать его для всех нужных типов. Тогда можно указать для «единой» функции требование трейта и пробрасывать вызов дальше. Это отлично оптимизируется, а ещё позволяет пользователю реализовывать трейт для своих типов, которые тоже можно будет передать в нашу функцию
Было бы по-настоящему здорово не перереализовывать уже имеющийся как минимум в Windows и macOS функционал (десять лет назад у меня винда прекрасно меняла обои автоматом — там были разные раскрашенные фрагменты множества Мандельброта), а написать, допустим, кроссплатформенную утилиту, которая эти системные настройки выставляет унифицированно, например. Закинул список URL, а он тебе все их скачал и поставил в ротацию средствами системы. И обновляет ещё периодически, когда новые картины появляются.
Ну и отдельное количество недоумение — Electron. Тащить целый браузер ради того, чтобы просто продублировать системный функционал...
Но хорошо, что удалось поупражняться в реализации своих идей, этого не отнять.
Про R я в принципе знаю достаточно давно, но именно на tidyverse меня навела ChatGPT, так что какие-то базовые вещи я освоил меньше, чем за день. Правда, она довольно быстро перестала помогать и начала мешать, поэтому дальше я, собственно, читал статьи на сайте tidyverse.
Вот, кстати, добрался до компьютера и могу привести те самые две строчки (и масса «обвеса») для ваших данных:
# подключаем библиотеки
library(tidyverse)
library(jsonlite)
# читаем данные
d <- read_json('file.json')
# или можно распарсить JSON прямо из буфера обмена, пользуюсь этим
d <- parse_json(clipboard())
# а теперь, собственно, превращаем history в таблицу
hist <- d$data$accountBalanceHistory$history %>% enframe %>% unnest_wider(value)
# преобразуем даты и рисуем график
# технически это одна строка, просто разбитая :)
hist %>%
mutate(across(balanceChangeDate, parse_datetime)) %>%
ggplot(aes(x=balanceChangeDate)) + geom_histogram()
Из неочевидных плюшек NSE, о котором упоминал в комментарии ниже, например, возможно такое:
hist %>%
# разбираем как дату все столбцы, оканчивающиеся на Date
mutate(across(ends_with("Date"), parse_datetime)) -> hist
# да, присваивание можно делать не только влево, но и вправо
Из-за того, что называется NSE — non-standart evaluation. R ленив, и вычисляет значения аргументов только при необходимости. Более того, их можно превратить обратно в языковые конструкции и проинтерпретировать иначе. В итоге каждая функция может иметь свой мини-синтаксис для аргументов. Потенциально это может, конечно, вести к хаосу, но на деле это делает синтаксис яснее и понятнее, например:
df %>% select(starts_with("c"))
оставит только те столбцы, имена которых начинаются с c , позволяя не перечислять их имена.
С тех пор, как я освоил rectangling (https://tidyr.tidyverse.org/articles/rectangle.html) при помощи tidyr, анализ JSON'ов любой сложности перестал представлять какие-либо проблемы.
В приведённом примере с датами операций их можно извлечь примерно одной строкой, а второй строкой преобразовать строки в настоящие даты и построить в соседнем окошке график
Причём автор даже не удосужился указать, в какой записи они «слушают» оную музыку. Зато много красивых слов с не вполне определённым смыслом.
Всё так, автоматическое чтение кода тоже пробовали (из внутренностей Psalm довольно удобно строится граф вызовов, с этой помощью мы находим затронутые пулл-реквестом эндпоинты/очереди), но получается на выходе довольно много мусора, так как количество потенциальных путей существенно превышает количество реальных.
Можно было бы попробовать прогонять какой-то автоматический анализ кода, опирающийся на намайненные данные: не что вообще может вызываться, а что вызывается при таком вот пути исполнения кода, этакий гибридный подход
Так целая глава называется
Оглавление «Чистой архитектуры»
Дядюшка Боб писал, что фреймворк — это деталь (которую должно быть легко заменить), поэтому я с подозрением отношусь ко всем шаблонам вида «чистая архитектура для...». Кстати, с этой точки зрения и «проверка доступности» — такая же деталь, которая, наверное, имеет значение только для балансировки трафика. Ведь если приложение действительно недоступно, то об этом пользователи узнают при любом запросе.
Но в связи с первым хочу задать вопрос: насколько эта структура поменяется, например, при смене фреймворка с Laravel на Symfony? Придётся ли переписывать что-то, кроме «клея» между бизнес-логикой и фреймворком? И, наверное, самый важный вопрос: как такая структура защищает от «прикипания» к конкретному фреймворку?
Спасибо! Вы написали статью, которую я давно хотел написать! На прошлой работе по заветам Голдратта организовал ретроспективы и удивительным образом проблемы начали решаться так, как никогда не решались до того. Правда, оригинальная нотация Голдратта не очень подходит для Миро (рисовал там), поэтому её слегка модифицировали.
Ещё из интересного: в решении конфликтов хорошо помогает ТРИЗ, ядро которой — снятие противоречие вместо нахождения компромиссов, а в поиске причинно-следственных связей — феноменологическое всматривание, то есть вместо Голдраттовского «да ну?» (Really?) задавать вопрос «а как я понимаю, что из А следует Б?» с рефлексией собственного восприятия
Меня больше другое занимает: масштаб оси X на этом графике:
Скрытый текст
Извините за рисование с телефона, просто продлил один «масштаб» оси X и другой
Не говоря уже о том, что график зависимости суицида от возраста выглядит совсем иначе:
Источник: https://rannks.ru/upload/iblock/45a/240921 Мартынихин презентация.pdf
(автор своих источников не указывает, разумеется)
JQ — прекрасный инструмент, его можно эффективно использовать и в связке с R (пакет jqr). Для интерактивного анализа я нахожу R более удобным, в том числе благодаря гибкому и унифицированному синтаксису tidyverse.
DuckDB тоже отлично работает, я как-то загрузил туда 500 млн строк CSV и был приятно удивлён производительностью. А благодаря dbplyr работа с данными в DuckDB вообще ничем не отличается от работы с данными в памяти R.
Что касается интерактивной визуализации, то есть Shiny для построения дашбордов, r2d3 для удобной работы с d3 и другие инструменты, но я скорее про них просто слышал.
В общем, для меня R и RStudio — это удобный «хаб», через который удобно пользоваться самым разным инструментарием.
Если выразить мысль максимально кратко — питон не поддерживает метапрограммирование и ленивые вычисления. R умеет и то и другое, и эти возможности активно используются как в tidyverse, так и во всей экосистеме в целом.
Например, одно и то же выражение
dplyr
с фильтрацией, агрегацией, мутацией и т. п. превращается в SQL-запрос простым изменением датафрейма на объектdbplyr
, или с помощью любых других бекендов кdplyr
.Благодаря метапрограммированию возможен data masking и non-standard evaluation, то есть внутри глаголов мы можем обращаться к столбцам дата-фрейма как к переменным, и делать с ними всё, что угодно. Pandas с его
query
пытается приблизиться к этому удобству, но в силу самих особенностей питона это невозможно — он не ленив, и сразу пытается вычислить аргументы функции.В ggplot2 тот же подход с использованием метапрограммирования делает код значительно компактнее, проще для написания и переиспользуемым. Просто оставлю здесь примеры.
magrittr
и так использую постоянно (в основном%<>%
), а на остальные посмотрю, спасибо!Python для меня гораздо менее удобен для ad hoc аналитики такого рода — как минимум, потому что код на R с tidyverse получается короче и удобнее для написания.
Что касается чтения данных не только из файликов — всё отлично работает и с БД (в том числе и с dbplyr), с запросами через REST API, да и с прочими источниками проблем нет.
А какие уникальные возможности R Вы имели в виду?
Если логика для всех трёх случаев имеет мало общего (а, скорее всего, оно так и есть), то можно объявить трейт
AsLabelList
с единственной функциейhas_label
реализовать его для всех нужных типов. Тогда можно указать для «единой» функции требование трейта и пробрасывать вызов дальше. Это отлично оптимизируется, а ещё позволяет пользователю реализовывать трейт для своих типов, которые тоже можно будет передать в нашу функциюДарю вам прекрасный термин «конкорд», которым, в частности, обозначаются те же квинтоктавы по отношению к старинной музыке.
А вот что действительно жаль, так то, что тоны означенных созвучий выбираются случайно
Было бы по-настоящему здорово не перереализовывать уже имеющийся как минимум в Windows и macOS функционал (десять лет назад у меня винда прекрасно меняла обои автоматом — там были разные раскрашенные фрагменты множества Мандельброта), а написать, допустим, кроссплатформенную утилиту, которая эти системные настройки выставляет унифицированно, например. Закинул список URL, а он тебе все их скачал и поставил в ротацию средствами системы. И обновляет ещё периодически, когда новые картины появляются.
Ну и отдельное количество недоумение — Electron. Тащить целый браузер ради того, чтобы просто продублировать системный функционал...
Но хорошо, что удалось поупражняться в реализации своих идей, этого не отнять.
Про R я в принципе знаю достаточно давно, но именно на tidyverse меня навела ChatGPT, так что какие-то базовые вещи я освоил меньше, чем за день. Правда, она довольно быстро перестала помогать и начала мешать, поэтому дальше я, собственно, читал статьи на сайте tidyverse.
Вот, кстати, добрался до компьютера и могу привести те самые две строчки (и масса «обвеса») для ваших данных:
Из неочевидных плюшек NSE, о котором упоминал в комментарии ниже, например, возможно такое:
Можно пощупать прямо в бразуере
Из-за того, что называется NSE — non-standart evaluation. R ленив, и вычисляет значения аргументов только при необходимости. Более того, их можно превратить обратно в языковые конструкции и проинтерпретировать иначе. В итоге каждая функция может иметь свой мини-синтаксис для аргументов. Потенциально это может, конечно, вести к хаосу, но на деле это делает синтаксис яснее и понятнее, например:
оставит только те столбцы, имена которых начинаются с
c
, позволяя не перечислять их имена.Ну и pipe-оператор, действующий так:
Из-за этого код получается короче и яснее
С тех пор, как я освоил rectangling (https://tidyr.tidyverse.org/articles/rectangle.html) при помощи tidyr, анализ JSON'ов любой сложности перестал представлять какие-либо проблемы.
В приведённом примере с датами операций их можно извлечь примерно одной строкой, а второй строкой преобразовать строки в настоящие даты и построить в соседнем окошке график
В 1.21 выводит, как у автора, а в 1.22 — как по «здравому смыслу»: поправили. Про это писали недавно
Не «о чём», а «зачем». Ответ есть в конце статьи
Современная нотация фиксирует существенно больше, чем 88 вариантов высот, распределённых во времени...
Тот случай, когда комментарии полезнее статьи. По-моему, эта история может стать отличной статьёй