Pig - Is there a better way to format a value with 6 digits - apache-pig

I am developing a pig script and have to display the number as 6 digits eventhough the number is 4 digit.
ex: 6001 should be displayed as 006001.
Thank you.

Alternatively, you can cast it to string and append '00'.
y = foreach x generate CONCAT('00',(chararray)val1);

Related

How to process mainframe numbers where "{" is the last character

I have a one mainframe file data like as below
000000720000{
I need to parse the data and load into a hive table like below
72000
the above field is income column and "{" sign which denotes +ve amount
datatype used while creating table income decimal(11,2)
in layout.cob copybook using INCOME PIC S9(11)V99
could someone help?
The number you want is 7200000 which would be 72000.00.
The conversion you are looking for is:
Positive numbers
{ = 0
A = 1
B = 2
C = 3
D = 4
E = 5
F = 6
G = 7
H = 8
I = 9
Negative numbers (this makes the whole value negative)
} = 0
J = 1
K = 2
L = 3
M = 4
N = 5
O = 6
P = 7
Q = 8
R = 9
Let's explain why.
Based on your question the issue you are having is when packed decimal data is unpacked UNPK into character data. Basically, the PIC S9(11)V2 actually takes up 7 bytes of storage and looks like the picture below.
You'll see three lines. The top is the character representation (missing in the first picture because the hex values do not map to displayable characters) and the lines below are the hexadecimal values. Most significant digit on top and least below.
Note that in the rightmost byte the sign is stored as C which is positive, to represent a negative value you would see a D.
When it is converted to character data it will look like this
Notice the C0 which is a consequence of the unpacking to preserve the sign. Be aware that this display is on z/OS which is EBCDIC. If the file has been transferred and converted to another code-page you will see the correct character but the hex values will be different.
Here are all the combinations you will likely see for positive numbers
and here for negative numbers
To make your life easy, if you see one of the first set of characters then you can replace it with the corresponding number. If you see something from the second set then it is a negative number.

How to get the last number of a string using selenium webdriver

1 - 2 of 2
Above is my text. This is from paging of a web application. How do i extract the last number of the above text. SO i will get the count of list in that page and i can run a loop with respect to the number.
You can use substring
Let's consider your example. You have a String 1 - 2 of 2 (pagination probably)
Each of individual character is a specified index of a String
1 = 0
space = 1
- = 2
space = 3
etc.
String has a set of methods to perform various tasks. One of them is length() which gives you number of characters in your String
What you can do is to pass your length of String to substring.
Example:
myString.substring(0,1) will give you results of 1
myString.substring(0,myString.length()) wil give you results of 1 - 2 of 5
Additional info: myString.length() is an int type so you can perform math operations like + or -
myString.substring(0,myString.length()-1) will give you results of 1 - 2 of
I gave you the tools, now it's time for you to find the solutions.
You could just split the string using the spaces and then grab the last element of the split array. That should cover you even if the last number has more than one digit. Throw in a trim, just in case, to remove any leading/trailing white space.
String[] splitter = pageCount.trim().split(" ");
System.out.println(splitter[splitter.length - 1]);

Pascal- How to convert Real to Integer variable

I'm writing a task in pascal.
Everything is ok, just my result is not right.
I'm summing some numbers
Example: 2.3 + 3.4+ 3.3 = 9
But output shows: 9.000000 + EEE or something like that.
So- how to convert, to be only 9, not this REAL variable.
To actually convert:
var
i: integer;
...
i := round(floatVar);
To output only the integer part:
writeln(floatVar:9:0);
Let's consider this quite simpler equation:
3.5 + 2.5
What do you expect? 6, right? Let's try this code
write(3.5 + 2.5);
Unfortunately, it's a floating-point number, so it would produce a number represented in a scientific way:
6.00000000000E+00
or 6.0000000000 x 100, or 6 x 10o. Whatever, you only care about 6, who need this weird useless long number? So the idea is to cut off the decimal part and output to the console only the integer part, which can be done with this line of code:
write(3.5 + 2.5 : 0 : 0);
Ok, now it outputs a beautiful number as expected
6
Seems like the problem is solved, but you say that:
I'm summing some numbers
Example: 2.3 + 3.4+ 3.3 = 9
Ohh so that the evenly, beautiful integer is just randomly appeared? Here the problem comes, how do you expect this equation would output?
3.6 + 2.5
It should be 6.1, right? Let's try it with the worked line of code:
write(3.6 + 2.5 : 0 : 0);
And the output is...
6
Unexpected, right? So how about rounding to some decimal places, like 1?
write(3.5 + 2.5 : 0 : 1);
write(3.6 + 2.5 : 0 : 1);
Then, 3.5 + 2.5 = 6.0 and 3.6 + 2.5 = 6.1. But 6.0 may look quite long, so how to make it output 6 for 6.0 and 6.1 for 6.1?
Actually, you can't make the program auto-detect if a real variable contains an integer value because the way a real var is stored is completely different from an integer var (how different they are, please contact Google; but you can do it manually by making a function to do the job).
So my solution is, to be easy, making the output rounded to some decimal places, and that's it.
For purpose of showing pretty output on the screen you can use something like this:
Writeln(result:0:2);
Result on screen would be this:
9.00
What this means someone would ask? Well first number 0 means how wide filed is. if you say it's 0 then Pascal writes it at the very left side of screen. If you said writeln(result:5:2) result would be:
9.00
In other words i would print form the right side and leave 5 chars to do so.
Second number 2, in this example means you want that result printed with 2 decimal places. You can place it only if you want to print on screen value that is real, single, double, extended and so on.You can round to any number of decimals, and if you do writeln(result:0:0) you would get ouput:
9
If you are printing integer and want to have some length of field, lets sat 5 you would do: writeln(int:5). If you added :2 to the end you would get compile time error.
This all also works for something like this: writeln(5/3.5+sqrt(3):0:3),
You should know that this does not round variable itself but just formats output. This is also legal:
program test;
var
a:real;
n,m:integer;
begin
readln(a,m,n);
writeln(a:m:n);
end.
What i did here is i asked user if on how many decimals and with what length of field he wants to write entered number a. This can be useful so i'm pointing it out. Thank you for reading. I hope i helped
You can convert to string, get the int part, e convert to int number!
Or Float to Str than Str to Int:
nPage := StrToInt(FloatToStr(Int(nReg / nTPages))) + 1;

Need to trim string based on value

var a = 123456789
var b = 6
based on 'b' I need to trim 'a'. example if 'a' having 8 digits I need to trim 'a' upto 6 digits(123456). if b is 8 I need to trim upto 8 digits. Please help me
It sounds like the easiest way to do what you want is to:
Convert a to a string.
Take the left-most digits up to a maximum of b.
This is likely easier than trying to do what you ask arithmetically.
I assume you're in javascript?
var a = "123456789";
var b = 6;
var n = a.substr(0,b);

SQL - Create Unique AlphaNumeric based on a 10-digit integer stored as VARCHAR

I'm trying to emulate a function in SQL that a client has produced in Excel. In effect, they have a unique, 10-digit numeric value (VARCHAR) as the primary key in one of their enterprise database systems. Within another database, they require a unique, 5-digit alphanumeric identifier. They want that 5-digit alphanumeric value to be a representation of the 10-digit number. So what they did in excel was to split the 10-digit number into pairs, then convert each of those pairs into a hexadecimal value, then stitch them back together.
The EXCEL equation is:
=IF(VALUE(MID(A2,1,4))>0,DEC2HEX(VALUE(MID(A2,3,2)))&DEC2HEX(VALUE(MID(A2,5,2)))&DEC2HEX(VALUE(MID(A2,7,2)))&DEC2HEX(VALUE(MID(A2,9,2))),DEC2HEX(VALUE(MID(A2,5,2)))&DEC2HEX(VALUE(MID(A2,7,2)))&DEC2HEX((VALUE(MID(A2,9,2)))))
I need the SQL equivalent of this. Of course, should someone out there know a better way to accomplish their goal of "a 5-digit alphanumeric identifier" based off the 10-digit number, I'm all ears.
ADDED 8/2/2011
First of all, thank you to everyone for the replies. Nice to see folks willing to help and even enjoying it! Based on all the responses, I'm apt to tell my client they're intent is sound, only their method is off kilter. I'd also like to recommend a solution. So the challenge remains, just modified slightly:
CHALLENGE: Within SQL, take a 10 digit, unique NUMERIC string and represent it ALPHANUMERICALLY in as few characters as possible. The resulting string must also be unique.
Note that the first 3-4 characters in the 10-digit string are likely to be zeros, and that they could be stripped to shorten the resulting alphanumeric string. Not required, but perhaps helpful.
This problem is inherently impossible. You have a 10 digit numeric value that you want to convert to a 5 digit alphanumeric value. Since there are 10 numeric characters, this means that there are 10^10 = 10 000 000 000 unique values for your 10 digit number. Since there are 36 alphanumeric characters (26 letters + 10 numbers), there are 36^5 = 60 466 176 unique values for your 5 digit number. You cannot map a set of 10 billion elements into a set with around 60 million.
Now, lets take a closer look at what your client's code is doing:
So what they did in excel was to split the 10-digit number into pairs, then convert each of those pairs into a hexadecimal value, then stitch them back together.
This isn't 100% accurate. The excel code never uses the first 2 digits, but performs this operation on the remaining 8. There are two main problems with this algorithm which may not be intuitively obvious:
Two 10 digit numbers can map to the same 5 digit number. Consider the numbers 1000000117 and 1000001701. The last four digits of 1000000117 get mapped to 1 11, where the last four digits of 1000001701 get mapped to 11 1. This causes both to map to 00111.
The 5 digit number may not even end up being 5 digits! For example, 1000001616 gets mapped to 001010.
So, what is a possible solution? Well, if you don't care if that 5 digit number is unique or not, in MySQL you can use something like:
hex(<NUMERIC VALUE> % 0xFFFFF)
The log of 10^10 base 2 is 33.219280948874
> return math.log(10 ^ 10) / math.log(2)
33.219280948874
> = 2 ^ 33.21928
9999993422.9114
So, it takes 34 bits to represent this number. In hex this will take 34/4 = 8.5 characters, much more than 5.
> return math.log(10 ^ 10) / math.log(16)
8.3048202372184
The Excel macro is ignoring the first 4 (or 6) characters of the 10 character string.
You could try encoding in base 36 instead of 16. This will get you to 7 characters or less.
> return math.log(10 ^ 10) / math.log(36)
6.4254860446923
The popular base 64 encoding will get you to 6 characters
> return math.log(10 ^ 10) / math.log(64)
5.5365468248123
Even Ascii85 encoding won't get you down to 5.
> return math.log(10 ^ 10) / math.log(85)
5.1829075929158
You need base 100 to get to 5 characters
> return math.log(10 ^ 10) / math.log(100)
5
There aren't 100 printable ASCII characters, so this is not going to work, as zkhr explained as well, unless you're willing to go beyond ASCII.
I found your question interesting (although I don't claim to know the answer) - I googled a bit for you out of interest and found this which may help you http://dpatrickcaldwell.blogspot.com/2009/05/converting-decimal-to-hexadecimal-with.html