検索

Article
· Oct 28, 2024 8m de lecture

Use the Flexible Python Runtime Feature for IRIS on Windows Server

I am just writing something to share what I encountered last night, which is the IRIS 2024.3 does not comes with Python by default any more!!!

Which means that I need to install it by myself!!😅 The pros is, I can select my python version😁🤭💃 The trouble is.... at the first place.... I don't know what I should do😥. By going through the community (I am much more prefer than the official document, sorry InterSystems document team😓 ), I found the following piece 

https://docs.intersystems.com/iris20242/csp/docbook/DocBook.UI.Page.cls?...

Hi, InterSystems document team good job!!! I love examples!!!😊

Let's go through it together!!!

1. Download Python from https://www.python.org/downloads/

OK, Let's try Python 3.12

2. Launch the Python installer.

3.Click Customize Installation.

4. Click Next until you reach the Advanced Options screen.

5. Select the option to Install Python for All Users.

I must say this step is very important😱, because I didn't check it in my 1st installation and seems causing the embedded python not working🤐

6. Click Install.

OK... seems that's all for the Python installation part😁 Let's check the path to see what is installed😀

 

 

 

Ok, let's move on to the Management Portal of the IRIS side😉

7. In the InterSystems IRIS Management Portal, go to System Administration > Configuration > Additional Settings > Advanced Memory.

8. On the Advanced Memory Settings page, in the PythonRuntimeLibrary row, click Edit.

9. Enter C:\Program Files\Python312\python3.dll.

"Don't double quote the path!!! Don't double quote the path!!! Don't double quote the path!!! ", this is what I found failure when I follow the "Example on Windows" and put a double quote around the path....😭😭😭. The instruction is so misleading😭😭😭 

10. Click Save.

11. On the Advanced Memory Settings page, in the PythonRuntimeLibraryVersion row, click Edit.

12. Enter 3.12.

13. Click Save.

 

Seems, the setting is ready😀 Let's move on to the terminal for the final verification 😊

14. From Terminal, launch Embedded Python and verify that sys.path now includes the Python 3.11 package directories.

do ##class(%SYS.Python).Shell()

import sys
sys.path

quit()

 

15. From Terminal, use the GetPythonInfo() method of the %SYS.PythonOpens in a new tab class to view the Python version information.

do ##class(%SYS.Python).GetPythonInfo(.info)

 

zw info

 

Looks good 😀 Let's test my code

I have written a utility class for generation dummy data in JSON, it seems stupid... 🤦‍♀️ but please forgive me I am still a beginner to python🤐

In my class, I try to have a mix the usage between object scripts and python😁😁

Come on, practice practice and practice😆

