q/kdb - hitting 'constants error when adding new key-value assignments to a dictionary within a function - constants

I am currently working on a script where within a function, key-value pairs are being added to a dictionary x - consider x as a single dictionary of different inputs used to query data, and different key-values are appended to this depending on certain conditions being fulfilled.
However, when I load in the script into my session with some new assignment logic added, I am hitting a 'constants error. This is despite all assignments being kept to this dictionary x. When these two new assignments within x are commented out, the script will load in successfully.
I know the 'constants error usually refers to the max number of constants within a certain scope being exceeded, but surely this shouldn't be happening when all assignment is happening within this dictionary x. Is there a way to get around this? What is causing this issue?

I think you are trying to do too much in one function. I think you are indexing or assigning values to the dictionary with too many constants. Below code will return the constants error:
dict:(10 + til 100)!til 100
value (raze -1_"{","dict[",/:(string[10+til 97],\:"];")),"}"
// with til 96
{dict[10];dict[11] ... dict[104]}
It's the code that is indexing the dictionary is causing the issue rather than the dictionary itself.

Related

kdb - checking dictionary variables for data vs. lambdas

All,
I have numerous nested dictionaries that I've been building and updating on the fly which can be combination of variables and lambdas functions. My initial inputs are constants and incremental data varies but are mostly derivatives using lambdas and function references.
I keep running a type issues as I pass constants and lambdas into my functions and my functions break. The solution at present is to simply wrap all my constants and data as simple f(x)s but I'd like to handle that inside my functions instead of wrapping everything.
In my example below, I'd like to add a conditional or something to QAQC the variable so I can handle it inside each function.
.inv.1.startDate: 2022.10.10 is a constant then my function breaks at sd: d[`startDate][] (which make sense as its not a function) but will work if .inv.1.startDate: {2022.10.10}
I tried a conditional below but it fails as not all dictionary values are f(x) either.
sd: ?[(type d[`startDate]=100h;d[`startDate][];d[`startDate])] ; which doesn't seem to work either.
Example of incremental references to render an array of series of dates
.inv.1.startDate:2022.10.10; //<---- works as f(x) but not when a constant
.inv.1.duration: 155;
.inv.1.iDate:{dateArray[.inv;1]};
.inv.2.startDate: {last (.inv.1.iDate[])};
.inv.2.duration: 250;
.inv.2.iDate:{dateArray[.inv;2]};
.inv.3.startDate: {last (.inv.2.iDate[])};
.inv.3.duration: 95;
.inv.3.iDate:{dateArray[.inv;3]};
dateArray:{[seg;segNum];
d: seg[`$string segNum];
sd: d[`startDate][]; //this can be a constant or a f(x) depending on when its called)
days: d[`duration]; // this could be a constant or a f(x) as well
result: sd+ til days
};
//attempt to emply a conditional but fails due to data type
sd: ?[(type d[`startDate]=100h;d[`startDate][];d[`startDate])] ;
FWIW- this is an expansion upon
kdb - nested functions within nested dictionaries
It looks like you are using ? in cases where $ is more applicable https://code.kx.com/q/ref/cond/
Also there is an order of evaluation issue with:
type d[`startDate]=100h
https://code.kx.com/q4m3/4_Operators/#412-left-of-right-evaluation
What you want is:
(type d[`startDate])=100h
Or more cleanly:
100h = type d[`startDate]
An alternative is to wrap your processing in a try-catch:
sd:{#[x;`;x]}d`startDate;
but as I mentioned in an earlier comment, personally I think it would be cleaner to have the constants in a lambda, e.g. .inv.1.startDate:{2022.10.10}

Trouble Understanding Xcodemath error messages

I have been working to understand why I am getting the error messages shown in the attachment.
The bottom-most message that indicates a comma is needed makes no sense to me at all.
The other two messages may well be related to a problem with data types, but I cannot determine what data type rules I have violated.
Many thanks for your time and attention.
It's a few different errors cropping up, and the error about the separator is not really indicative of the problem.
SecondPartFraction is being declared twice. If those are meant to be two different variables, they should have two different names. If you simply wish to reassign a new value to SecondPartFraction, just drop the var off the second time you use it (as is has already been declared, you simply need to refer to it again).
Doubles and Ints can't be together for division, so that error is correct. If you want to get a Double result, just change the 16 to 16.0. Then the compiler won't complain.
The numbers you're getting are originating from a textfield too, which might cause some problems. If the user enters text into your textfields, instead of numbers, the app will crash since StepFirstPart and StepSecondPart are force unwrapped. You will probably want to do some kind of Optional Chaining to handle the case where the entry is not numeric.
In the last line, the label text is being set to an Int - in order to do this, you'll have to use string interpolation instead, since the text for a label must be a string rather than a number:
TotalNumRisers.text = "\(TotalRisers)"
Just one last quick note - in Swift, camel casing is standard for naming, so the first letter of every variable should be lowercase, then the others upper. So StepFirstPart would become stepFirstPart instead.
You create the same variable twice here e.x
var x = 0
var x = value + x
instead it should be
var x = 0
x = value + x // remove var from here

`[~,ui] = Unique(Day)` what is this doing?

When looking at Matlab code I have stumbled upon the following line of code:
[~,ui] = Unique(Day)
(Where Day is the vector containing a numeric value of day like so: 1,2,3, etc.)
What is it doing? I have noticed that it creates some kind of unique identifiers for the numeric value of the day (i.e. for 1 to 31) as well as a variable called Volume. What is Volume?
[~,ui] = Unique(Day) evaluates the function Unique with input argument Day.
This function has 2 outputs, and if you want to use both, you would write
[a,b]=Unique(Day). However, if you need only second output, you can put ~ instead of the first argument. So, your first output will not be saved.
It is impossible to answer, what Volume means, because you didn't provide the code of the function Unique.

How MATLAB's "if" function handles multiple inputs

I ran a quick test to see how if deals with multiple input values. It appears that the default behavior is to apply and to the collection of values, but I couldn't find any documentation. Can anyone confirm or provide a counterexample?
>> if([1,1,1]) disp(sprintf('hi'));end;
hi
>> if([1]) disp(sprintf('hi'));end;
hi
>> if([1,1,0]) disp(sprintf('hi'));end;
EDIT: to clarify, I don't intend to try to use this "feature," but wanted to be sure I knew how erroneous input would be handled. Suppose, for example, your code read
if(my_function) and the (badly written) my_function usually returns a single value but occasionally returns multiple values. Good practice, of course , would parse the returned values appropriately and feed a single value to if.
I don't find any practical reason to create an if statement which depends on anything but a scalar.
Regarding what's done in MATLAB practically?
You may assume MATLAB applies the function all on the input of the if statement.
This will hold as intuition given the array is non empty.
For example, if we have array - array4Example which is not empty, the statement if on the array - if(array4Example) is equivalent of the statement if on the scalar - if(all(array4Example(:))).
This matches the documentation if the if function.

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.