I have following tuple
{{
'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},
mobile_no,<<"9930050224">>,
email,<<"prakhar#bwa.io">>,
name,<<"PT">>,
user_role,<<"broker">>,
user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>
}}
In form of =>
{{
key1, value1
key2, value2....
}}
Can a simple function call sort on basis of keys as under without parentheses?:
{{
'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},
email,<<"prakhar#bwa.io">>,
mobile_no,<<"9930050224">>,
name,<<"PT">>,
user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>,
user_role,<<"broker">>
}}
Can you define a simple function to sort the all parameters in {key, value} based on key parameters, but there are no parenthesis around each key, value
I won't comment about why you need this function, though I agree with "#I GIVE TERRIBLE ADVICE" and #Hynek. Here is a solution to your question:
1> Ut = {{'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},mobile_no,
<<"9930050224">>,email,<<"prakhar#bwa.io">>,name,<<"PT">>,user_role,<<"broker">>,user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>}}.
{{'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},
mobile_no,<<"9930050224">>,email,<<"prakhar#bwa.io">>,name,
<<"PT">>,user_role,<<"broker">>,user_id,
<<"fp85od1zv5x4jddkens6648z5bc9jroj">>}}
2> Group2 = fun Group2([],R) -> R; Group2([A,B|T],R) -> Group2(T,[{A,B}|R]) end.
#Fun<erl_eval.36.54118792>
3> Group = fun(L) -> Group2(L,[]) end.
#Fun<erl_eval.6.54118792>
4> F = fun(In) -> {X} = In, list_to_tuple(lists:sort(Group(tuple_to_list(X)))) end.
#Fun<erl_eval.6.54118792>
5> F(Ut).
{{'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>}},
{email,<<"prakhar#bwa.io">>},
{mobile_no,<<"9930050224">>},
{name,<<"PT">>},
{user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>},
{user_role,<<"broker">>}}
6>
Shlok, you're fighting an uphill battle working directly with raw BSON tuples. Use the BSON library API to access the data that they contain:
2> RawDoc.
{'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},
email,<<"xxxxyyyy#bwa.io">>,mobile_no,<<"0000022222">>,name,
<<"PT">>,user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>,
user_role,<<"broker">>}
3> bson:at(email, RawDoc).
<<"xxxxyyyy#bwa.io">>
5> Key = fun(Key, Doc) -> {Key, bson:at(Key, Doc} end.
7> {Key(user_id, RawDoc), Key(user_role,RawDoc)}.
{{user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>},
{user_role,<<"broker">>}}
Ideally, you should write a function to convert there BSON tuples to the Erlang #record{} you're using to model your data, end of story.
If you assume you'll be getting BSON objects with a variable number of keys, and you want to sort them 'just in case', you're going to have a bad time in the long run.
P.S. Don't post your users' real data online ;)
Related
I think I'm close to what I want, though I suspect I'm not understanding how thaw / TH Region works.
Here is what I'm trying to implement (at least roughly)
modifyPerIndex :: forall t a. Foldable t => t (Tuple Int (a -> a)) -> Array a -> Array a
modifyPerIndex foldableActions array = run do
mutableArray <- thaw array
let actions = fromFoldable foldableActions
foreach actions (\(Tuple index action) -> modify index action mutableArray)
freeze mutableArray
This is sort of how I imagine updateAtIndices works. I suppose I could write modifyPerIndex to use updateAtIndices by reading in the values, applying the (a -> a) and mapping the result into a list of Tuples to be sent to updateAtIndices.
I'm curious how to do it this way though.
In the code above modify returns ST h Boolean, which I'd like to change into ST h Unit. That's where I'm lost. I get that h here is a constraint put on mutable data to stop it from leaving run, what I don't understand is how to use that.
There are a few options. But it has nothing to do with h. You don't have to "use" it for anything, and you don't have to worry about it at all.
First, the most dumb and straightforward approach - just bind the result to an ignored variable and then separately return unit:
foreach actions \(Tuple index action) -> do
_ <- modify index action mutableArray
pure unit
Alternatively, you can use void, which does more or less the same thing under the hood:
foreach actions \(Tuple index action) -> void $ modify index action mutableArray
But I would go straight for for_, which is the same as foreach, but works for any monad (not just ST) and ignores individual iterations' return values:
for_ actions \(Tuple index action) -> modify index action mutableArray
I am having a couple of issues to put this in a functional format.
select from tableName where i=fby[(last;i);([]column_one;column_two)]
This is what I got:
?[tableName;fby;enlist(=;`i;(enlist;last;`i);(+:;(!;enlist`column_one`column_two;(enlist;`column_one;`column_two))));0b;()]
but I get a type error.
Any suggestions?
Consider using the following function, adjust from the buildQuery function given in the whitepaper on Parse Trees. This is a pretty useful tool for quickly developing in q, this version is an improvement on that given in the linked whitepaper, having been extended to handle updates by reference (i.e., update x:3 from `tab)
\c 30 200
tidy:{ssr/[;("\"~~";"~~\"");("";"")] $[","=first x;1_x;x]};
strBrk:{y,(";" sv x),z};
//replace k representation with equivalent q keyword
kreplace:{[x] $[`=qval:.q?x;x;"~~",string[qval],"~~"]};
funcK:{$[0=t:type x;.z.s each x;t<100h;x;kreplace x]};
//replace eg ,`FD`ABC`DEF with "enlist`FD`ABC`DEF"
ereplace:{"~~enlist",(.Q.s1 first x),"~~"};
ereptest:{((0=type x) & (1=count x) & (11=type first x)) | ((11=type x)&(1=count x))};
funcEn:{$[ereptest x;ereplace x;0=type x;.z.s each x;x]};
basic:{tidy .Q.s1 funcK funcEn x};
addbraks:{"(",x,")"};
//where clause needs to be a list of where clauses, so if only one whereclause need to enlist.
stringify:{$[(0=type x) & 1=count x;"enlist ";""],basic x};
//if a dictionary apply to both, keys and values
ab:{$[(0=count x) | -1=type x;.Q.s1 x;99=type x;(addbraks stringify key x),"!",stringify value x;stringify x]};
inner:{[x]
idxs:2 3 4 5 6 inter ainds:til count x;
x:#[x;idxs;'[ab;eval]];
if[6 in idxs;x[6]:ssr/[;("hopen";"hclose");("iasc";"idesc")] x[6]];
//for select statements within select statements
//This line has been adjusted
x[1]:$[-11=type x 1;x 1;$[11h=type x 1;[idxs,:1;"`",string first x 1];[idxs,:1;.z.s x 1]]];
x:#[x;ainds except idxs;string];
x[0],strBrk[1_x;"[";"]"]
};
buildSelect:{[x]
inner parse x
};
We can use this to create the functional query that will work
q)n:1000
q)tab:([]sym:n?`3;col1:n?100.0;col2:n?10.0)
q)buildSelect "select from tab where i=fby[(last;i);([]col1;col2)]"
"?[tab;enlist (=;`i;(fby;(enlist;last;`i);(flip;(lsq;enlist`col1`col2;(enlist;`col1;`col2)))));0b;()]"
So we have the following as the functional form
?[tab;enlist (=;`i;(fby;(enlist;last;`i);(flip;(lsq;enlist`col1`col2;(enlist;`col1;`col2)))));0b;()]
// Applying this
q)?[tab;enlist (=;`i;(fby;(enlist;last;`i);(flip;(lsq;enlist`col1`col2;(enlist;`col1;`col2)))));0b;()]
sym col1 col2
----------------------
bah 18.70281 3.927524
jjb 35.95293 5.170911
ihm 48.09078 5.159796
...
Glad you were able to fix your problem with converting your query to functional form.
Generally it is the case that when you use parse with a fby in your statement, q will convert this function into its k definition. Usually you should just be able to replace this k code with the q function itself (i.e. change (k){stuff} to fby) and this should run properly when turning the query into functional form.
Additionally, if you check out https://code.kx.com/v2/wp/parse-trees/ it goes into more detail about parse trees and functional form. Additionally, it contains a script called buildQuery which will return the functional form of the query of interest as a string which can be quite handy and save time when a functional form is complex.
I actually got it myself ->
?[tableName;((=;`i;(fby;(enlist;last;`i);(+:;(!;enlist`column_one`column_two;(enlist;`column_one;`column_two)))));(in;`venue;enlist`venueone`venuetwo));0b;()]
The issues was a () missing from the statement. Works fine now.
**if someone wants to add a more detailed explanation on how manual parse trees are built and how the generic (k){} function can be replaced with the actual function in q feel free to add your answer and I'll accept and upvote it
I have been playing with Pony arrays to understand Pony better, and wanted to write the map function for any arrays.
I am talking about something like the standard map function most languages have nowadays for converting elements of collections, as in Clojure:
(map #(+ 1 %) [1 2 3]) ; => [2 3 4]
But I want it to actually modify the given array, not return a new one.
My current attempt so far runs into many errors due to capabilities:
// array is "iso" so I can give it to another actor and change it
let my_array: Array[U64] iso = [1; 2; 3; 4]
// other actor tries to recover arrays as "box" just to call pairs() on it
let a = recover box my_array end // ERROR: can't recover to this capability
for (i, item) in a.pairs() do
// TODO set item at i to some other mapped value
try my_array.update(i, fun(item))? end
end
Anyone knows how this can be done
Alright, took me a while, but I was able to get things working.
Here's my basic understanding of what's going on (please correct me if I'm wrong)!
The first step was to understand that we need to use aliases to change the capabilities of a variable in Pony.
So, in order to make an iso variable useable as a box, one must alias it by basically, consuming it into another variable:
let a: Array[U64] ref = consume array // array is "iso"
for (i, item) in a.pairs() do
try a.update(i, item + n)? end
end
This works!!
One more problem I had was that I couldn't do much with the resulting Array[U64] ref. Can't pass it to anyone, for example.
So I wrapped the whole thing into a recover block in order to end up with the same array, but as a val (immutable reference to the array) which is more useful as I can send it to other actors:
let result = recover val
let a: Array[U64] ref = consume array
for (i, item) in a.pairs() do
try a.update(i, item + n)? end
end
a
end
Now I can send result to anyone!
I'm using swi-prolog 7.3.31.
I have a compound term question of the form:
question(q_(Question),y_(Yes),n_(No))
where Yes and No can be either an atom or an other compound term question and so on.
I'm using using a form with reply_html_page where I display the text of the question Question and where I have two submit buttons one for 'yes' and one for 'no'.
Here is a sample of my form for the 'yes' button:
form([class = 'form-inline ',
action = '/choice_handler',
method = 'POST'], [
input([name = choice,
id = choice,
type = hidden,
class = 'form-control',
value = 'yes']),
input([name = question,
type = hidden,
value = Yes ]),
button([class = 'btn btn-default yes',
type = submit], ['yes']) ])
Here is my issue, I want to pass the value of Yes in order to recursively display a new question or the final result, however I fail to do so because the value of the input form must be an atom and not a coupound term.
Hence the question: is there any way to pass the compound term to the handler?
Note that an atom is often enough when exchanging data, because you can use atom_to_term/3 to convert an atom to a compound term:
atom_to_term(+Atom, -Term, -Bindings)
Use Atom as input to read_term/2 using the option variable_names and return the read term in Term and the variable bindings in Bindings. Bindings is a list of Name = Var couples, thus providing access to the actual variable names. See also read_term/2. If Atom has no valid syntax, a syntax_error exception is raised. New code should use read_term_from_atom/3.
Example:
?- atom_to_term('the(f(X,Y),Z)', Term, Bindings).
Term = the(f(_1596, _1598), _1604),
Bindings = ['X'=_1596, 'Y'=_1598, 'Z'=_1604].
Thus, you can simply take the atom and recover the compound term, under suitably general assumptions.
I am doing a small script to get SNMP traps with PySnmp.
I am able to get the oid = value pairs, but the value is too long with a small information in the end. How can I access the octectstring only which comes in the end of the value. Is there a way other than string manipulations? Please comment.
OID =_BindValue(componentType=NamedTypes(NamedType('value', ObjectSyntax------------------------------------------------(DELETED)-----------------(None, OctetString(b'New Alarm'))))
Is it possible to get the output like the following, as is available from another SNMP client:
.iso.org.dod.internet.private.enterprises.xxxx.1.1.2.2.14: CM_DAS Alarm Traps:
Edit - the codes are :
**for oid, val in varBinds:
print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
target.write(str(val))**
On screen, it shows short, but on file, the val is so long.
Usage of target.write( str(val[0][1][2])) does not work for all (program stops with error), but the 1st oid(time tick) gets it fine.
How can I get the value from tail as the actual value is found there for all oids.
Thanks.
SNMP transfers information in form of a sequence of OID-value pairs called variable-bindings:
variable_bindings = [[oid1, value1], [oid2, value2], ...]
Once you get the variable-bindings sequence from SNMP PDU, to access value1, for example, you might do:
variable_binding1 = variable_bindings[0]
value1 = variable_binding1[1]
To access the tail part of value1 (assuming it's a string) you could simply subscribe it:
tail_of_value1 = value1[-10:]
I guess in your question you operate on a single variable_binding, not a sequence of them.
If you want pysnmp to translate oid-value pair into a human-friendly representation (of MIB object name, MIB object value), you'd have to pass original OID-value pair to the ObjectType class and run it through MIB resolver as explained in the documentation.
Thanks...
the following codes works like somwwhat I was looking for.
if str(oid)=="1.3.6.1.2.1.1.3.0":
target.write(" = str(val[0][1]['timeticks-value']) = " +str(val[0][1]['timeticks-value'])) # time ticks
else:
target.write("= val[0][0]['string-value']= " + str(val[0][0]['string-value']))