Class Demo.utli.datagen Extends %RegisteredObject
{

ClassMethod obsGen() As %String [ Language = python ]
{
	#w ##class(Demo.utli.datagen).obsGen()
	import json
	#C:\InterSystems\IRISHealth\bin> .\irispip.exe install --target C:\InterSystems\IRISHealth\mgr\python\ iris
	#python -m pip install --target C:\InterSystems\IRISHealth\mgr\python\ iris
	import iris
	
	#Blood pressure: between 90/60 mmHg and 120/80 mmHg
	#Breathing: 12 to 18 breaths per minute
	#Pulse: 60 to 100 beats per minute
	#Temperature: 97.8°F to 99.1°F (36.5°C to 37.3°C); average 98.6°F (37°C)
	##gen bpsys 
	ranvalue=iris.cls("Demo.utli.datagen").resultValueGen("80-120")
	#print(ranvalue)
	ranvaluelist=ranvalue.split(',')
	bpsys=ranvaluelist[0]
	
	##gen bpdia 
	ranvalue=iris.cls("Demo.utli.datagen").resultValueGen("60-90")
	#print(ranvalue)
	ranvaluelist=ranvalue.split(',')
	bpdia=ranvaluelist[0]
	
	
	obs={'bpsys':bpsys,'bpdia':bpdia}
	#print(obs)
	
	return json.dumps(obs)
}

ClassMethod forTest() As %String [ Language = objectscript ]
{
	//w ##class(Demo.utli.datagen).forTest()
	set a={}.%FromJSON(..obsGen()) //from json tn dynamic object
	w a,!
	w "bpsys is "_a.bpsys_", bpdia is "_a.bpdia,!  // write the individual data
	set b=a.%ToJSON()	//from dynamic object to json
	w b,!
	
	// loop through the array using an iterator
	set iter = a.%GetIterator()
	while iter.%GetNext(.key , .value ) 
	{
		write !, ?5, "Key: ", key, ", Value: ", value, " type: ", a.%GetTypeOf(key)_" with value "_a.%Get(key)
	}
	w !
	return 1
}

ClassMethod labresultGen1() As %String [ Language = python ]
{
	#w ##class(Demo.utli.datagen).labresultGen1()
	import json
	import datetime
	#python -m pip install --target C:\InterSystems\IRISHealth\mgr\python\ iris
	import iris
	
	# init result
	initstr='{"labresults": [{"LabOrderNumber": "Lab24100001", "ItemNumber": "1", "ItemCode": "6690-2", "ItemCodeSystem": "LN", "ItemDesc": "Wbc", "ItemStatus": "F", "Value": "7.0", "Unit": "/nl", "RefRange": "3.8-11.0", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.552090", "UpdatedAt": "2024-10-21 16:49:01.552090"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "2", "ItemCode": "770-8", "ItemCodeSystem": "LN", "ItemDesc": "Neutros", "ItemStatus": "F", "Value": "68", "Unit": "%", "RefRange": "40-82", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.552090", "UpdatedAt": "2024-10-21 16:49:01.552090"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "3", "ItemCode": "736-9", "ItemCodeSystem": "LN", "ItemDesc": "Lymphs", "ItemStatus": "F", "Value": "20", "Unit": "%", "RefRange": "11-47", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.552090", "UpdatedAt": "2024-10-21 16:49:01.552090"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "4", "ItemCode": "5905-5", "ItemCodeSystem": "LN", "ItemDesc": "Monos", "ItemStatus": "F", "Value": "16", "Unit": "%", "RefRange": "4-15", "Abnormal": "H", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.552090", "UpdatedAt": "2024-10-21 16:49:01.552090"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "5", "ItemCode": "713-8", "ItemCodeSystem": "LN", "ItemDesc": "Eos", "ItemStatus": "F", "Value": "3", "Unit": "%", "RefRange": "0-8", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553096", "UpdatedAt": "2024-10-21 16:49:01.553096"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "6", "ItemCode": "706-2", "ItemCodeSystem": "LN", "ItemDesc": "Baso", "ItemStatus": "F", "Value": "0", "Unit": "%", "RefRange": "0-1", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553160", "UpdatedAt": "2024-10-21 16:49:01.553160"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "7", "ItemCode": "38518-7", "ItemCodeSystem": "LN", "ItemDesc": "Imm Gran", "ItemStatus": "F", "Value": "0", "Unit": "%", "RefRange": "0-2", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553160", "UpdatedAt": "2024-10-21 16:49:01.553160"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "8", "ItemCode": "789-8", "ItemCodeSystem": "LN", "ItemDesc": "Rbc", "ItemStatus": "F", "Value": "4.02", "Unit": "/pl", "RefRange": "4.07-4.92", "Abnormal": "L", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553296", "UpdatedAt": "2024-10-21 16:49:01.553296"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "9", "ItemCode": "718-7", "ItemCodeSystem": "LN", "ItemDesc": "Hgb", "ItemStatus": "F", "Value": "13.7", "Unit": "g/dl", "RefRange": "12.0-14.1", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553296", "UpdatedAt": "2024-10-21 16:49:01.553296"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "10", "ItemCode": "4544-3", "ItemCodeSystem": "LN", "ItemDesc": "Hct", "ItemStatus": "F", "Value": "40", "Unit": "%", "RefRange": "34-43", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553296", "UpdatedAt": "2024-10-21 16:49:01.553296"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "11", "ItemCode": "787-2", "ItemCodeSystem": "LN", "ItemDesc": "Mcv", "ItemStatus": "F", "Value": "80", "Unit": "fl", "RefRange": "77-98", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553296", "UpdatedAt": "2024-10-21 16:49:01.553296"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "12", "ItemCode": "mch", "ItemDesc": "Mch", "ItemStatus": "F", "Value": "30", "Unit": "pg", "RefRange": "27-35", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553296", "UpdatedAt": "2024-10-21 16:49:01.553296"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "13", "ItemCode": "mchc", "ItemDesc": "Mchc", "ItemStatus": "F", "Value": "32", "Unit": "g/dl", "RefRange": "32-35", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553296", "UpdatedAt": "2024-10-21 16:49:01.553296"}, {"LabOrderNumber": "Lab24100001", "ItemNumber": "14", "ItemCode": "plt", "ItemDesc": "Platelets", "ItemStatus": "F", "Value": "221", "Unit": "/nl", "RefRange": "140-400", "InputBy": "12", "InputOrg": "lab", "InputDateTime": "2024-10-21 16:49:01.553296", "UpdatedAt": "2024-10-21 16:49:01.553296"}]}'
	#print(initstr)
	
	# convert to dict
	initstrdic=json.loads(initstr)
	#print(initstrdic)
	
	# loop through the reslut
	labresults=initstrdic["labresults"]
	for result in labresults:
		# update the result
		x=datetime.datetime.now()
		result.update({"InputDateTime":x.strftime("%Y-%m-%d %H:%M:%S.%f")})
		result.update({"UpdatedAt":x.strftime("%Y-%m-%d %H:%M:%S.%f")})
		#print(result["RefRange"])
		ranvalue=iris.cls("Demo.utli.datagen").resultValueGen(result["RefRange"])
		#print(ranvalue)
		ranvaluelist=ranvalue.split(',')
		result.update({"Value":ranvaluelist[0]})
		result.update({"Abnormal":ranvaluelist[1]})
		#print(result)
	
	#print(labresults)
	# put the lab result list into dict
	labresultsdict={"labresults":labresults}
	return json.dumps(labresultsdict)
}

ClassMethod resultValueGen(range = "0-1") As %String [ Language = python ]
{
	import random
	#w ##class(Demo.utli.datagen).resultValueGen()
	# expecting the range is numeric which look like "3-17" with a dash seperator
	list1=range.split('-')
	lowerbound=int(float(list1[0]))
	uppderbound=int(float(list1[1]))
	#print(lowerbound)
	#print(uppderbound)
	if uppderbound==1:
		ranvalue=random.randrange(0, 2)
	else:
		a=lowerbound-2
		if a<0:
			a=0
		b=uppderbound+2
		ranvalue=random.randrange(a, b)
	rtstr=str(ranvalue)+','
	if ranvalue<lowerbound:
		rtstr=str(ranvalue)+',L'
	if ranvalue>uppderbound:
		rtstr=str(ranvalue)+',H'	
	return rtstr
}

}

 

