go to post Stuart Strickland · May 12, 2023 And the answer to passing multiple arguments to ZLANG commands was given only a few days ago: https://community.intersystems.com/post/zlangc0-functionality#comment-22...
go to post Stuart Strickland · Apr 13, 2023 So much easier with journalling switched on! In February 2000 we had to "undelete" a global containing all the cash transaction records at a large investment management institution when one of our colleagues accidentally deleted it near the end of the day. No journals, no backup, no option to re-input a whole day's work. Luckily the data was still there, albeit with no block pointers. It was a DSM system so we modified a program called ^BLCKDMP to read every block on the disk and write every node from our lost global out to an O/S file in %GO format. Took 15 hours to run and we had the system back by 9am the next day. Needless to say, everything changed from then with regards to journalling and backups and programmer access. It was an interesting experience in emergency firefighting and a nice learning experience in how the data is stored using the "common characters" space saving mechanism. M is really quite brilliant.
go to post Stuart Strickland · Mar 19, 2023 I remember working on a system like that written in something called MaxiMumps. When doing their equivalent of $Order the second time you found null was the end of the subscript range. They also had an post-conditional character ";" which behaved like "if not". These two lines were effectively the same. S:A'=B C=D S;A=B C=D ...to save a character!
go to post Stuart Strickland · Feb 19, 2023 Hi Mark, When looping through numerics, unless you intervene, it will loop through every number in magnitude order until you reach the end. So, if you start at 8009 and 8010 exists then it will find it. And 8009 is not next to 800900001 by a long way. When looping through strings, it's going to go through them like a human would when going through a dictionary. All words with the same prefix are next to each other. So you can easily stop your loop immediately when you find a word that doesn't match. This code will probably do what you want, athough I haven't tested it: Noddy ;; Find all subscripts with numeric prefix using minimum $ORDER ;Find(Prefix=8009,MaxSubscriptlength=12) I Prefix=+Prefix { // Must be numeric S MatchLength=$l(Prefix) F I=MatchLength:1:MaxSubscriptLength { // try starting from every number beginning with // 8009, thru 80090, 800900, up to say 800900000000 // or whatever the maximum subscript length is S Start=Prefix_$E("000000000000",0,I-MatchLength) F { // see if we found one, even at the start of the loop I $D(^REXREF3(1,Start)) { // but it must have our prefix // this test can end the loop! Q:$E(Start,1,MatchLength)'=Prefix // but only looking for numerics in this loop // don't want to find again later Q:Start'=+Start // Now do whatever it is you want to do with it.. // <REMOVE MINE AND INSERT YOUR CODE HERE> W !,Start } S Start=$O(^REXREF3(1,Start)) Q:Start="" } } } // Now look for strings with that prefix // all strings starting with 8009 will immediately follow "8009 " // so start there, there won't be an numeric subscripts following a string S Start=Prefix S MatchLength=$l(Prefix) I Prefix=+Prefix S Start=Start_" " F { // see if we found one, even at the start of the loop I $D(^REXREF3(1,Start)) { // but it must have our prefix // this test can end the loop! Q:$E(Start,1,MatchLength)'=Prefix // Now do whatever it is you want to do with it.. // <REMOVE MINE AND INSERT YOUR CODE HERE> W !,Start } S Start=$O(^REXREF3(1,Start)) Q:Start="" } q
go to post Stuart Strickland · Jan 3, 2023 I had to do something like this a few years ago to add a digital signature to a message in XML format. If I remember correctly you have to get your object into a %XML.Document which works in conjunction with %XML.Node. %XML.Node is used to traverse the %XML.Document to get to the section you want in canonical form. Then you pass the Node to ##class(%XML.Writer).Canonicalize(Node) to get the XML as a string which is then passed to the encryption function you use to get your digest/signature. You can pass the whole document or just a subsection to the canonicalize function. I can't say if it's the only or best way to do it but it was sufficiently quick enough to handle thousands of messages per minute.
go to post Stuart Strickland · Dec 14, 2022 Discourage the use of hard coded breaks in the first place! There are alternatives. Use ZBREAK Tag+OffSet^Routine to set a break point just for the current process Use the debugger in Cache´ Studio (under the Debug menu and attach to a process) George James has a decent debugger in Serenjii Put something in your processes to remove hard coded break points when you promote code through the development cycle (you can automate this if you try)
go to post Stuart Strickland · Nov 24, 2022 I've seen some places where the ^ROUTINE global is fully or partially deleted after compilation. I suspect that the same would work for ^rMAC or ^oddDEF - you'd have to test it. One company that I'm aware of encrypts the ^ROUTINE global after compilation which has the added "benefit" of making it extra difficult to debug errors! If you really want to hide your code you could compile the code on an identical system and then just deploy the object code.
go to post Stuart Strickland · Nov 11, 2022 I had the same thoughts but decided to make assumptions that allowed me to code using the least characters. If you cater for the tricky stuff you'd probably have to double the length of your code.
go to post Stuart Strickland · Nov 11, 2022 Shaved off another character ClassMethod Order(a As %String) As %String{1 s s=$p(a," ",$i(i)),n=$zstrip(s,"*a"),$p(z," ",n)=$tr(s,n) G 1:n Q $g(z)}
go to post Stuart Strickland · Nov 11, 2022 Make that 77 with this: ClassMethod Order(a As %String) As %String{ f{s s=$p(a," ",$i(i)),n=$zstrip(s,"*a"),$p(z," ",n)=$tr(s,n) ret:'n $g(z)}}
go to post Stuart Strickland · Nov 11, 2022 Nice generation of a pandigital number with 1e20/17. Can save a character with $zpi_0 ClassMethod Order(a As %String) As %String{ s r=a f i=1:1:5e5{s s=$p(a," ",i),w=$tr(s,$zpi_0),$p(r," ",$tr(s,w))=w} q r} This was mine also at 78: ClassMethod Order(a As %String) As %String{ f i=1:1 s s=$p(a," ",i),n=$zstrip(s,"*a"),$p(z," ",n)=$tr(s,n) ret:'n $g(z)}
go to post Stuart Strickland · Sep 1, 2022 And if you find the job is starting (from evidence provided by $T and $ZCHILD) then ensure you have an error trap in your class to catch why it's falling over. At the very least make it Set ^tempGlo($H)=$ZE or DO ^%ET when it encounters an error. If you can't edit the class for any reason then JOB a routine that you can edit and make that call your class after setting up an error trap.
go to post Stuart Strickland · Aug 16, 2022 #1) Why did you choose to become a software engineer / developer? I was at University when introduced to COBOL. Found it really easy and natural while my friends appeared to struggle. Some of them offered to pay me to write their coursework. The first program I sold was to the nephew of the manager of a Scottish pop group (The Bay City Rollers). He gave me a 3 month supply of potatoes for one program! When I found I could make an easy living writing code there was no looking back. (And I haven't been paid in potatoes since I was a student) #2) How and when did you start to generate a "flow state of mind" during your career? We were taught Jackson Structured Programming at Uni. A short time drawing on a large sheet of paper how a program should flow works wonders for getting it right first time. (Right first time saves money). If you start off as you mean to go on it very quickly becomes the natural way to do things. I don't use JSP now but its basic principles are the basis for how my programming mind thinks. I'd say you should pick a programming methodology and stick to it until you are competent. As @Robert Cemper said, learn your language fluently. #3)What are recommended habits inside and outside, during you own time and duringyour work time, to be focused during your coding session and daily tasks?Write re-useable code that can be called to do small or big repetitive tasks. Don't try to write anything that is all things to all people. If you write code well then it should be easy to add new functionality. When you are happy that your code is doing the job, don't seek the approval of someone with a big ego - they will try to make you re-write it. And related to this, if someone else writes code that works yet you don't understand it realise that it's your time to learn, don't try to make them change it. Comment your code then go back and re-read it the next day. If it doesn't make sense to you then it won't make sense to anyone else. Write the gist of a program at the top of the code. Your code is going to have your name on it for years. Make it a good advert for your skills. If you find something repetitive and/or annoying, automate it. It might cost you a couple of hours in the short term but in the long term it will save you years. Don't allow yourself to be distracted by valueless tripe while at work (eg social media) Find a way to make things fun and enjoy yourself.
go to post Stuart Strickland · Jul 8, 2022 199 if I steal your ideas f i=1:1:$l(a){s x=$lfs("A,4,@,B,|3,8,C,(,<,E,3,€,G,9,6,I,|,],K,|<,|{,L,1,£,O,0,*,S,5,$,T,7,+,X,><,}{,Z,2,~/_"),c=$e(a,i),p=$lf(x,$$$UPPER(c)) s:p k(p)=3-$g(k(p),2),c=$li(x,p+k(p)) s r=$g(r)_c} q r
go to post Stuart Strickland · Jul 8, 2022 I did have a 220 in one line but your answer is superb. S A=$lfs("A,4,@,,B,|3,8,,C,(,<,,E,3,€,,G,9,6,,I,|,],,K,|<,|{,,L,1,£,,O,0,*,,S,5,$,,T,7,+,,X,><,}{,,Z,2,~/_") f i=1:1:$l(x){s L=$E(x,i),P=$lf(A,$zu(28,L,5))+3 s:P#4=0 $LI(A,P)='$LG(A,P),$e(x,i)=$LI(A,P-1-$LG(A,P))} q x
go to post Stuart Strickland · Jul 4, 2022 Here's my answer. Looks like I'm playing on my own. 242 Chars, not including comments. /// For rules see https://community.intersystems.com/post/code-golf-zcvtstr-leet/// Build a list where each letter that is to be replaced /// is followed in the list by its two possible replacements./// The next piece indicates which was the last replacement used./// Note: Only uppercase letters are in the list so need to /// translate before searching, using $ZU(28,L,5) to translate./// For each character in the input string find its list position./// Use $LISTFIND to find its position./// Test the position found with Position-1#4/// Not found characters return 0, and 0-1#4 is non zero so do nothing with them/// Positions 1,5,9,11,15,19,23,27,31,35,39,43, and 47 contain characters/// that must be replaced. Position-1#4 is zero for these./// No test case or rule for any of the destination symbols already existing in/// the input string. Introducing that will complicate things as would need to test/// character before and after current one to try to avoid double letters./// When each character is found change the last used replacement indicator./// Then return the replacement characters./// If the replacement characters contained any of the replaceable characters/// then you would have to work backwards from the end of the input string/// to avoid getting in a loop. This would cost 1 character.ClassMethod Convert(x As %String) As %String{S A=$lfs("A,4,@,,B,|3,8,,C,(,<,,E,3,€,,G,9,6,,I,|,],,K,|<,|{,,L,1,£,,O,0,*,,S,5,$,,T,7,+,,X,><,}{,,Z,2,~/_")f i=1:1:$l(x){s $E(x,i)=$$r($e(x,i))} q xr(L)S P=$lf(A,$zu(28,L,5)) q:P-1#4 L S $LI(A,P+3)='$LG(A,P+3) Q $LI(A,P+2-$LG(A,P+3))}
go to post Stuart Strickland · Jul 1, 2022 I've got an answer in 242 characters but I think there's a mistake in the test case: Do $$$AssertEquals(##class(CodeGolf.Leet).Convert("no no no no "), "n0 n* n0 n*") Do $$$AssertEquals(##class(CodeGolf.Leet).Convert("Iris"), "|R]5") The "n" doesn't get converted to uppercase but the "r" does. Surely it should be Do $$$AssertEquals(##class(CodeGolf.Leet).Convert("Iris"), "|r]5") and there's a rogue space at the end of "no no no no ".
go to post Stuart Strickland · May 20, 2022 185 - with an unusual use of $PIECE instead of $SELECT to save 2 characters, which would also shorten yours to 184 1 s c=",",x=$p(a,c,$i(i)) q:x="" o f{s y=$p(a,c,$i(j)+i),g=$g(g,y-x) q:j*g+x'=y s l="-"_y} s g=$zabs(g),$p(o,c,$i(p))=x s:2-'g<j o=o_$s(g:l_$p("/"_g,c,g>1),1:"*"_j),i=i+j-1 k g,j g 1 f i=1:1:2e6{s x=",",a=$p(s,x,i),d=$p(s,x,i+1)-a f c=1:1{q:d*c+a'=$p(s,x,i+c)} s q=$zabs(d),v=$s(c>2&d:"-"_(c-1*d+a)_$p("/"_q,x,q>1),c>1&'d:"*"_c,1:0) s:v'=0 $p(s,x,i,i+c-1)=a_v} q s
go to post Stuart Strickland · May 19, 2022 Hi Vitaliy, Out of curiosity I had a go at this. I can't get under 188 using my own ideas and code: 1 s c=",",x=$p(a,c,$i(i)) q:x="" o f{s y=$p(a,c,$i(j)+i),g=$g(g,y-x) q:j*g+x'=y s l=y} s g=$zabs(g),$p(o,c,$i(p))=x s:2-'g<j o=o_$s(g:"-"_l_$s(g>1:"/"_g,1:""),1:"*"_j),i=i+j-1k g,j g 1 You could shave 2 characters off each of your versions by having a variable contain the comma: a s x=",",a=$p(s,x,$i(i)),d=$p(s,x,i+1)-a f c=1:1{q:d*c+a'=$p(s,x,i+c)} s q=$zabs(d),v=$s(c>2&d:"-"_(c-1*d+a)_$s(q=1:"",1:"/"_q),c>1&'d:"*"_c,1:0) s:v'=0 $p(s,x,i,i+c-1)=a_v q:a="" s g a