Python и все-все-все.
Сначала о том как я к этому пришел. Я делаю инструментарий для облеченного создания бизнес-приложений. Его суть такая: допустим у нас есть задача сделать какой то АРМ или мобильное рабочее место для учета или управления в экосистеме 1С/SAP или другой учетной системы(или не учетной), так как я разрабатываю под Android SDK то я могу сделать это нативными средствами, и так как я все-таки 1Сник я могу это сделать на 1С:Мобильной платформе или 1С:Мобильном клиенте, но вариант 1С кажется мне спорным так как при сопоставимых трудозатратах на 1С нельзя сделать то что можно сделать в нативной разработке – ни по функционалу, ни по быстродействию/надежности, да еще вроде бы 1С в отличии от других средств разработки не бесплатная (но это не точно). Ну ок, допустим я выбрал какое то средство для разработки, но тут вот какой момент – при всем своем разнообразии задачи учета состоят из неких стандартных повторяющихся логических блоков, и из этих кубиков хотелось бы собирать решение, чтобы была визуальная структура, чтобы можно было видоизменять под изменяющиеся процессы бизнеса не запутываясь в коде. Для этого есть третий подход – конструктор. Я сравниваю это с замечательной штукой «1С: Конвертация данных». Можно делать конвертацию без нее. Просто взять и написать обработчики каждый раз с нуля. А можно с ней и решение получится структурированным и готовым к изменениям/масштабированию. Смысл конструктора примерно в этом . Вроде бы Simple UI - нужная штука. Но к сожалению у меня была одна проблема – удобный интерпретатор кода (да обработчики все равно надо писать – от этого никуда не деться). Когда клиент работает в онлайн-режиме код выполняется на стороне учетной системы, а вот когда в самостоятельном режиме – тут я сделал свой «метаязык» + стандартный SQL для работы с СУБД приложения. И хотя там были и интерпретаторы выражений, условные переходы и т.д. я все равно с завистью смотрел на ту же 1С где можно сделать все. Даже если «все» не нужно на конкретном проекте, всегда хочется иметь запас под рукой, чтобы быть уверенным. В общем решение нашлось – интерпретатор Python. Благодаря головастым ребятам из Англии его теперь можно привинтить в нативные Java/Kotlin gradle проекты. Это прям серебряная пуля для меня – настолько хорошо это ложиться на архитектуру Simple UI.
Сами посудите:
- Python – один из самых простых для изучения языков.
- При этом это настоящий мощный язык с классами и другим конструкциями «взрослых» языков
- Python лучший язык для обработки данных, недаром он mast have для data science.
- При этом это лучший язык для скриптов (его многие и воспринимают как язык скриптов хотя это давно не так) а мне как раз и нужны скрипты и по больше части обработка данных, но и по возможности чтобы это было просто и лаконично.
- Это весьма распространённый в мире язык с множеством мощных библиотек и огромным комьюнити (что также важно для меня так как на Simple UI разрабатывают не только в СНГ)
Получается из всех языков для обработки бизнес-логики Python наверное самый подходящий. Вот это удача!
Просто приведу пару примеров чтобы показать удобство и лаконичность Python :
1. Отправляем запрос и сразу получаем объект ответа сразу в виде объекта json
r = requests.get('https://www.cbr-xml-daily.ru/daily_json.js')
rjson = r.json
2. Читаем нужные колонки в файле Excel на выходе готовый объект
import pandas
excel_data_df = pandas.read_excel('records.xlsx', sheet_name='Cars', usecols=['Car Name', 'Car Price'])
Как соединяется Python c Simple UI?
- Через «Переменные» - общий стек переменных обычных и глобальных, отображаемых и нет через который передаются также и команды
- Через прямой доступ к SQL приложения из скрипта
Пример скрипта «Калькулятор». hashMap - это и есть "Переменные" Simple UI, put/get - поместить/вставить. Это все что нужно знать о соединении скриптов с конструктором
def get_action(unit):
if unit == 'btn_c':
return 'C'
if unit == 'btn_q1':
return '('
if unit == 'btn_q2':
return ')'
if unit == 'btn_div':
return '/'
if unit == 'btn_7':
return '7'
if unit == 'btn_8':
return '8'
if unit == 'btn_9':
return '9'
if unit == 'btn_1':
return '1'
if unit == 'btn_2':
return '2'
if unit == 'btn_3':
return '3'
if unit == 'btn_4':
return '4'
if unit == 'btn_5':
return '5'
if unit == 'btn_6':
return '6'
if unit == 'btn_mul':
return '*'
if unit == 'btn_minus':
return '-'
if unit == 'btn_plus':
return '+'
if unit == 'btn_sign':
return '-'
if unit == 'btn_0':
return '0'
if unit == 'btn_res':
return '='
if unit == 'btn_dot':
return '.'
raise ValueError('Undefined unit: {}'.format(unit))
res = hashMap.get("res")
action = get_action( hashMap.get("listener"))
if action=="=":
res=eval(res)
elif action=="C":
res=0
else:
if res=="0":
res=action
else:
res+=action
hashMap.put("res",str(res))
И результат в Simple UI:
Пример работы с СУБД приложения прямым запросом к SQL
import sqlite3
from sqlite3.dbapi2 import Error
import json
conn = sqlite3.connect('SimpleWMS')
cursor = conn.cursor()
cursor.execute("SELECT nom FROM goods LIMIT 30")
json_res = {
"type": "table",
"textsize": "25",
"hidecaption": "true",
"hideinterline": "false",
"columns": [
{
"name": "title",
"header": "Задача",
"weight": "2"
}
]
}
results = cursor.fetchall()
lst = []
for link in results:
d = {}
d['title']=str(link[0])
lst.append(d)
json_res['rows']=lst
conn.close()
hashMap.put("table",json.dumps(json_res,ensure_ascii=False))
И результат в Simple UI:
А вот пример поиска товаров по штрихкоду в Google – с экрана сканируется штрихкод, из выдачи Google с помощью beautiful soup выдергиваются заголовки:
А вот видео о том, как все это выглядит в Simple UI:
Локальное хранилище конфигураций/стартер конфигураций
Конфигурация в Simple UI – это обычная xml строка. Ее можно получить на устройство разными способами:
- Она скачивается через веб сервис учетной системы при прямом подключении
- Распространить через собственный магазин приложений (рекомендуется для самостоятельных конфигураций)
- Ее можно послать в виде файла (и программа ее откроет) вместе с настройками
- Можно передать через QR код вместе с настройками
- Через встроенный веб-сервис
Но так как даже с одной конфигурацией могут быть разные настройки подключения, либо нужно сохранить на устройстве несколько конфигураций локально и потом между ними переключаться – нужен стартер. Стартер «перезапускает» приложение с нужными настройками и конфигурацией.
Попутно он решает еще задачи:
- Выводится дополнительная информация о конфигурации – теги и описание
- Можно проверить подключение
Новые возможности логина
Теперь можно управлять подключением к сервису – настройками подключения для онлайн-режима и postgrest из своих экранов. При этом конфигурация с настройками также перезагружается и настройки записываются в основные настройки (либо НЕ записываются в зависимости от команды). Также добавлено поле ввода пароля.