Добрый день,
Написан модуль Питон. Прилагается.
Необходимо в Calc кнопки для вывода результатов типа -
df.info()
Первые записи
df.head()
Последние записи
df.tail()
Вывод с форматированием
df.style.background_gradient(cmap='Blues', axis=0).format("{:.3f}")
plt.show()
Пока не понимаю как это сделать.
Сам Питон и редактор Visual Calc установлены.
Установлено расширение APSO 1.4.4
Создание модуля получается через встроившуюся нову строку в меню Сервис - Макросы - Organize Python Script.
Там этот модуль создал и редактировал через Edit - Module create и далее Module - Edit.
При создании на рабочем столе кнопки при подвязывании ро действию на нее макроса модуля с макросами Питон не видно.
Также не обратиться и к функциям Питон в модуле через =Формула, тк Calc не понимает этих функций.
Как присвоить выполнение функций модуля Питона к листу Calc через =Формула или кнопок ?
Спасибо.
Цитата: juceser от 31 марта 2025, 11:41редактор Visual Calc
Что такое "редактор Visual Calc"?
Прошу извинить, программа называется Visual Studio Code.
Не имеет отношения к MS Visual Studio.
В Вашем архиве два файла: Работа5.ods и Module1.py. Файл .py содержит код. Но этот файл не имеет отношения к LibreOffice, потому что макросы документа содержатся только внутри самого документа, а не лежат рядом. Ну и да, внутри Работа5.ods есть свой Module1.py в Scripts/python, но он практически пустой.
Если Вы будете работать с внутренним файлом .py, то Вы получите возможность привязывать соответствующие функции к событиям (в т.ч. кнопок). Но использовать этот код как функции таблиц напрямую нельзя. Либо Вы сделаете функции Basic, которые можно использовать как функции таблиц (и из них будете вызывать код Python), либо Вы оформите Ваш код как расширение. См. например https://ask.libreoffice.org/t/user-defined-function-in-calc-using-python/105612 и https://ask.libreoffice.org/t/unable-to-run-the-simpliest-python-macro-for-calc-udf/95916
Я заметил что внутренний модуль пустой и уже скопировал туда код.
Я видел ссылки где показано что можно создать на листе кнопку и навесить на нее функцию из модуля Питона.
Но у меня это не работает, поскольку в перечне макросов нет модуля Питона по выбору ...
Цитата: juceser от 31 марта 2025, 12:46Я заметил что внутренний модуль пустой и уже скопировал туда код.
...
Но у меня это не работает, поскольку в перечне макросов нет модуля Питона по выбору
В том файле, который приложен в начальном посте, ситуация до Ваших исправлений. Нет файла с исправлениями - нет возможности посмотреть и посоветовать.
Прикладываю.
Работа5_.ods
Цитата: juceser от 31 марта 2025, 11:41Установлено расширение APSO 1.4.4
И Вы, конечно, использовали его для управления скриптами документа?
Добавляю скриншоты чтобы пояснить как встроен APSO, как открываю модуль Питона. Добавляю скрин на примере кнопки что модуль Питона не виден для присвоения кнопке.
Добавляю файл с полностью внесенным кодом.
Добавляю пошаговую инструкцию что надо сделать в рамках работы.
Все скриншоты не вошли.
Когда у Вас в APSO выделен Module1, попробуйте двойной щелчок по нему.
Сколько не щелкай, ничего не появляется по Module1, а если выбирать Standard - Module1, то видны функции VBA.
А Вы можете в файле по кнопке привязать например -
with plt.style.context('ggplot'):
plt.figure(figsize=(8, 4))
plt.suptitle('Сглаженный график двух функций')
plt.plot(X_, Y_, label=r'$y(x)$')
plt.plot(X_, Z_, label=r'$z(x)$')
plt.xlabel(r'$x$', fontsize=12)
plt.ylabel(r'$f(x)$', fontsize=12)
plt.legend(loc='best', fontsize=10);
plt.show()
?
Интересно было бы посмотреть как это вообще привязывается, это же не процедура, не функция, а набор кода.
Цитата: juceser от 31 марта 2025, 15:31Сколько не щелкай, ничего не появляется по Module1
Неправда, появляется сообщение об ошибке индентации - потому что Ваш код неправильно отформатирован (в Python индентация важна синтаксически).
Появляется где? Я сказал что не появляется при присвоении кнопке.
А в редактировании появляется конечно.
Я и не говорил что не появляется.
Как код то к кнопке подвязать?
Я уже отформатировал эту ошибку, здесь важно чтобы с 1 позиции код шел почему-то.
Вот есть код в модуле Питона который график строит -
with plt.style.context('ggplot'):
plt.figure(figsize=(8, 4))
plt.suptitle('Сглаженный график двух функций')
plt.plot(X_, Y_, label=r'$y(x)$')
plt.plot(X_, Z_, label=r'$z(x)$')
plt.xlabel(r'$x$', fontsize=12)
plt.ylabel(r'$f(x)$', fontsize=12)
plt.legend(loc='best', fontsize=10);
plt.show()
Как его на кнопку приткнуть?
Может я до этого не ясно как-то объяснял, извиняюсь тогда.
Вы не только объясняете неясно (хотя понять в принципе можно). Самое главное - Вы не делаете Вашу часть работы.
Вы прикрепляете файлы с неправильным кодом. Код неправильный - его нельзя "на кнопку приткнуть". Вы пишете "Я уже отформатировал эту ошибку" - и опять не прикладываете исправленный файл. Ну так нет файла с правильным кодом, но где не получается назначить его на событие - нет и помощи.
Цитата: juceser от 31 марта 2025, 15:42Я уже отформатировал эту ошибку
Но мы видим, по-прежнему, старый вариант.
Цитата: juceser от 31 марта 2025, 15:31Интересно было бы посмотреть как это вообще привязывается, это же не процедура, не функция, а набор кода.
По нажатию кнопки будет вызываться процедура (подпрограмма, функция). Измените свой текст удобным для себя образом.
Посмотрите, пожалуйста. Сейчас при редактировании ошибок найдено не было.
При выборе кнопки можно теперь увидеть некоторые функции модуля Питон.
Получается что пока в коде где-то были ошибки он вообще ничего не показывал при назначении кнопки.
Об этом мне не было известно. VBA не так себя ведет.
По-прежнему пока неясно как работать с выводом команд, похожих на работу в интепретаторе -
Работа с DataFrame
Информация
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 19 entries, 0 to 18
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 x 19 non-null float64
1 y 19 non-null float64
2 g 19 non-null float64
3 z 19 non-null float64
dtypes: float64(4)
memory usage: 760.0 bytes
Первые записи
df.head()
x y g z
0 -1.7 4.677369 1.378405 1.308333
1 -1.5 4.234381 1.303840 1.252763
2 -1.3 3.855986 1.224745 1.193922
3 -1.1 3.614309 1.140175 1.131402
4 -0.9 3.601079 1.048809 0.453596
Последние записи
df.tail()
x y g z
14 1.1 1.301703 2.017349 1.115142
15 1.3 1.068996 2.131938 1.266948
16 1.5 0.945114 2.240702 1.398717
17 1.7 0.852905 2.344684 1.515127
18 1.9 0.747829 2.444650 1.619388
Вывод с форматированием
df.style.background_gradient(cmap='Blues', axis=0).format("{:.3f}")
x y g z
0 -1.700 4.677 1.378 1.308
1 -1.500 4.234 1.304 1.253
2 -1.300 3.856 1.225 1.194
3 -1.100 3.614 1.140 1.131
4 -0.900 3.601 1.049 0.454
5 -0.700 3.889 0.949 0.267
6 -0.500 4.460 0.837 0.071
7 -0.300 5.123 0.707 -0.129
8 -0.100 5.516 0.548 -0.323
9 0.100 5.316 1.262 -0.598
10 0.300 4.521 1.457 0.049
11 0.500 3.450 1.620 0.438
12 0.700 2.460 1.764 0.718
13 0.900 1.740 1.895 0.936
14 1.100 1.302 2.017 1.115
15 1.300 1.069 2.132 1.267
16 1.500 0.945 2.241 1.399
17 1.700 0.853 2.345 1.515
18 1.900 0.748 2.445 1.619
Цитата: juceser от 31 марта 2025, 16:23VBA не так себя ведет.
вы в vba работали с макросами на python?
нет
Куда Питон должен выводить работу данных команд? На лист? В отдельное окно интерпретатора?
В меню имеется еще пункт Python Shell - если его выбрать, то возникает ошибка, не связанная с кодом в модуле работы.
Странно, ранее у меня открывался этот shell, но ничего из команд в модуле все равно не понимал.
Опишу как я понимаю работу с python. Скрипт из документа , выполняется в встроенном в LO python, он ничего не знает о ваших pandas numpy итд. Что бы узнал ищите по форуму тему от economist, об установке дополнительных библиотек.
Я так понимаю, первые команды модуля и импортируют эти библиотеки.
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
Но, получается, это код в модуле никак не исполняется.
Цитата: bigor от 31 марта 2025, 16:52ищите по форуму тему от economist
Установка python-библиотек Pandas и др. в LO7 Calc (Windows) (https://forumooo.ru/index.php?topic=8696.msg70413#msg70413)
ТС выбрал сложную "точку перегиба" для двух миров в виде кнопки с кодом. Кмк лучше так:
1) Ставим обычный python 3.12 с pandas jupyterlab matplotlib. Очень удобен и быстр uv вместо pip.
2) Пишем исследовательский код в браузере с автодополнением, справкой, даже в 4 руки, если надо быстро, с построением графиков в jupyterlab (промышленный стандарт, повторенный всеми, потому что лучше ничего нет).
3) Графики сохраняем в "кристальный" svg или предсказуемый png-формат типа: plt.savefig("график.svg", format="svg", transparent=True, bbox_inches="tight", inches=0)
4) Полученные графики импортируем простым макросом в LibreOffice, примеры есть на нашем Форуме.
Почему так лучше, без шагов 3 и 4? Вы быстро обнаружите что ваш Блокнот Jupyter можно одной строкой кода превратить в 15 других форматов (HTML, PDF итд), в т.ч. с интерактивными графиками, или даже веб-приложение, что будет намного полезнее в деле массового распространения и доступности результатов вашего труда на любых устройствах.
Либра не умеет в интерактивность, ее нужно для этого кодить, а это в разы сложнее, чем Jupyter. Я видел уже десятки примеров выбора именно такого пути и подтверждаю его высочайшую эффективность и интересность.
Даже в прожженных корпорациях, где от сетки Excel выгорел экран, аналитики с радостью переходят на pandas/jupyter, в новый дивный мир гибридов кода, документации и визуализаций web-формата блокнота (json).
В данном случае освоение нового инструмента не распыление сил, а избегание острых углов экосистемы LibreOffice, где Python пока что на задворках (но ситуация плавно меняется, и вы к ней подготовитесь сами, если начнете сейчас). Ускорение освоения и реализации проектов (Python : LO BASIC) могу оценить как 4:1, ровно во столько раз проще всё отчетно-графиковое-дэшбордовое дается в JupyterLab.
Прогоняю сейчас этот же код в консоли APSO. Ну что сказать, это куда утомительней, чем даже в cmd после запуска Python, там мне удавалось копировать целые блоки и интерпретатор это понимал, здесь нет.
Но операторы проходят, например import pandas прошел без проблем, нет ошибки, значит видит библиотеки.
Столкнулся, например, с тем что код присвоения нескольким переменным значений, прошедший без проблем в интерпретаторе Питона, в APSO вызвал непонимание -
>>>x0, xk, dx = -2.0, 2.0, 0.1
File "<console>", line 1
0, xk, dx = -2.0, 2.0, 0.1
^^^^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
>>> 0, xk, dx := -2.0, 2.0, 0.1
File "<console>", line 1
0, xk, dx := -2.0, 2.0, 0.1
^^
SyntaxError: invalid syntax
>>> x0, xk, dx := -2.0, 2.0, 0.1
File "<console>", line 1
x0, xk, dx := -2.0, 2.0, 0.1
^^
SyntaxError: invalid syntax
>>> x0 = -2.0
>>> xk = 2.0
>>> dx = 0.1
По одному он значения присвоил.
Получается APSO это не окно обращения к тому же самому Питону, что мы запускали в командной строке, а свой собственный интерпретатор со своим собственным и отличающимся от основного синтаксиса языком, что совсем печально и вынуждает править код под свою версию языка даже на таких элементарных вещах.
Уже следующая команда ставит в тупик -
>>> df = pd.DataFrame(columns=['x', 'y', 'g', 'z'])
>>> for i in range(n):
... x = x0 + i*dx
... df.loc[len(df.index)] = [x, y(x), g(x), z(x)]
...
Traceback (most recent call last):
File "<console>", line 3, in <module>
File "<console>", line 2, in z
TypeError: 'module' object is not callable
>>> for i in range(n):
... x = x0 + i*dx
... df.loc[len(df.index)] = [x, y(x), g(x), z(x)]
...
Traceback (most recent call last):
File "<console>", line 3, in <module>
File "<console>", line 2, in z
TypeError: 'module' object is not callable
>>>
При том что было ранее задано import pandas as pd без проблем, те обращение к модулю законно.
В консоли Питона проблем не было.
С предыдущей ошибкой разобрался, там ошибка была в написании функции z, пропущен sin и вместо math.sin(x) было math(x). При этом синтаксический контроль был пройден.
Сейчас завис на поверхности -
def xyz(x, y):
return ((3*math.exp(-2*y))*(x**2)) - ((2*math.cos(x))*(math.sin(y))*(y**2))
x0, xk, dx = -1, 1, 0.1
y0, yk, dy = -1.2, 1.2, 0.1
nx = round((xk-x0)/dx) + 1
ny = round((yk-y0)/dy) + 1
u, v = np.mgrid[x0:xk:nx*1j, y0:yk:ny*1j]
z3 = xyz(u, v)
fig = plt.figure()
plt.suptitle('Поверхность')
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(u, v, z3, cmap='inferno');
plt.show()
Код не проходит, получается что функция слишком сложная что-ли, хотя она считаемая.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[39], line 9
6 ny = round((yk-y0)/dy) + 1
8 u, v = np.mgrid[x0:xk:nx*1j, y0:yk:ny*1j]
----> 9 z3 = xyz(u, v)
10 fig = plt.figure()
11 plt.suptitle('Поверхность')
Cell In[39], line 2, in xyz(x, y)
1 def xyz(x, y):
----> 2 return ((3*math.exp(-2*y))*(x**2))
TypeError: only length-1 arrays can be converted to Python scalars
При этом если функцию упростить до
def xyz(x, y):
return (y*(x**2))
x0, xk, dx = -1, 1, 0.1
y0, yk, dy = -1.2, 1.2, 0.1
nx = round((xk-x0)/dx) + 1
ny = round((yk-y0)/dy) + 1
u, v = np.mgrid[x0:xk:nx*1j, y0:yk:ny*1j]
z3 = xyz(u, v)
fig = plt.figure()
plt.suptitle('Поверхность')
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(u, v, z3, cmap='inferno');
plt.show()
то строит поверхность.
Итак решение полностью найдено - все выполнено на платформе Anaconda через jupyter notebook.
Далее весь код засовываем в консоль и все интерактивно отображается в браузере.
Предыдущая проблема также решена, оказывается здесь нужно обращаться почему-то не к модулю math, как делали в графиках, а к модулю numpy as np -
def xyz(x, y):
return ((3*np.exp(-2*y))*(x**2)) - ((2*np.cos(x))*(np.sin(y))*(y**2))
# Исходные данные
x0, xk, dx = -1, 1, 0.1
y0, yk, dy = -1.2, 1.2, 0.1
nx = round((xk-x0)/dx) + 1
ny = round((yk-y0)/dy) + 1
# Построение графика
u, v = np.mgrid[x0:xk:nx*1j, y0:yk:ny*1j]
z3 = xyz(u, v)
fig = plt.figure()
plt.suptitle('Поверхность')
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(u, v, z3, cmap='inferno');
# Сохранение графика в PNG
plt.savefig("plot_surf.png", format="png") # Также можно сохранить как JPG или SVG, изменив формат
plt.show()
Тогда этот же код спокойно работает.
Да, осталась непонятка с сохранением графика plt.savefig, поскольку функция не терпит в имени указание абсолютного пути, но пусть уж сохраняет (а она сохраняет) в профиле. Хотелось бы большего, сохранить весь вывод скажем в pdf или html, и это вроде тоже как должно работать, но File - Save and export Notebook As выдает в меню все варианты серым. Ладно, будем считать, что это не работает. Задача в целом выполнена без LO.
Сохранение из jupyter за пределы папки запуска (профиля) невозможно. Но можно указать ее C: и тогда везде.
А чтобы работали все экспорты в pdf, html и десяток др форматов из jupyter при запуске ячейки - используйте JupyterLab c расширениями со словом export в названии. Там несколько вариантов, есть зависимости, тема большая. Очень удобно экспортировать весь блокнот в html c инъекциями JavaScript, и он будет работать в браузере (например для обратной связи, голосований, визирования или для показа секретов в iframe. Html лучше чем pdf, потому что это красиво, это почти всегда web-сервер и мгновенная доставка всем кому нужно, включая мобильные.