Reputation: 615
Trying to understand what this function does:
yr:{ yr:.z.T+1000*x; -1 string .z.Z; while[(.z.T < yr); ZZ,::.z.Z]}
I understand .z.Z gets the datetime, and that execution is from right to left. what is ZZ? What is .z.T?
Essentially, what does the line accomplish?
Upvotes: 1
Views: 369
Reputation: 3969
What This Function is doing:
This function accepts one parameter(should be int) and add those many seconds to current time(lets say it future time). Then it starts a loop from current time to future time and in every iteration, append current date and time to global list(referred by variable ZZ).
How to Call: yr[2]
Explanation:
yr:.z.T+1000*x
.z.T
give you current local time.
1000 is equivalent to 1 seconds. So it is adding x seconds to current time and storing it in variable yr. ( :
means assignment (=))
ZZ,::.z.Z
::
is used to assign something to global variable. So ZZ
is a
global variable which is list (like array).
,
is used to append. Above statement is equivalent to ZZ : ZZ , .z.Z
.z.Z
gives current local date and time.
while[(.z.T < yr);...]
This is a condition for the loop. So it takes the current time(.z.T
)
and check whether it is lesser than future time that was calculated
in first statement.
Loop will end once current time =yr(future time).
ZZ
.Upvotes: 0
Reputation: 1919
There is a nicer rewrite of this to make it much more idiomatic. It takes advantage of the overload of \
to iterate. Check out http://code.kx.com/q/ref/adverbs/#converge-iterate
The current function you have, takes the current time (.z.T
) and adds x
number of seconds (it multiplies by 1000 to make it milliseconds). This becomes your bound, and then as long as the current time is less than that, you append .z.Z
(the datetime marker) to a global list ZZ
.
The version below will do the same with a couple advantages:you avoid using a global and you write more idiomatic code
f2:{{.z.Z}\[{y; .z.T<x}.z.T+1e3*x; .z.Z]}
While your condition {y; .z.T<x}.z.T+1e3*x
is true, your loop will continue to iterate. Note that we make sure to pass in the time limit from outside, so that it is not revaluated it each time, additionally we need a dummy parameter y
, as it will try to apply this condition to the result of our iteration, but we don't really want that, since that is .z.Z
. Each time it iterates it will evaluate .z.Z
returning the datetime. Since you are using \
and not /
you will get the entire list generated.
q)f2:{{.z.Z}\[{y; .z.T<x}.z.T+1e3*x; .z.Z]}
q)f2 1
2014.04.30T17:40:23.357 2014.04.30T17:40:23.357 .......
That being said, if you're looking to generate a sequence of datetime values, from now to now+x, this is not the best way to do that, since your .z.Z
stamp will reflect the time it takes your machine to actually evaluate that.
CORRECTION:
I did not correctly explain the reason our condition testing lambda is {y; .z.T<x}.z.T+1e3*x
. You want to make sure your .z.T+1e3*x
is only evaluated at the start, so you do not want your bound to be inside the function. Additionally, if you were to leave out the y
param, then {z.T<x}.z.T+1e3*x
would immediately evaluate to false, and your iteration would return a type
error as it tries to apply your iteration result to 0b
at each cycle of the loop. By keeping y
and just not using it, we make sure to delay this evaluation and create a lambda that correctly tests our bound.
Upvotes: 1
Reputation: 1230
.z.T
is the current time in the time
datatype; the underlying number in time
s is milliseconds since midnight, so adding 1000*x
gives a time x
seconds in the future.
-1 string .z.Z
prints the current datetime
to stdout
.
while[(.z.T < yr); ..]
loops as long as the current time is less than yr
(x
seconds in the future).
ZZ,::.z.Z
appends the current datetime
to a global variable named ZZ
.
some additional notes:
the datetime
datatype is in general deprecated in favor of timestamp
.
the parentheses around the test condition are redundant.
the second :
is also redundant, but for more interesting reasons: ,:
(like all of the two-argument "writeback" functions (x+:1
, y-:2
, etc.)) always modifies either a global or a local variable, depending on whether a local of that name exists in the function.
proof:
q)delete from`.;
q){ZZ:(); yr:.z.T+1000*x; -1 string .z.Z; while[(.z.T < yr); ZZ,::.z.Z]}1
2014.04.30T18:26:24.592
q)ZZ
'ZZ
q)
the ZZ
being modified inside the while loop in that version of the function was the local variable declared in the first statement, not a global one as one might assume given the presence of a ::
in the modification statement.
anyway, if you want to do it like this, it should at the very least be rewritten to yr:{ yr:.z.T+1000*x; -1 string .z.Z; while[.z.T < yr; ZZ,:.z.Z]}
.
Upvotes: 1
Reputation: 2615
e.g.
q)f:{ZZ,::2}
q)f[]
q)ZZ
,2
q)f[]
q)ZZ
2 2
.z.T is the time.
Upvotes: 1