Using externally described data structures in RPG ILE Free - rpgle

I'm having a world of issues using externally described data structures in RPG ILE Free.
The simplest issue seems to be just declaring the structure.
DCL-DS PALWGHT extname(SCN102DS);
PW DIM(20) OVERLAY(PALWGHT:1);
END-DS;
When I compile, it says the external file does not exist...but it does and it is in my library list.
A R PALWGHT
A P01WGHT 11S 3
A P02WGHT 11S 3
A P03WGHT 11S 3
A P04WGHT 11S 3
A P05WGHT 11S 3
A P06WGHT 11S 3
A P07WGHT 11S 3
A P08WGHT 11S 3
A P09WGHT 11S 3
A P10WGHT 11S 3
A P11WGHT 11S 3
A P12WGHT 11S 3
A P13WGHT 11S 3
A P14WGHT 11S 3
A P15WGHT 11S 3
A P16WGHT 11S 3
A P17WGHT 11S 3
A P18WGHT 11S 3
A P19WGHT 11S 3
A P20WGHT 11S 3
This worked prior to changing it to free format.....
DPALWGHT E DS EXTNAME(SCN102DS)
DPW 11s 3 DIM(20) OVERLAY(PALWGHT:1)
I'm lost. It's probably something really stupid....

A couple issues. First, in free-form the file name in EXTNAME(filename) must be either a Named Constant or character literals. This is different from the fixed form variant which can be a File Name or character literals. If you read all the error messages you get RNF0202 - THE PARAMETER FOR EXTNAME OR EXTFLD MUST BE A DEFINED NAMED CONSTANT OR LITERAL. If you use a file name, it must be enclosed in quotes in free-form.
DCL-DS PALWGHT extname('SCN102DS');
PW is still undefined though because it does not have a type declaration. And, in free-form, OVERLAY() cannot point at the data structure. Instead you use POS(). So the whole thing should look something like:
DCL-DS PALWGHT extname('SCN102DS');
PW LIKE(P01WGHT) DIM(20) POS(1);
END-DS;

Related

Trying to remove '1/2, 3/4, 1/3' values in excel using pandas

I have a practice column with these values in excel
apple
0 1 1/2
1 2 1/4
2 3 3/4
Excel turns these values into Fractions, so the output is like this:
app
0 1.50
1 2.25
2 3.75
All I am trying to do is a find/replace so the output turns into this
app
0 1
1 2
2 3
I've tried all kinds of things, but cant get it to work. I know how to do the find/replace part, just not how to remove the decimals or better yet, the fractions.
This are two different versions of turning the fractions into string values
fraction_df=df.astype({'app':'string'})
df['app']=df['app'].astype('string')
and then I tried to run find/replace
df=df.replace(['1/2','3/4','1/3'], '', regex=True)
A simple problem, but I can't seem to figure it out
To convert 1.5 to 1 do the following:
df['app'] = pd.to_numeric(df['app']).astype(int).astype(str)
To convert 1 1/2 to 1.5:
df['app'] = (df['app']
.str.extract('(?P<a>\d+)\s+(?P<b>\d+)/(?P<c>\d+)')
.astype(int).eval('a+b/c')
)

python return wrong result when I multiple float with int

I have a multiple in python 3.7.3
when I run 0.58 * 100 it return 57.99999999999999
Then I found that Java have same result. But C can return right number. I don't know what happen with them. Sorry if it look like basic.
Its actually not the wrong answer, just an unexpected one.
If we think a bit about the problem, There are an infinite amount of numbers between 0 and 1. Then we can see that you cannot represent all numbers between 0 and 1 with a finite amount of bytes, as infinite numbers are more then a finite number of numbers. so some numbers just cant be represented (in fact, most numbers of the infinite series between 0 and 1 cannot be represented)
Following the floating point standard (IEEE-754), 0.58 is really 0.5799999999999999289457264239899814128875732421875 which is the closest number to 0.58 that can be represented with 64bit floating points.
check it with python
>>> Decimal(0.58)
Decimal('0.57999999999999996003197111349436454474925994873046875')
If you want 58.0 you can quantize it to two decimals with the Decimal class.
>>> Decimal(100 * 0.58).quantize(Decimal('.01'))
Decimal('58.00')

Python KeyError: 'column name'

I have the data file which looks like this -
[Table 1]
Terms Author Frequency
Hepatitis Christopher 2
Acid Subrata 1
Acid Kal 3
Kinase Pramod 31
Kinase Steve 5
Kinase Sharon 10
Acid Rob 5
Acid Christopher 2
Hepatitis Sharon 3
which I want to convert in a frequency matrix like this -
Terms Christopher Subrata Kal Pramod Steve Sharon Rob
Hepatitis 2 0 0 0 0 3 0
Acid 2 0 3 0 0 0 5
Kinase 0 0 0 31 5 10 0
Now I have figured out how to do that and I am using this code for that -
a = pd.read_csv("C:\\Users\\robert\\Desktop\\Python Project\\Publications Data\\New Merged Title Terms Corrected\\Python generated file\\Terms_Frequency_File.csv")
b = a.groupby(['Terms']).apply(lambda x:x.set_index(['Terms','Author']).unstack()['Frequency'])
and this worked absolutely fine till yesterday but today I generated the [Table 1] data again as I had to add one additional author to the data and trying to make a frequency matrix again like in [Table 2] but it's giving me this silly error -
KeyError: 'Terms'
I am pretty sure this has to do something with the index column in the dataframe or some white space issues in the index column(in this case 'Terms' column).
I tried to read several answers on this like this - KeyError: 'column_name' and this - Key error when selecting columns in pandas dataframe after read_csv and tried those methods but these aren't helping.
Any help on this will be much appreciated! Thanks much!
I've got the same problem as you. I've observed that if I change the data in .csv format in OpenOffice program then the error occurs. Instead of that I've downloaded the data from the Internet and I edited the data in simple Notepad++ editor. Then it works normally. I know that perhaps this solution doesn't help in you case, but maybe you should change the text editor or program that supports .csv files.