OK let's test it on the terminal

 

1st Change to my namespace

 

2nd run the code

 

looks good😉, let's try another piece

 

😁 seems not bad, let's try the final piece

 

seems working 😊

 

Thank you for reading😚

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Article
· Oct 28, 2024 2m de lecture

第四章 I O 输入输出简介 - Read 命令

第四章 I O 输入输出简介 - Read 命令

Read 命令

该命令从当前设备读取数据。对于某些设备,以星号开头的参数返回 ASCII 数字信息;对于其他人来说,它们表示控制功能。

语法

READ variable:timeout

WRITE 命令

该命令将数据写入当前设备。对于某些设备,以星号开头的参数允许使用其 ASCII 数值写入 ASCII 字符;对于其他人来说,它们表示控制功能。对于某些设备,以 # 字符开头的参数指示写入该字符的次数。

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Question
· Oct 28, 2024

How to print selected rows in a detail listing in a pivot table

Hi, I'm new to the Analytics world in Intersystems and was attempting to print and/or export selected rows from a detail listing in a pivot on a dashboard.  I am able to print and/or export all the rows; but if I select a specific set of rows, it prints out the entire detail listing; not the selected rows. Please advise on the best approach to accomplish this task.  Thanks.

2 Comments
Discussion (2)2
Connectez-vous ou inscrivez-vous pour continuer
Question
· Oct 28, 2024

Business Process - Export Code with different versions

Our TEST environment and PROD environment are on two different versions of HealthShare Health Connect.

