How to get a particular value from a map - stack

In my contract I have a map with a principal as its key and a tuple as its value. I want to get a particular value from the value-tuple for every principal in the map.
Let's say I want to get the salary for every member from the map below.
(define-map members principal {position: (string-ascii 30), salary: uint})

You need to use map-get
Check this examples
;; A map that creates a principal => uint relation.
(define-map balances principal uint)
;; Set the "balance" of the tx-sender to u500.
(map-set balances tx-sender u500)
;; Retrieve the balance.
(print (map-get? balances tx-sender))
Or
(define-map orders uint {maker: principal, amount: uint})
;; Set two orders.
(map-set orders u0 {maker: tx-sender, amount: u50})
(map-set orders u1 {maker: tx-sender, amount: u120})
;; retrieve order with ID u1.
(print (map-get? orders u1))

You can use Clarity's get function in conjunction with map-get:
Example:
(define-map members principal {position: (string-ascii 30), salary: uint})
(map-set members 'ST3QFME3CANQFQNR86TYVKQYCFT7QX4PRXM1V9W6H {position: "test", salary: u500})
(print (get salary (map-get? members 'ST3QFME3CANQFQNR86TYVKQYCFT7QX4PRXM1V9W6H)))
And a link to Clarity's get function demonstrating this usage: https://docs.stacks.co/docs/write-smart-contracts/clarity-language/language-functions#get
However, you can't iterate through a map, you need to know the key to look up data, so if you wanted to iterate, you would need a list of all the principals and iterate through that using the map function, looking up the corresponding principal in the map on each iteration.

Related

Neo4j query takes an eternity to execute

My code takes an eternity to compute jaccard similarity. It is an .csv file with 100000 in it. I have already created indexes on 2 basic Nodes (id+ value)
I have already use the Jaccard algorithm in Playground but it also takes an eternity to run.
MATCH (i:Item)-[:HAS]->(p2:Properties)<-[:HAS]-(i1:Item)
WITH {item:id(i), categories: collect(id(i1))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard.stream(data, {similarityCutoff: 0.5})
YIELD item1, item2, count1, count2, intersection, similarity
RETURN algo.asNode(item1).id AS from, algo.asNode(item2).id AS to, intersection, similarity
Can anyone help?
The first two lines syntax of your query is not correct. You should run it like this:
OLD:
MATCH (i:Item)-[:HAS]->(p2:Properties)<-[:HAS]-(i1:Item)
WITH {item:id(i), categories: collect(id(i1))} as userData
NEW:
MATCH (i:Item)-[:HAS]->(p2:Properties)
WITH {item:id(i), categories: collect(id(p2))} as userData
This is what the algorithm (jaccard ) is doing. An item (say Item1) is similar (number from 0 to 1 inclusive) to another item (like Item2) if both shares the same properties. For example; Item1 has 3 properties1,2,3 and Item2 has 3 properties2,3,4. So the jaccard similarity index is 2/4 or 0.5 because property2,3 are common and there are 4 unique properties in both items.
So in your query, you only need to specify that an item (like item1) has some properties and you don't need to specify another item (like item2) has some properties. The function will iterate all items and will give you the jaccard index, that is, item1 vs item2, item1 vs item3..., item2 vs item3, so on...This is the syntax for algo.similarity.jaccard.stream.
See reference here: https://neo4j.com/docs/graph-algorithms/current/labs-algorithms/jaccard/

Reordering text in DOORS layout column using DXL

I have seen this question asked for numbers, but my layout column consists of strings of text. There is no inherent order to the strings and the possible values for the attribute connected to an object could be, for example "apple", "orange", "banana", or "kiwi". The column I want looks for in-links from another module and each in-link can have multiple values for the attribute in question. Ultimately I want the values to be ordered "orange", "banana", "kiwi", "apple" depending on what values each linked objects have. For example, if the linked object contains all 4 then you would get the list of the full order. If it only has banana and apple you would return the value for the column "banana" , "kiwi". Sorry I don't have a code sample. At this point it would just be the stock layout column DXL though. Thanks for any help.
If your real world is really as simple as your example, it might be sufficient to just have a combination of if statement s, like (pseudocode)
if linked_values contains "orange"
display "orange\n"
if linked_values contains "banana"
display "banana\n"
and you have a nice, sorted list of values.
If not, you need real sorting.
Sorting in DXL is usually done using skip lists. When you iterate over a skip list, you get the values in the order of the sorted keys (note that keys are unique, there cannot be two objects with the same key in a skip list).
So, it would be your task to create a mapping that for each entry to be stored calculates a key that represents the correct order and a temporary skip list.
If I understand your example correctly, you would have a mapping
orange: a
banana: b
kiwi: c
apple: d
Let's assume that there may be multiple oranges per object and you want to list all of them, because you do not only want to display the fruit but also some attribute like size or quality. In this case, you would create sort keys like this:
Object 1 has linked objects with the values: first apple (big), second apple (small), kiwi (medium), third apple (big), orange. This would make the following skip list:
key: d001, value: apple (big)
key: d002, value: apple (small)
key: c003, value: kiwi (medium)
key: d004, value: apple (big)
key: a005, value: orange
If you want to sort first by fruit, then by size, and you code your sizes by a: big, b: medium, c: small, d: undefined, you would have keys like:
da001
dc002
cb003
da004
ad005

SSRS: Adding a filter that returns information from entire group

I am trying to create a report in SSRS. Below is a small example of what my dataset looks like.
Example Data Set
So, there are three different stores (A,B,C) and each has a landlord (a,b,c). Landlords can pay via three different methods (1,2,3) and the amounts paid per method are shown.
Right now, I have two filters set up. The first is by Store and the second is by Landlord.
What I am having trouble with is:
How can I set up a filter by the Amount that will return information from an entire Store/Landlord?
So for example, if I wanted to filter Amount by 150, I would like to return all the "payment" information for the store(s) that have a payment of 150. Such as the following:
Desired Result
Is it possible to add a filter to return information from the entire group? (Store and Landlord are the group in this case)
I am new to SSRS so any help/insight would be greatly appreciated!
You can use LookUpSet to locate the matching groups, JOIN to put the results in a string and the INSTR function to filter your results.
=IIF(ISNOTHING(Parameters!AMOUNT.Value) OR INSTR(
Join(LOOKUPSET(Fields!Amount.Value, Fields!Amount.Value, Fields!Store.Value, "DataSet1"), ", ") ,
Fields!Store.Value
) > 0, 1, 0)
This translates to:
If the Store value is found (INSTR > 0) in the list (JOIN) of Stores where the Amount is the current Amount (Lookupset).
In your filter, put the above expression in the Expression, change the type to INTEGER and the Value to 1.
[

Multi-step traversal in Cypher?

I have a data structure where data is composed of two sorts of nodes: item and claim. claim represents some information about the item and may refer to other items, such as - certain entity being located in certain other entity, e.g. "Germany is in Europe". Example structure:
create
(v1:item {id:"Q1", name: "Europe"}),
(v2:item {id:"Q2", name: "France"}),
(v3:item {id:"Q3", name: "Germany"}),
(v4:item {id:"Q4", name: "Bavaria"}),
(v5:item {id:"Q5", name: "Munich"}),
(c1:claim:located),
(c2:claim:located),
(c3:claim:located),
(c4:claim:located),
(v5)-[:claim]->c4,
(c4)-[:located]->v4,
(v4)-[:claim]->c3,
(c3)-[:located]->v3,
(v3)-[:claim]->c2,
(c2)-[:located]->v1,
(v2)-[:claim]->c1,
(c1)-[:located]->v1;
also in http://console.neo4j.org/?id=ncbom6. Now, if I wanted to traverse it - e.g. to figure out all items in Germany, or in Europe, how can I do this? Is it possible with Cypher in this model? I know there's something like v1-[r:*]->v2 but this assumes either one specific relationship or any relationship, and I need a repeating pattern of claim-located pairs.
If you want to find, for example, all the items in Europe, using the data in your console:
MATCH (v:item { name: "Europe" })<-[:claim|located*]-(x:item)
RETURN x;
If you also want to ensure that the path traversed strictly alternates between claim and located relationships, here is a somewhat tricky way to do that:
MATCH (v:item { name: "Europe" })<-[rel:claim|located*]-(x:item)
WHERE REDUCE(s = 0, x IN rel | CASE
WHEN (s = 0 AND TYPE(x)= 'claim')
THEN 1
WHEN (s = 1 AND TYPE(x)= 'located')
THEN 0
ELSE NULL END )= 0
RETURN x;
You can modify the WHEN tests if you need additional checking.

OpenERP - many2one remove old data

I have a one2many which stores some data.
In python, when I need to update the object with .write method; the new data is stored but the old stuff remain there.
How can I empty the many2many before using .write method ??
Maybe using .browse and .search ?? please help !!!
It would be great if you have posted some example of what you are trying to do. Any way, you have 2 solutions:
use unlink()
understand how the write() ORM method works on one2many fields.
Let take the example of account.invoice and account.invoice.line.
The first approach - unlink():
def delete_lines(self, cr, uid, ids, context=None):
invoice_pool = self.pool.get('account.invoice')
line_pool = self.pool.get('account.invoice.line')
for invoice in invoice_pool.browse(cr, uid, ids, context=context):
line_ids = [line.id for line in invoice.invoice_line]
line_pool.unlink(cr, uid, line_ids, context=context)
The second approach - write()
Looking at the OpenERP docs (https://doc.openerp.com/6.0/developer/2_5_Objects_Fields_Methods/methods/#osv.osv.osv.write):
write(cr, user, ids, vals, context=None)
...
Note: The type of field values to pass in vals for relationship fields is specific:
For a one2many field, a lits of tuples is expected. Here is the list of tuple that are accepted, with the corresponding semantics
(2, ID) remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)
So for the vals parameter we need a list of tuples in the following format:
[
(2, line1_id),
(2, line2_id),
(2, line3_id),
...
]
The following code illustrates the use of the write() method.
def delete_lines(self, cr, uid, ids, context=None):
invoice_pool = self.pool.get('account.invoice')
for invoice in invoice_pool.browse(cr, uid, ids, context=context):
vals = [(2, line.id) for line in invoice.invoice_line]
invoice.write(vals)
I didn't test the examples so let me know if they do the job.
Here is how I solved it:
my_object = self.pool.get('my.main.object')
props = self.pool.get('table.related')
prop_id = props.search(cr, uid, [('id_1', '=', id_2)])
del_a = []
for p_id in prop_id:
del_a.append([2, p_id])
my_object.write(cr, uid, line_id, {'many2one_field': del_a}, context=context)
Where:
del_a.append([2, p_id]) creates the string of tuples with code "2" (delete)
and my_object is where I need to make the changes.

Resources