What is the difference between nulltypes :: and 0n in KDB? - kdb

Both of these appear to be null types, but seem to behave differently.
For example, if instantiate a dictionary with
`a`b!(0n 0n)
I'm unable to upsert integers, where as I can if i do:
`a`b!(:: ::)
I can. What is the difference between 0n and ::?

0N actually defaults to 0Nj. Same way if you define non-float numbers they will also be long. 0N is not equivalent to :: because of this.
If you want the values of your dictionary to be integers, you would need to define it as such: `a`b!0N 0Ni (or keep it as generic null with the identity)

Related

append item to dictionary list, kdb

I have a dictionary
q).test.dict:(`test1;`test2)!(1i;2i)
q).test.dict
test1| 1
test2| 2
and I need to append an item to one of the dictionary lists to get the following result:
q).test.dict
test1| 1
test2| 2 4i
However I am having trouble assigning to that dictionary list.
I have tried the following:
q).test.dict[`test2]:.test.dict[`test2],4i
'type
[0] .test.dict[`test2]:.test.dict[`test2],4i
And have tried other methods of assignment which also result in a type error.
I feel like im missing something quiet obvious here but cant seem to put my finger on it.
The issue is that you've initiated/defined the dictionary to have a uniform value (integer atoms) and so kdb expects/enforces the values to remain integer atoms. You can avoid this by creating a default entry (with say generic null ::) to force the value to be a mixed list. Then you can append
.test.dict:(`;`test1;`test2)!(::;1i;2i)
If you instead define your dictionary like this
.test.dict:(`test1;`test2)!(enlist 1i;enlist 2i)
It will work. The problem is, the value of your dictionary is a list of integers, not a list of lists of integers.

Specman e: Is there a way to know how many values there is in an enumerated type?

I need to know how many values there is in an enumerated type in my verification environment. E.g.:
type my_type: [a, b, c, d];
I there a way to check on the fly that there 4 different values in the my_type?
Thank you for your help
There's an all_values(...) pseudo-routine that returns all possible values of a scalar type. You can use this to get the number of enum literals:
assert all_values(my_type).size() == 4;
Besides what Tudor suggested, another way is to use set_of_values() pseudo-routine that returns a set (rather than a list) of all values:
set_of_values(my_type).uint_size()
In a way, using set_of_values() is better because all_values() creates a new list, which usually consumes more memory than a set.
uint_size() returns the size of the set as uint. There is also size() but it returns int(bits: *), so it's good enough to use uint_size() in this case, because there can never be more than MAX_UINT items in an enumerated type.
also - set_of_values() return 'set', which you can inquire for the type smallest/largest value, and its range.
For example:
var x := set_of_values(my_type).uint_max();
keep y == set_of_values(my_type).uint_max().as_a(my_type).as_a(my_type);
print set_of_values(my_type).uint_min().as_a(my_type);

Obfuscate decimal(6,2) number using T-SQL

How can I effectively obfuscate numbers from range 0.00 ~ 9999.99 like
11.68
6.84
7.99
7.00
so that small difference in values of similarily-sized numbers is not immediately visible?
I thought about splitting each number into integer and decimal part and use them as coordinates (e.g. 11.68 → (11, 68)) and converting them to polar coords, which is nice, but I still need two values to store them.
Do you know some nice tranformation of decimal(6,2) into another single number (can be like float or even int) and back which relies only on T-SQL math functions?
I would like to add one more barrier between values and people who have full database acceess and can be tempted to analyze true (unobfuscated) values they see, but are relatively lazy to learn T-SQL and study how "nonsense values" they see after obfuscation, can be decoded.
Use ENCRYPTBYPASSPHRASE() and DECRYPTBYPASSPHRASE()
Suitable methods are already present since SQL Server 2008. Their purpose is encryption, but well, with locally stored passphrase it's merely just an obfuscation :) (Anyway, at the moment this is what was expected in the question.)
DECLARE #Value decimal(6,2) = 7.99;
DECLARE #Passphrase varchar(4) = 'abcd';
-- obfuscation
DECLARE #Obf varbinary(50) = ENCRYPTBYPASSPHRASE(#Passphrase, CAST(#Value AS varchar(20)));
-- deobfuscation
SELECT CAST(CAST(DECRYPTBYPASSPHRASE(#Passphrase, #Obf) AS varchar(20)) AS decimal(6,2))
Value obfuscated this way can be also held in varchar/nvarchar data type.

IEC61131-3 directly represented variables: data width and datatype

Directly represented variables (DRV) in IEC61131-3 languages include in their "addresses" a data-width specifier: X for 1 bit, B for byte, W for word, D for dword, etc.
Furthermore, when a DRV is declared, a IEC data type is specified, as any variable (BYTE, WORD, INT, REAL...).
I'm not sure about how these things are related. Are they orthogonal or not? Can one define a REAL variable with a W (byte) address? What would be the expected result?
A book says:
Assigning a data type to a flag or I/O address enables the programming
system to check whether the variable is being accessed correctly. For
example, a variable declared by AT %QD3 : DINT; cannot be
inadvertently accessed with UINT or REAL.
which does not make things clearer for me. Take for example this fragment (recall that W means Word, i.e., 16 bits - and both DINT and REAL correspond to 32 bits)
X AT %MW3 : DINT;
Y AT %MD4.1 : DINT;
Z AT %MD4.1 : REAL;
The first line maps a 32-bits IEC var to a 16-bits location. Is this legal? would the write/read be equivalent to a "cast" or what?
The other lines declare two 32-bits IEC variables of different type that points to the same address (I guess this should be legal). What is the expected result when reading or writing?
Like everything in PLC world, its all vendor and model specific, unfortunately.
Siemens compiler would not let you declare Real address with bit component like MD4.1, it allowed only MD4 and data length had to be double word, MB4 was not allowed.
Reading would not be equivalent to cast. For example you declare MW2 as integer and copy some value there. PLC stores integer as, lets say in twos complement format. Later in program you read MD2 as real. The PLC does not try to convert integer to real, it just blindly reads the bytes and treats it as real regardless what was saved there or what was declared there. There was no automatic casting.
This is how things worked in Siemens S7 plc-s. But you have to be very careful since each vendor does things its own way.

How to hash fixed size string plus one integer

I have a simple struct consists of a fixed size string and an integer. I need to use this struct as the key for a hash table. I have a hash function for sting, Hs(string), and a hash function for integer, Hi(int), I'm wondering if the hash function for this simple struct would just be H(struct) = Hs(string) + Hi(int)? Alternatively, I could encode the integer into a string and append it to the string, then just use the string hash function. Any suggestions?
Thanks.
In order to figure the "how" we need to answer a few questions first:
a) how many items you should be able to accommodate ?
b) what's the size of the hash table ?
c) how many combinations of <string X int> are there (since the string has a fixed size it's easy to calculate) ?
Once you figure that out - it will be easier to find a hashing function that will minimize collisions, for example, there might be a case where using Hs(string) is good enough!
Either of those would work. My default would be Hs(string) XOR Hs(int) but plus is fine too. It just needs to probably not collide and both of those will probably not collide although Hs(string) XOR Hs(int) or Hs(string) + Hs(int) will be faster.