TEST IRIS for UNIX (Red Hat Enterprise Linux 8 for x86-64) 2024.1 (Build 267_2U) Tue Apr 30 2024 16:06:39 EDT [HealthConnect:7.2.0-1.r1]
PROD IRIS for UNIX (Red Hat Enterprise Linux 8 for x86-64) 2022.1.4 (Build 812_0_22913U) Thu Dec 7 2023 17:06:30 EST [HealthConnect:3.5.0-1.m1] [HealthConnect:3.5.0-1.m1]

Someone within the group wants to migrate a BP from TEST to PROD, however they are running into an error "attribute 'languageOverride' is not declared for element 'assign'" 

I know when we were moving from 2018 to 2022.1.4 there was a command we had to call to format the exports correctly because of the different versions of HealthShare Health Connect. 

  • Is this the same case here?
    • Can someone remind me what that command is?
  • Or how do we get around this error when moving code from a newer version to an older version?
4 Comments
Discussion (4)3
Connectez-vous ou inscrivez-vous pour continuer
Article
· Oct 28, 2024 2m de lecture

Écriture d'une fonction d'agrégation définie par l'utilisateur dans IRIS - exemple : Median

Les fonctions d'agrégation définies par l'utilisateur sont prises en charge dans IRIS depuis 2021.1.0. J'avais souhaité une étoile pour celle-ci il y a des années avant de trouver un moyen secret et astucieux de remplacer MAX et MIN dans un type de données personnalisé, mais je n'ai pas eu l'occasion d'en essayer un jusqu'à aujourd'hui. J'ai pensé que c'était une expérience/un exemple intéressant - la question de savoir comment obtenir une médiane dans IRIS SQL s'est déjà posée une fois - donc je la partage ici sans trop de commentaires supplémentaires.

Une mise en garde : les UDAF n'ont pas la belle parité objet/SQL que les autres types de fonctions ont, vous devez donc exécuter SQL pour définir la fonction d'agrégation (utilement enveloppée dans une méthode de classe dans l'exemple ci-dessous). La compilation de la classe seule ne suffit pas.

/// Classe implémentant une fonction d'agrégation médiane pour IRIS SQL
Class DC.Demo.Median
{

/// Renvoie une nouvelle référence globale dans IRISTEMP à utiliser pour stocker les résultats intermédiaires
ClassMethod Initialize() As %String [ PublicList = ref, SqlProc ]
{
    New ref
    Set ref = $Name(^IRIS.Temp.UDAF.Median($Increment(^IRIS.Temp.UDAF.Median)))
    Set @ref = 0
    Quit ref
}

/// Met à jour la valeur globale temporaire pour un seul enregistrement
ClassMethod Iterate(ref As %String, value As %Numeric) As %String [ SqlProc ]
{
    If (value '= "") {
        Do $Increment(@ref)
        Do $Increment(@ref@(+value))
    }
    Quit ref
}

/// Trouve la médiane réelle (éventuellement une moyenne des deux valeurs médianes)
ClassMethod Finalize(ref As %String) As %Numeric [ SqlProc ]
{
    Set median = ""
    Set total = @ref
    Set position1 = (total+1)\2
    Set position2 = (total+2)\2
    Set val1 = ""
    Set val2 = ""
    Set reached = 0
    Set key = ""
    For {
        Set key = $Order(@ref@(key),1,refCount)
        Quit:key=""
        set reached = reached + refCount
        if (reached >= position1) && (val1 = "") {
            Set val1 = key
        }
        if (reached >= position2) && (val2 = "") {
            Set val2 = key
        }
        If (val1 '= "") && (val2 '= "") {
            Set median = (val1+val2)/2
            Quit
        }
    }
    Kill @ref
    Quit median
}

/// Pour définir réellement l'UDAF d'un point de vue SQL, appelez cette méthode de classe.
ClassMethod Define()
{
    // Supprimez la fonction au cas où quelque chose aurait changé
    &sql(DROP AGGREGATE DC_Demo.Median)
    &sql(CREATE AGGREGATE DC_Demo.Median(arg NUMERIC) RETURNS NUMERIC
       INITIALIZE WITH DC_Demo.Median_Initialize
       ITERATE WITH DC_Demo.Median_Iterate
       FINALIZE WITH DC_Demo.Median_Finalize)
    $$$ThrowSQLIfError(SQLCODE,%msg)
}

}

J'espère que cela aidera quelqu'un !

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer