Макропрограммирование K3 в Python

Материал из K3-Macro

Общие принципы[править | править код]

Команда macro в К3 может запускать два типа файлов – макропрограмму k3 (файл .mac) и макропрограмму на Python (файл .py). Расширение файла показывает системе, какой интерпретатор использовать.

Также в К3 есть возможность вставить блок кода на Python внутрь файла .mac. Для этого необходимо воспользоваться конструкцией

<?python
…
?>

Для всех строчек кода внутри будет использоваться интерпретатор python.

Библиотека, функции и команды. Ключевые слова[править | править код]

Для использования функционала К3 в программу на Python нужно импортировать специальную библиотеку Import k3

Все функции и команды K3 вызываются как функции из этой библиотеки с использованием трёх основных принципов:

  • Имя функции совпадает с именем команды, но обязательно должно быть написано в нижнем регистре;
  • Все аргументы или ключевые слова передаются в функцию в том же порядке, как и при обычном вызове в макропрограмме;
  • В Python нет специального обозначения для возвращения результата работы команды (# в макропрограмме). Поскольку команды – это тоже функции в Python, они возвращают значение обычным образом.

Например, команда рисования линии, возвращающая ссылку на построенный объект

#line1 line 0 0 0 100 0 0 done

В python будет записываться как

line1 = k3.line(0, 0, 0, 100, 0, 0, k3.k_done)

k3.k_done – это объект соответствующий ключевому слову done. Все ключевые слова записываются для использования в Python таким образом: k3.k_<название>, где <название> — название ключевого слова.

Ключевое слово для интерактивного ввода (то, что в макропрограмме записывалось знаком двоеточия ( : ), в Python запишется как k3.k_interact, например:

k3.line(0, 0, 0, k3.k_interact, k3.k_done)

построит линию от точки 0 до точки, введённой пользователем в интерактивном режиме.

Eksklamacia.png Функции К3, запущенные через библиотеку К3 в Python, всегда возвращают числа в формате с плавающей точкой (double). Поэтому часто для дальнейшего использования их нужно перевести в целое, например

k3.getobjnum(k3.sysvar(60))

вернёт ошибку, поскольку функция getobjnum должна получать на вход целое число, а k3.sysvar() вернёт double. Необходимо писать так:

k3.getobjnum(int(k3.sysvar(60)))

Переменные и массивы K3[править | править код]

Все переменные, которые мы объявляем в коде на Python – это обычные переменные Python. Некоторые функции K3 требуют работы именно с переменными или массивами K3, например, функции objident и objgab3

k3.objident(<object>, <variable>)

k3.objgab3(<object>, <array>)

Здесь <variable> - это переменная k3, а <array> — массив К3 и именно такие объекты нужно передавать в функцию.

Переменная К3 в Python — это объект класса k3.Var, создаётся с помощью:

varname = k3.Var(<name>)

Где <name> — строка с именем переменной K3.

У этого объекта есть атрибут varname.value, который содержит значение этой переменной.

В результате, вызов функции objident будет выглядеть таким образом:

varname = k3.Var(‘obj1’)
k3.objident(k3.k_interact, varname)

в результате ссылка на объект, выбранный пользователем в интерактивном режиме (ключ interact), будет присвоена переменной K3 с названием obj1, которой соответствует объект в Python с именем varname. Для того, чтобы добраться до этого объекта, используем обращение к атрибуту value

k3.move(varname.value, k3.k_done, 100, 0, 0)

Этой функцией мы сдвигаем объект, лежащий в переменной K3, на 100 по оси x

Массив K3 создаётся похожим образом:

arrname = k3.VarArray(<length>, <name>)

Здесь <length> — это длина будущего массива, а <name> — его имя в K3.

Eksklamacia.png Не забывайте, что хотя Python может работать с динамическими списками, массивы K3 – статические, то есть содержат ровно столько элементов, какая длина указана при создании.

С точки зрения Python объект VarArray — это список объектов типа Var, каждый из которых – один элемент массива, например

for member in arrname:
	print(member.value)

выведет в консоль (в панель команд) значения всех элементов массива arrname

Аналогичным образом можно использовать и глобальные переменные и массивы, например:

gl_var = k3.GlobalVar(‘name’)

аналогично записи

global
name;

в K3, то есть объявляет глобальную переменную с именем name. В результате её значение можно получить (gl_var.value), проверить, было ли оно раньше присвоено (k3.isvardef(‘name’)) и так далее.

Учтите, что функция isvardef принимает не саму переменную, а её имя, то есть её аргумент должен быть строкой.

Работа с глобальными массивами осуществляется через k3.GlobalVarArray

Получение параметров в макропрограмму (getpar)[править | править код]

Для того, чтобы программа на python могла получить параметры макро, переданные через строку запуска, также как и в макропрограмме, нужно воспользоваться функцией getpar.

income = k3.getpar()

в результате переменной income будет присвоен список переменных K3, в которых и будут находиться переданные значения.

val0 = income[0].value
val1 = income[1].value
…
и т.д.

В отличие от макропрограммы в Python при вызове getpar не объявляется явно количество значений, которые мы собираемся получить.

Пример программы для К3-Мебель на Python[править | править код]

 # -*- coding: utf-8 -*-
 # Макро для поиска объектов с плохими записями в базе
 import k3	#Импортируем библиотеку функций и команд К3
 
 def Object_Is_Panel(obj):
 	'''Функция проверяет по атрибуту FurnType, является ли объект мебельной панелью'''
 	furntype = k3.getattr(obj, 'FurnType', '')		#Функция К3 getattr 
 	return furntype[:2]=='01' and not furntype[2:]=='0000'
 
 def Check_Panel_Material(obj):
 	'''Функция проверяет на корректность заданный для панели материал'''
 	if not Object_Is_Panel(obj):
 		return 1
 	priceid = k3.getattr(obj, 'PriceID', 0)
 	if priceid==0:
 		k3.putmsg('PriceID панели не задан или равен 0')	#Функция К3 putmsg 
 		return 0
 	if k3.priceinfo(priceid, 'Thickness', 0, 1)==0:	#Функция К3 priceifo 
 		k3.putmsg('Некорректный материал панели')
 		return 0
 	return 1
 
 k3.layers(k3.k_new, 'Possible_Errors')	#Функция К3 layers с ключом new
 object_number = int(k3.sysvar(62))	#sysvar(62) – количество объектов, но в Python добавляем int()
 errnum=0
 for current_number in range(object_number):
 	if not Check_Panel_Material (k3.getobjnums(current_number+1)):
 			k3.chprop(k3.k_layer, k3.k_partly, k3.getobjnums(current_number), k3.k_done, 'Possible_Errors')
 			errnum=errnum+1
 k3.putmsg(f'На слой Possible_Errors отправлено {errnum} объектов')

В основном теле программы создаётся новый слой командой layers с ключом new, затем идёт перебор всех объектов функцией getobjnums.

Заметьте, что функция getobjnums принимает в качестве аргумента номер объекта от 1 до sysvar(62), а счётчик в цикле range(object_number) в Python генерирует номера от 0 до object_number, поэтому объекты нумеруем, добавляя к значению счётчика 1.

Функция k3.putmsg() принимает на вход строку, поэтому можно использовать стандартное для Python форматирование строк.