SAS 9.4 Character functions - Why might one cell return unexpected results?

I am manipulating some string variables and certain cells are returning unexpected values with substring and length functions. These cells hold character-formatted dates, as I need to do a few manipulations before converting them to SAS dates, because of the nature of the Excel file they're coming from. Here is an example:
HAVE:
Obs _orig
1 4/3
2 12/16
3 1/13
4 6/2
5 3/10
6 5/4
7 10/14
WANT:
Obs _orig _length _sub_1_2
1 4/3 3 4/
2 12/16 5 12
3 1/13 4 1/
4 6/2 3 6/
5 3/10 4 3/
6 5/4 3 5/
7 10/14 5 10
I am using this code:
data want;
set have;
_strip=strip(_orig);
_sub_1_2=substr(_strip,1,2);
_length=length(_strip);
run;
This is what I get. The discrepancies are bolded.
Obs _orig _length _sub_1_2
1 4/3 5
2 12/16 5 12
3 1/13 4 1/
4 6/2 3 6/
5 3/10 4 3/
6 5/4 5
7 10/14 5 10
Both are cases where SAS calculates length=5 when length should = 3. In both cases, the value for the substring-derived variable is blank altogether. Results are the same if I use compress(), trim(), or trimn() in my code, rather than strip(). Thank you for any help you can provide
Sounds like maybe unprintable characters got in your data. If you PUT _orig $hex.; to the log, what do you see? Should be: 342F332020
152 data want;
153 length orig $5;
154 orig='4/3';
155 len=length(orig);
156 put orig= len=;
157 put orig hex.;
158 run;
orig=4/3 len=3
342F332020
To get rid of non-printable characters, you could try:
_strip=compress(orig,,'kw');
Seems pretty clear to me that your variables have leading spaces or other leading characters that look like spaces on the screen. So for OBS=6 the value of the string is more like " 5/4" which has a length of 5 and the first two characters both look like spaces. If LENGTHN() of your new _sub_1_2 variable is not 0 then it has some non-printing character there. Perhaps something like 'A0'X which some webpages use as a non-breaking space or tab character ('09'x).
I suspect that you don't want the first two characters, but instead want the first word when using / as the delimiter. You can use the LEFT() or STRIP() function to remove the leading blanks. Or COMPRESS() to remove other junk. So you might use COMPRESS() with the k and d modifiers to only keep the digits and slashes.
data want;
set have;
length first $5 ;
first = scan(compress(_orig,'/','kd'),1,'/');
run;

Is there a J idiom for adding to a list until a certain condition is met?

Imagine you're generating the Fibonacci numbers using the obvious, brute-force algorithm. If I know the number of Fibonaccis I want to generate in advance, I can do something like this using the power conjunction ^::
(, [: +/ _2&{.)^:20 i.2
How can I instead stop when the Fibonaccis reach some limit, say 1e6? (I know how to do this inside a function using while., but that's no fun.)
I want to stress that this is a general question about J, not a specific question about Fibonacci. Don't get too distracted by Fibonacci numbers. The heart of the question is how to keep appending to a list until some condition is met.
Power has also a verb form u^:v^:n where the second verb can be used as a check. Eg: double (+:) while (n is _) less than 100 (100&>):
+:^:(100&>)^:_ ] 1
128
+:^:(100&>)^:_ ] 3
192
As usual, to append to the result of power, you box the noun:
+:^:(100&>)^:(<_) ] 3
3 6 12 24 48 96 192
I think the best answer to this is in Henry Rich's book J for C programmers. Specifically, it using the Power Conjunction ^: . You can also use it to converge until there is no change, so that the limit would not need to be defined. Henry uses the example that:
2 *^:(100&>#:])^:_"0 (1 3 5 7 9 11)
128 192 160 112 144 176
The ^:_ Power Conjunction repeats until there is no change and the ^:(100&>#:]) tests for the result being less than 100. If it is then ^: is applied to 1 and the loop 2* is done again, if it is not less than 100 then ^: would be applied to 0 and that results in it doing nothing and nothing changes and the loop exits. The fact that it use "0 as the rank means that it can apply the doubling function 2* to each of 1 3 5 7 9 11 individually.
Henry really does explain the process better than I, so here is the reference for further reading.
http://www.jsoftware.com/help/jforc/loopless_code_iv_irregular_o.htm#_Toc191734389

Resources