I'm working on a spree commerce application. I have troubles with product filters. I can edit range filters but i want to add "all prices" filter.
Here is the code:
conds = [ [ Spree.t(:or_over_price, price: format_price(0)) , v[:amount].gteq(0)],
[ "#{format_price(25000)} - #{format_price(50000)}" , v[:amount].in(25000..50000)],
[ "#{format_price(50000)} - #{format_price(75000)}" , v[:amount].in(50000..75000)],
[ "#{format_price(75000)} - #{format_price(100000)}" , v[:amount].in(75000..100000)]]
{
So is working as 0 or over. But i want to show it as "all prices"
I need to change this line but i dont know how:
[ Spree.t(:or_over_price, price: format_price(0)) , v[:amount].gteq(0)]
Thanks in advance.
Just add to your config/locales/en.yml
all_prices: all prices
then in your conds array
conds = [ [ Spree.t(:all_prices) , v[:amount].gteq(0)],
[ "#{format_price(25000)} - #{format_price(50000)}" , v[:amount].in(25000..50000)],
[ "#{format_price(50000)} - #{format_price(75000)}" , v[:amount].in(50000..75000)],
[ "#{format_price(75000)} - #{format_price(100000)}" , v[:amount].in(75000..100000)]]
{
Related
I have a bunch of polygons that have self-intersection which causes some errors in further postprocessing them (in particular - I can't calculate intersection area of those polygons with other polygons). Here is an example of broken polygon:
{
"type": "MultiPolygon",
"coordinates": [
[
[
[
6.881057785381658,
46.82373306675715
],
[
6.857171686909481,
46.81861230543794
],
[
6.857354659059071,
46.81856788926046
],
[
6.856993473052509,
46.82693029065604
],
[
6.8612894138116785,
46.83422796373707
],
[
6.86720955648855,
46.835636765630476
],
[
6.871281147359957,
46.83078486366309
],
[
6.871573291317274,
46.8306215963777
],
[
6.877608228639841,
46.82771553607934
],
[
6.877758462659651,
46.82772313420989
],
[
6.877852632482749,
46.827735617670285
],
[
6.880928107931434,
46.82630213148064
],
[
6.8810399979122305,
46.82622029042867
],
[
6.881117606743071,
46.826115612819855
],
[
6.881057785381658,
46.82373306675715
]
]
]
]
}
This is what it looks like on the map - as you can see, there is intersection of two polygon edges. RGeo throws an error, pointing intersection coordinate (I guess): => "Geos::GEOSException: TopologyException: Input geom 0 is invalid: Self-intersection at or near point 6.8573510795579145 46.818650764080992 at 6.8573510795579145 46.818650764080992". So, I have it at least.
My question is: is there a way to fix that intersection automatically? I read, that a possible solution is to insert 2 similar points with coordinates of self-intersection. But the problem is - the polygon has a specific order, and I don't know WHERE to insert those points.
Also, maybe there are some existing tools helping fix that...
The solution I would use is postgis's ST_MakeValid option for postgres if that is an option for you you could do something along the lines of ST_AsText(ST_MakeValid(geom_column)) or if you would rather pass in the text here is an example using the bowtie example shown in prepair:
select ST_AsText(ST_MakeValid(ST_GeomFromText('POLYGON((0 0, 0 10, 10 0, 10 10, 0 0))')));
st_astext
-----------------------------------------------------------
MULTIPOLYGON(((0 0,0 10,5 5,0 0)),((5 5,10 10,10 0,5 5)))
(1 row)
If that doesn't interest you, you could export those geometries and use a tool like prepair to convert them. To sum up how this works behind the scenes, it will split these "bowties" into multiple polygons which will then be made into a multipolygon. The same type of fix will applied to multipolygons.
Is it possible to convert this HASH into an array of arrays based solely on the position of the key (rather than it's value). ie: I know ahead of time that the first Key will always be PROD/ALPHA, and the second Key will always be a country (that I would like to be able to change in the future at will)
The idea would be to group all servers of the same type (webservers) that are also in the same environment (production) but are located in different farms (UK, USA)
While any suggestions on how to do this are welcome, I'll be happy to just know that I'm not walking into a dead-end I won't be able to solve.
Here are some visuals to aid in my explanation:
{
"PROD": {
"USA": {
"generic": [
"nginx-240"
],
"WEB": [
"nginx-210",
"nginx-241",
"nginx-211",
"nginx-209"
],
"APP": [
"tomcat-269",
"tomcat-255",
"tomcat-119",
"tomcat-124"
]
},
"UK": {
"WEB": [
"nginx-249",
"nginx-250",
"nginx-246",
"nginx-247",
"nginx-248"
],
"generic": [
"tomcat-302"
],
"APP": [
"tomcat-396",
"tomcat-156",
"tomcat-157"
]
}
},
"ALPHA": {
"USA": {
"WEB": [
"nginx-144",
"nginx-146",
"nginx-145",
"nginx-175",
"nginx-173"
],
"APP": [
"tomcat-204",
"tomcat-206"
]
}
}
}
The expectation is that data from the lowest level in the hash would be grouped together.
Again the idea is that all Production app servers (both from UK and USA) are grouped together in the following kind of pattern:
PROD_UK_APP would be represented by
["tomcat-396","tomcat-156","tomcat-157"] as these are the lowest branches of the tree PROD->UK->applicationserver
[
[
[PROD_UK_APP],[PROD_USA_APP]
],
[
[PROD_UK_WEB],[PROD_USA_WEB]
]
]
New list..
[
[
[ALPHA_USA_WEB]
],
[
[ALPHA_USA_APP],
[
[
Again the idea is to keep this generic. Is this something that is practically achievable or am I likely to require some degree of hardcoding to ensure it always works? The idea is that if tomorrow UK becomes JAPAN, it will still work in exactly the same way, comparing between the APP and WEB tier of UK, and JAPAN (separating ALPHA from PROD).
EDIT: my attempt to try and sort it:
def walk
a = []
myhash.each do |env, data|
data.each do |dc, tier|
tier.each do |x, y|
a << y
end
end
end
p a
end
[["nginx240"], ["nginx210", "nginx241", "nginx211", "nginx209"], ["tomcat269", "tomcat255", "tomcat119", "tomcat124"], ["nginx249", "nginx250", "nginx246", "nginx247", "nginx248"], ["tomcat302"], ["tomcat396", "tomcat156", "tomcat157"], ["nginx144", "nginx146", "nginx145", "nginx175", "nginx173"], ["tomcat204", "tomcat206"]]
Thanks,
I think I follow what you're looking for and you should get what you're after with:
myhash.values.each_with_object([]) do |by_country, out_arr|
by_country.values.each do |by_type|
out_arr << by_type.values
end
end
which would return:
[
[
[
"nginx-240"
],
[
"nginx-210",
"nginx-241",
"nginx-211",
"nginx-209"
],
[
"tomcat-269",
"tomcat-255",
"tomcat-119",
"tomcat-124"
]
],
[
[
"nginx-249",
"nginx-250",
"nginx-246",
"nginx-247",
"nginx-248"
],
[
"tomcat-302"
],
[
"tomcat-396",
"tomcat-156",
"tomcat-157"
]
],
[
[
"nginx-144",
"nginx-146",
"nginx-145",
"nginx-175",
"nginx-173"
],
[
"tomcat-204",
"tomcat-206"
]
]
]
Piece by piece
Take your hash, disgard the keys and just create an array of values.
iterate over the values (array of hashes by country) and initialize an array to return.
for each hash that by_country points to, again take the values, to drop into the by type(?) hashes
iterate over your by_type hashes and again take the values of each
push each return array into the array you want to return
Current data what we have is node store has almost 65MB of data, and 260MB of relationship store ?
And while going to production, expect 200 users using the application concurrently, which behind the scenes trigger neo4j queries. And I went through the neo4j calculator, it is recommended to have 64G RAM.
Currently the staging where I test has 3 RHEL servers with 8G memory each, and 4G has been assigned for java heap. And it has HDD not SSD. And each server 2 cpu cores.
And as a single user, the simple queries brings the fast, and some complex ones which has to run bigger data nodes run in 20 seconds. It goes well till 2 to 3 users. But after sometime, the results are not returned, and the query runs indeterminately.
I am not sure what is the expected system configuration for the kind of data, and the management wants to justify the requirement for higher system procurement.
Is there any chance, this configuration can be tweaked to support production load.
And I already did the performance tweaks as suggested in the neo4j site, from linux performance to memory cache performance parameters.
Or is it necessary to have bigger RAM to load all relationship into memory, to make the queries and concurrent loads have faster response
Query which is in Question
match (c:company)
where c.company IN [ "GENERAL ELECTRIC-TELEPRESENCE","PNOC_REG02","testzenos2","testzenos3","PT10","CMSP_SLT_SYNC","CMSP_SLT_SYNC_2","Smoke Test Company","PTrans-Regr","SPWIFI-POC","PNOC_REG01","IBM","MERAKISP-MERAKICUST","0101rms","Meraki_SP01-new3" ]
match (c)-[r1]->(s:physical_location)-[r5]->(im:im_tkt)
where (
( im.assigned_group_id IN [ "SGP000000000259" ] and im.company = "GENERAL ELECTRIC-TELEPRESENCE")
OR ( im.assigned_group_id IN [ "SGP000000000259" ] and im.company = "PNOC_REG02")
OR ( im.assigned_group_id IN [ "SGP000000000259","SGP000000000175" ] and im.company = "testzenos2")
OR ( im.assigned_group_id IN [ "SGP000000000259","SGP000000000175" ] and im.company = "testzenos3")
OR ( im.assigned_group_id IN [ "SGP000000000259","SGP000000000088" ] and im.company = "PT10")
OR ( im.assigned_group_id IN [ "SGP000000000175","SGP000000000088" ] and im.company = "CMSP_SLT_SYNC")
OR ( im.assigned_group_id IN [ "SGP000000000175","SGP000000000088" ] and im.company = "CMSP_SLT_SYNC_2")
OR ( im.assigned_group_id IN [ "SGP000000000088" ] and im.company = "Smoke Test Company")
OR ( im.assigned_group_id IN [ "SGP000000000088" ] and im.company = "PTrans-Regr")
OR ( im.assigned_group_id IN [ "SGP000000000088" ] and im.company = "SPWIFI-POC")
OR ( im.assigned_group_id IN [ "SGP000000000088" ] and im.company = "PNOC_REG01")
OR ( im.assigned_group_id IN [ "SGP000000000088" ] and im.company = "IBM")
OR ( im.assigned_group_id IN [ "SGP000000000088" ] and im.company = "MERAKISP-MERAKICUST")
OR ( im.assigned_group_id IN [ "SGP000000000088" ] and im.company = "0101rms")
OR ( im.assigned_group_id IN [ "SGP000000000088" ] and im.company = "Meraki_SP01-new3") )
RETURN collect(distinct(im.incident_number)) as im_tkt__incident_number ,
collect(distinct(im.company)) as im_tkt__company ,
collect(distinct(im.assigned_support_organization)) as im_tkt__assigned_support_organization ,
collect(distinct(im.assignee)) as im_tkt__assignee ,
collect(distinct(im.description)) as im_tkt__description ,
collect(distinct(im.priority)) as im_tkt__priority ,
collect(distinct(im.status)) as im_tkt__status ,
collect(distinct(im.impact)) as im_tkt__impact ,
collect(distinct(im.entryid_TS1)) as im_tkt__entryid_TS1;
This is the query which runs for a longer time
Did you create indexes or constraints ?
create index on :company(company);
create index on :im_tkt(assigned_group_id);
Use Parameters in your real program !!
Pass in a list of maps for param like this:
[{company:"GENERAL ELECTRIC-TELEPRESENCE",
assigned_group_ids:[ "SGP000000000259" ]},
...]
Then query:
UNWIND {param} as pair
MATCH (c:company {company:pair.company})-[r1]->(s:physical_location)-[r5]->(im:im_tkt)
WHERE im.assigned_group_id IN pair.assigned_group_ids
RETURN collect(distinct(im.incident_number)) as im_tkt__incident_number ,
collect(distinct(im.company)) as im_tkt__company ,
collect(distinct(im.assigned_support_organization)) as im_tkt__assigned_support_organization ,
collect(distinct(im.assignee)) as im_tkt__assignee ,
collect(distinct(im.description)) as im_tkt__description ,
collect(distinct(im.priority)) as im_tkt__priority ,
collect(distinct(im.status)) as im_tkt__status ,
collect(distinct(im.impact)) as im_tkt__impact ,
collect(distinct(im.entryid_TS1)) as im_tkt__entryid_TS1;
for testing you can use
UNWIND [{company:"GENERAL ELECTRIC-TELEPRESENCE", assigned_group_ids:[ "SGP000000000259" ]}] as pair
MATCH (c:company {company:pair.company})-[r1]->(s:physical_location)-[r5]->(im:im_tkt)
WHERE im.assigned_group_id IN pair.assigned_group_ids
RETURN ...
I would like to dynamically add a button to the layout of a view, with the actor causing this addition belonging to a button that is already part of the layout.
I started with this:
REBOL [title: "Dynamic Button Addition"]
tilesize: 60x60
curtile: 1
stylize [
p: button [
facets: [init-size: tilesize max-size: tilesize]
actors: [
on-action: [
++ curtile
append tiles compose [ p (to-string curtile) ]
print ? tiles/options/content
v/redraw
]
]
]
]
v: [
tiles: hgroup [ p "1" ]
]
view v
...which does not appear to have the value of tiles/options/content change with each click.
I can get it to change if make these changes:
append tiledata compose [ p (to-string curtile) ]
and
tiledata: [ p "1" ]
v: [
tiles: hgroup tiledata
However, this does not cause any change on screen. If I replace the last four lines with this:
v: view [
tiles: hgroup tiledata
]
...so that v is now the view rather than the view's layout, I get this error when I click:
** Script error: v has no value
** Where: actor all foreach do-actor unless do-face if actor all foreach do-actor if do-event do-event if do-event either -apply- wake-up loop -apply- wait forever try do-events if view do either either either -apply-
** Near: actor face :data
This makes sense to me, because v is not yet done being defined, until I exit the program, IIUC.
How, then, can I make changes to v before the program ends, but after it's been passed to view?
Not very nice, but working if you replace
v/redraw
with these two lines
unview/all
view v
And there is a real dynamic example on how to update a layout that has already be viewed
I will simplify it
stylize [
tbox: hpanel [
actors: [
on-make: [
append face/options [
content: [
]
]
do-actor/style face 'on-make none 'hpanel
]
]
]
]
view/across [
button "button 1"
on-action [
append-content test compose [
button ( join "button " 2 + length? test/gob)
]
]
test: tbox
]
I'm trying to improve the Sliding Tile Puzzle example by making the starting positions random.
There's a better way to do this--"It is considered bad practice to convert values to strings and join them together to pass to do for evaluation."--but the approach I took was to try to generate Rebol3 source, and then evaluate it. I have it generating correctly, I think:
random/seed now
arr: random collect [ repeat tilenum 9 [ keep tilenum ] ]
hgroup-data: copy {}
repeat pos 9 [
curtile: (pick arr pos)
append hgroup-data either curtile = 9
[ reduce "x: box tilesize gameback " ]
[ rejoin [ { p "} curtile {" } ] ]
if all [(pos // 3) = 0 pos != 9] [ append hgroup-data " return^/" ]
]
print hgroup-data
...outputs something like:
p "4" x: box tilesize gameback p "5" return
p "3" p "7" p "1" return
p "2" p "8" p "6"
...which if I then copy and paste into this part, works correctly:
view/options [
hgroup [
PASTE-HERE
]
] [bg-color: gameback]
However, if I try to do it dynamically:
view/options [
hgroup [
hgroup-data
]
] [bg-color: gameback]
...(also print hgroup-data, do hgroup-data, and load hgroup-data), I get this error:
** GUI ERROR: Cannot parse the GUI dialect at: hgroup-data
...(or at: print hgroup-data, etc., depending on which variation I tried.)
If I try load [ hgroup-data ] I get:
** Script error: extend-face does not allow none! for its face argument
** Where: either if forever -apply- apply init-layout make-layout actor all foreach do-actor unless -apply- apply all build-face -apply- apply init-layout make-layout actor all foreach do-actor if build-face -apply- apply init-layout make-layout actor all foreach do-actor unless make-face -apply- apply case view do either either either -apply-
** Near: either all [
word? act: dial/1
block? body: get dial...
However, if I use the syntax hgroup do [ hgroup-data ], the program runs, but there are no buttons: it appears to be somehow over-evaluated, so that the return values of the functions p and box and so on are put straight into the hgroup as code.
Surely I'm missing an easy syntax error here. What is it?
First, I would say it's better to construct a block directly, instead of constructing a string and converting it to a block. But if you really want to do that, this should do the trick:
view/options compose/only [
hgroup (load hgroup-data)
] [bg-color: gameback]