Validation Pattern MUMPS - intersystems-cache

I am working to create a program in M that reads an input of names in a certain format. Once the user places a null value it prints out all of the values. Where I am getting stuck is reading into a global variable. I look forward to any input I can receive.
n prompt,val,done
s prompt="Enter a name (LAST,FIRST MI): "
s val="" f in=1:1 s val=$O(^ZNAME(val)) q:val=""
f w !,prompt r val q:val="" d q:done
. i val'?1.A1",".1" "1.A.1(1" "1A) w !,"Invalid name" q
. s val=$GET(^ZNAME)
. s done=1
i val="" q
w !,"You entered: ",val
. s done=1
q

Your code looks strange. In first this line s val="" f in=1:1 s val=$O(^ZNAME(val)) q:val="" is useless, just order all values in first subscript of global. Then your code should fail with UNDEFINED error for done variable when entered val will passed your pattern. And finally it gets new value from global ^ZNAME, and does not matter what was entered, it will get one value for all times.

I don't completely understand what you want to do but this is what I built:
read names till you give an empty name
if the name follows a pattern add him to ^ZNAME
at the end print all names in ^ZNAME
Here you go:
readlist
N prompt,val
S prompt="Enter a name (LAST,FIRST MI): "
F W !,prompt R val Q:val="" D
. I val'?1.A1",".1" "1.A.1(1" "1A) W !,"Invalid name"
. E S ^ZNAME(val)=""
F S val=$O(^ZNAME(val)) Q:val="" D
. W !,"You entered: ",val
Q
Example (using GTM):
GTM>D readlist^ZZTEST
Enter a name (LAST,FIRST MI): first,last
Enter a name (LAST,FIRST MI): name,surname
Enter a name (LAST,FIRST MI):
You entered: first,last
You entered: name,surname
GTM>zwr ^ZNAME
^ZNAME("first,last")=""
^ZNAME("name,surname")=""

Related

Writing numbers only each second and third line in Fortran

I am fighting with trying to get numbers 1 and 2 only on each second and third line in the second column.
I have a file tisk2 with
O
H
H
O
H
H
And I need to get to file tisk this:
O
H1
H2
O
H1
H2
I mean I want no number no text after O. I tried to write this code:
program cislo
implicit none
integer :: i, sum, j, k
character :: t*10, m*10
open(10,file="tisk2",status='old')
open(12,file="tisk",status='old')
do k=0,5
read(10,*) m
enddo
do j=1,3
do i = 0,0
t=" "
print*, t
exit
enddo
sum=0
do i=1,2
write(12,fmt='(a2,i2)') m, i
enddo
enddo
end program cislo
I can print only i and I get nothing, second line 1 and third line 2. Then alone print m. But when I want to put both to one file, it skips O and writes to file only H1, H2 and then again. Does anyone has an idea how to get what I need? Thank you for help.

Accessing external (DSPF) fields using arrays in RPGLE free

In the old RPG III and the non-free RPGLE/RPG IV you could "rename" fields you get from either a record of a PF/LF or a record from a DSPF.
This lead to possibilities like grouping several lines of input (additional order text) into a array. So I didn't have to MOVEL or EVAL ottxt1 to the external described field x1txt1, ottxt2 to x1txt2 and so on.
I'd only had to rename the LF record and the DSPF record fields to the array-fields, read the record and shift them from the one array to the other and display my DSPF record
H DECEDIT('0,') DATEDIT(*DMY.) dftactgrp(*no)
Fsls001 cf e workstn
Fordtxtl0 if e k disk
D ot s 20a dim(6)
D x1 s 20a dim(6)
Iordtxtr
I ottxt1 ot(1)
I ottxt2 ot(2)
I ottxt3 ot(3)
I ottxt4 ot(4)
I ottxt5 ot(5)
I ottxt6 ot(6)
Isls00101
I x1txt1 x1(1)
I x1txt2 x1(2)
I x1txt3 x1(3)
I x1txt4 x1(4)
I x1txt5 x1(5)
I x1txt6 x1(6)
C k$or00 klist
C kfld otonbr
C kfld otopos
C eval otonbr = 2
C eval otopos = 2
C k$or00 chain ordtxtr
C if %found(ordtxtl0)
C eval x1 = ot
C endif
C
C exfmt sls00101
C
C move *on *inlr
But is this also possible in *FREE RPGLE? And if so, how?
You can define data structures containing the fields from the files, and overlay them with an array.
Replace your I specs and array definitions with these data structures. You don't have to specify anything besides the field names for the fields from the externally-described file.
dcl-ds otDs;
ottxt1;
ottxt2;
ottxt3;
ottxt4;
ottxt5;
ottxt6;
ot like(ottxt1) dim(6) pos(1);
end-ds;
dcl-ds x1Ds;
x1txt1;
x1txt2;
x1txt3;
x1txt4;
x1txt5;
x1txt6;
x1 like(x1txt1) dim(6) pos(1);
end-ds;

Applying an operation on each element of nested list

I have a complex nested list (depth can be >2 also):
p:((`g;`d1`d2);(`r;enlist `e1);(`r;enlist `p1))
How to add an element to each element of the nested list but retaining the original structure; e.g. adding `h to each element of p to get the following :
((`g`h;(`d1`h;`d2`h));(`r`h;enlist `e1`h);(`r`h;enlist `p1`h))
I tried this but doesn't give what I want :
q)p,\:`h
((`g;`d1`d2;`h);(`r;enlist `e1;`h);(`r;enlist `p1;`h))
q)raze[p],\:`h
(`g`h;`d1`d2`h;`r`h;`e1`h;`r`h;`p1`h)
You can use .z.s to recursively go through the nested list and only append `h to lists of symbols:
q){$[0=type x;.z.s'[x];x,\:`h]}p
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h
For this function I have made the assumption that your nested lists will only contain symbols. It checks the type of the list, if it is not a mixed list then it appends `h to each element. If it is a mixed list then it passes each element of that list back into the function separately to check again.
Although not recursive (and so requires some knowledge about the shape of your nested list), a more conventional approach would be
q).[p;2#(::);,';`h]
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h
Though Thomas has already answered the question; In case you want to specify any other operation apart from append, you can use the following :
q)f:{`$ "_" sv string x,y}
q){[o;a;e] $[-11<>type e; .z.s [o;a] each e; o[e;a]] }[f;`h] each p
`g_h `d1_h`d2_h
`r_h ,`e1_h
`r_h ,`p1_h
or when f is assigned as append operation
q)f:{x,y}
q){[o;a;e] $[-11<>type e; .z.s [o;a] each e; o[e;a]] }[f;`h] each p
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h

Adding Columns in kdb based on other columns value

I have a column like this in dataframe named test:
Name Client
A P
B Q
C R
D S
E T
I need to to create a new column clienttype in the same dataframe with condition that, if Client = P or Q clienttype = first. If client type = R or S clienttype = second and so on. Can anyone tell how to do this in kdb? Thanks
Could this be solved with a dictionary?
q)update ClientType:(`P`Q`R`S!`first`first`second`second)Client from tab
Name Client ClientType
----------------------
A P first
B Q first
C R second
D S second
E T
Extension to this: You can also use vector conditionals ?[;;] for these types of problems. Unfortunately in this case in would result in many nested vector conditionals:
update Clienttype:?[Client in`P`Q;`first;?[Client in`R`S;`second;`third]]from tab
Name Client Clienttype
----------------------
A P first
B Q first
C R second
D S second
E T third
If you only had two possible options (e.g. first and second) this approach could prove useful.
You did not tell us the types of the columns in your table, but if all your entries are single letter, they are best represented by q char type:
q)show t:([]Name:"ABCDE";Client:"PQRST")
Name Client
-----------
A P
B Q
C R
D S
E T
Now, the Clienttype is best stored as a number which can be computed as
q)update Clienttype:1+(("i"$Client)-"i"$"P")div 2 from t
Name Client Clienttype
----------------------
A P 1
B Q 1
C R 2
D S 2
E T 3
or if you must use symbols,
q)types:`first`second`third`fourth
q)update Clienttype:types(("i"$Client)-"i"$"P")div 2 from t
Name Client Clienttype
----------------------
A P first
B Q first
C R second
D S second
E T third

Calculator doesn't execute the operations

I am trying to build a calculator in abap. The requirements are:
Reads
two numbers (ex. 56.3 and 78.2)
a character from the following list: q, w, e, r, t
Displays the result of the operation specified by the character
Addition for character q
Subtraction for character w
Multiplication for character e
Division for character r
Exponent for character t
I have created a table with the operations that I am using in the calculator.
The problem is when I execute the program it only prints my last option (else) "the operation is not possible".
Here's the code I wrote:
REPORT Z_CALCULATOR_V2.
TABLES: ZOPERATII.
DATA result type p decimals 2.
DATA Q type c.
DATA W like Q.
DATA E like Q.
DATA R like Q.
DATA T like Q.
PARAMETERS Nr_1 type p decimals 2 OBLIGATORY.
PARAMETERS Nr_2 like Nr_1 OBLIGATORY.
PARAMETERS Operatie LIKE zoperatii-operatie OBLIGATORY.
if Operatie = Q.
result = Nr_1 + Nr_2.
elseif Operatie = W.
result = Nr_1 - Nr_2.
elseif Operatie = E.
elseif Operatie = R.
result = Nr_1 / Nr_2.
elseif Operatie = T.
result = Nr_1 ** Nr_2.
else.
WRITE 'The operation is not possible'.
endif.
write result.
if you change the data declarations to:
DATA Q type c value 'Q'.
DATA W type c value 'W'.
DATA E type c value 'E'.
DATA R type c value 'R'.
DATA T type c value 'T'.
the code should run as you expect. That said, you should read up on the documentation as suggested in the comments.