How to render a tree in solid-js with minimum updates when updating a node - solid-js

I have this structure passed as props:
let moves = [
'd4 d4',
'd4d5 d5',
'd4d5f4 Bf4',
'd4d5f4c5 c5',
'd4d5f4c5e3 e3',
'd4d5f4c5e3d4 cxd4',
'd4d5f4c5e3d4d4 exd4',
'd4d5f4c5e3b6 Qb6',
'd4d5f4c5e3b6c3 Nc3',
'd4d5f4c5e3b6c3e6 e6',
'd4d5f4c5e3b6c3e6f3 Nf3',
'd4d5f4c5e3b6c3e6f3e7 Be7 { Hello world }',
'd4d5f4c5e3b6c3e6f3c4 c4',
'd4d5f4c5e3b6c3e6f3e7a5 a5 { What s up ok ok ok ook }',
'd4d5f4c5e3b6c3e6f3e7a5d8 Qd8',
'd4d5f4c5e3b6c3e6f3c4b3 b3',
'd4d5f4c5e3b6c3e6f3c4b3b5 b5 {__red__ redyes}',
'd4d5f4c5e3b6c3e6f3c4b3b5b1 Rb1',
'd4d5f4c5e3b6c3e6f3c4b3b5b1a5 Qa5',
'd4d5f4c5e3b6c3e6f3c4b3b5b1a5b7 Rxb7',
'd4d5f4c5e3b6c3e6f3c4b3b5b1a5b7c3 Qxc3',
'd4d5f4c5e3b6c3e6f3c4b3b5b1a5c4 Bxc4',
'd4d5f4c5e3b6c3e6f3c4b3b5b1a5c4c7 Qxc7',
'd4d5f4c5e3b6c3e6f3c4b3b5b1d7 Qd7',
'd4d5f4c5e3b6c3e6f3c4b3b5b1d7e5 Ne5',
]
So an array of paths into the tree and data separated by space.
Please turn this into a renderable tree view. I have no idea how to do this.

Related

Adding and triggering a transition within on_enter state callback

I want to store a previous state A when entering state B using a state history. Later 'on_enter' of another state X, add a transition X->A, trigger it and return to state A.
A -> B (store A) -> C -> X (add transition from X to A) -> A
from transitions.extensions import HierarchicalGraphMachine
class Matter(HierarchicalGraphMachine):
def __init__(self, states):
# self.separator = '/'
self.history = []
self.stored = []
HierarchicalGraphMachine.__init__(
self,
states=states,
initial='root',
show_state_attributes=True
)
#property
def state(self):
return self.history[-1]
#state.setter
def state(self, value):
self.history.append(value)
def store_last(self):
self.stored.append(self.history[-2])
def to_stored(self):
stored = self.stored.pop()
temp_transition = {
'trigger': 'jump',
'source': self.state,
'dest': stored
}
self.add_transition(**temp_transition)
self.trigger('jump')
self.remove_transition(**temp_transition)
TRANSITIONS = [
['walk', 'standing', 'walking'],
['stop', 'walking', 'standing'],
['drink', '*', 'caffeinated'],
['walk',
['caffeinated', 'caffeinated_dithering'],
'caffeinated_running'],
['relax', 'caffeinated', 'standing']
]
STATES = [{
'name': 'root',
'initial': 'standing',
'transitions': TRANSITIONS,
'children': [
{
'name': 'standing',
},
{
'name': 'walking',
'on_enter': 'store_last',
},
{
'name': 'caffeinated',
'children': [
'dithering',
{
'name': 'running',
'on_enter': 'to_stored'
}
]
}
]
}]
If I run the code skipping on_enter the transition is added, triggered and removed as expected.
# this works
lump = Matter(states=STATES)
lump.trigger('walk')
assert lump.history == ['root', 'root_standing', 'root_walking']
assert lump.stored == ['root_standing']
lump.trigger('drink')
# set state manually to skip on_enter
lump.state = 'root_caffeinated_running'
# run on_enter method manually works
lump.to_stored()
assert lump.state == 'root_standing'
assert lump.stored == []
assert lump.get_nested_transitions(trigger='jump') == []
lump.get_graph().draw('my_state_diagram.pdf', prog='dot')
If I run it within on_enter I get an error "MachineError: "Can't trigger event 'jump' from state(s) root_caffeinated_running!"
# cannot do the jump using on_enter
lump = Matter(states=STATES)
lump.trigger('walk')
lump.trigger('drink')
lump.trigger('walk')
# Can't trigger event 'jump' from state(s) root_caffeinated_running!
lump.get_graph().draw('my_state_diagram.pdf', prog='dot')
By default transitions will add auto transitions which can be used to reach every state directly without the need to add transitions temporarily. In combination with Machine.trigger that can be used to call events by their name, your to_stored method could be simplified to:
def to_stored(self):
stored = self.stored.pop()
self.trigger(f"to_{stored}")

How to insert multiple row in dynamoDb using PHP?

I have written below Json for insert in dynamodb, but unable to insert. But if I try single element without array it's working fine.
$item = $marshaler->marshalJson('
[
{
"PK":"CATG",
"SK":"NAME#SMART_PHONE",
"TYPE":"CATG",
"ATTR":{
"name":"安いスマートフォン一覧【最安値比較】"
}
},
{
"PK":"CATG#SMART_PHONE",
"SK":"SUBCATG#IPHONE",
"TYPE":"SUBCATG",
"ATTR":{
"name":"IPHONE",
"Compa":"mac",
"uid":123
}
},
{
"PK":"CATG#SMART_PHONE#SUBCATG#IPHONE",
"SK":"PROD#PHONE11",
"TYPE":"PROD",
"ATTR":{
"name":"PHONE11",
"uid":123,
"price":112.02,
"images":[
],
"total":120
}
},
{
"PK":"CATG#SMART_PHONE#SUBCATG#IPHONE",
"SK":"PROD#PHONE7",
"TYPE":"PROD",
"ATTR":{
"name":"PHONE7",
"Compa":"mac",
"uid":124,
"price":102.02,
"images":[
],
"total":80
}
}
]
');
$params = [
'TableName' => $tableName,
'Item' => $item
];
$result = $dynamodb->putItem($params);
After apply this code.
I have got below error
Fatal error: Uncaught InvalidArgumentException: The JSON document must be valid and be an object at its root. in E:\xampp\htdocs\shop\vendor\aws\aws-sdk-php\src\DynamoDb\Marshaler.php:99 Stack trace: #0 E:\xampp\htdocs\shop\item.php(30): Aws\DynamoDb\Marshaler->marshalJson('\r\n [\r\n ...') #1 {main} thrown in E:\xampp\htdocs\shop\vendor\aws\aws-sdk-php\src\DynamoDb\Marshaler.php on line 99
If I insert single row it's working fine. How can I insert bulk row ?
To insert multiple items you have two options:
you can have a loop and repeatedly call the PutItem API for each one
you can break up your collection of items into groups of up to 25 and use the BatchWriteItem API (see docs)
Note that the BatchWriteItem API will still result in 25 WCU being used but it just saves you a bit on the network round-trips, making fewer calls.
The downside of using BatchWriteItem is that you have to manage the grouping of items and then handle the partial successful writes, such that unsuccessful items get re-grouped/re-tried.

Within a gimp python-fu plug-in can one create/invoke a modal dialog (and/or register a procedure that is ONLY to be added as a temp procedure?)

I am trying to add a procedure to pop-up a modal dialog inside a plug-in.
Its purpose is to query a response at designated steps within the control-flow of the plug-in (not just acquire parameters at its start).
I have tried using gtk - I get a dialog but it is asynchronous - the plugin continues execution. It needs to operate as a synchronous function.
I have tried registering a plugin in order to take advantage of the gimpfu start-up dialogue for same. By itself, it works; it shows up in the procedural db when queried. But I never seem to be able to actually invoke it from within another plug-in - its either an execution error or wrong number of arguments no matter how many permutations I try.
[Reason behind all of this nonsense: I have written a lot of extension Python scripts for PaintShopPro. I have written a App package (with App.Do, App.Constants, Environment and the like that lets me begin to port those scripts to GIMP -- yes it is perverse, and yes sometimes the code just has to be rewritten, but for a lot of what I actual use in the PSP.API it is sufficient.
However, debugging and writing the module rhymes with witch. So. I am trying to add emulation of psp's "SetExecutionMode" (ie interactive). If
set, the intended behavior is that the App.Do() method will "pause" after/before it runs the applicable psp emulation code by popping up a simple message dialog.]
A simple modal dialogue within a gimp python-fu plug-in can be implemented via gtk's Dialog interface, specifically gtk.MessageDialog.
A generic dialog can be created via
queryDialogue = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT \
gtk.MESSAGE_QUESTION, \
gtk.BUTTONS_OK_CANCEL, "")
Once the dialog has been shown,
a synchronous response may be obtained from it
queryDialogue.show()
response = queryDialogue.run()
queryDialogue.hide()
The above assumes that the dialog is not created and thence destroyed after each use.
In the use case (mentioned in the question) of a modal dialog to manage single stepping through a pspScript in gimp via an App emulator package, the dialogue message contents need to be customized for each use. [Hence, the "" for the message argument in the Constructor. [more below]]
In addition, the emulator must be able to accept a [cancel] response to 'get out of Dodge' - ie quit the entire plug-in (gracefully). I could not find a gimpfu interface for the latter, (and do not want to kill the app entirely via gimp.exit()). Hence, this is accomplished by raising a custom Exception class [appTerminate] within the App pkg and catching the exception in the outer-most scope of the plugin. When caught, then, the plug-in returns (exits).[App.Do() can not return a value to indicate continue/exit/etc, because the pspScripts are to be included verbatim.]
The following is an abbreviated skeleton of the solution -
a plug-in incorporating (in part) a pspScript
the App.py pkg supplying the environment and App.Do() to support the pspScript
a Map.py pkg supporting how pspScripts use dot-notation for parameters
App.py demonstrates creation, customization and use of a modal dialog - App.doContinue() displays the dialogue illustrating how it can be customized on each use.
App._parse() parses the pspScript (excerpt showing how it determines to start/stop single-step via the dialogue)
App._exec() implements the pspScript commands (excerpt showing how it creates the dialogue, identifies the message widget for later customization, and starts/stops its use)
# App.py (abbreviated)
#
import gimp
import gtk
import Map # see https://stackoverflow.com/questions/2352181/how-to- use-a-dot-to-access-members-of-dictionary
from Map import *
pdb = gimp.pdb
isDialogueAvailable = False
queryDialogue = None
queryMessage = None
Environment = Map({'executionMode' : 1 })
_AutoActionMode = Map({'Match' : 0})
_ExecutionMode = Map({'Default' : 0}, Silent=1, Interactive=2)
Constants = Map({'AutoActionMode' : _AutoActionMode}, ExecutionMode=_ExecutionMode ) # etc...
class appTerminate(Exception): pass
def Do(eNvironment, procedureName, options = {}):
global appTerminate
img = gimp.image_list()[0]
lyr = pdb.gimp_image_get_active_layer(img)
parsed = _parse(img, lyr, procedureName, options)
if eNvironment.executionMode == Constants.ExecutionMode.Interactive:
resp = doContinue(procedureName, parsed.detail)
if resp == -5: # OK
print procedureName # log to stdout
if parsed.valid:
if parsed.isvalid:
_exec(img, lyr, procedureName, options, parsed, eNvironment)
else:
print "invalid args"
else:
print "invalid procedure"
elif resp == -6: # CANCEL
raise appTerminate, "script cancelled"
pass # terminate plugin
else:
print procedureName + " skipped"
pass # skip execution, continue
else:
_exec(img, lyr, procedureName, options, parsed, eNvironment)
return
def doContinue(procedureName, details):
global queryMessage, querySkip, queryDialogue
# - customize the dialog -
if details == "":
msg = "About to execute procedure \n "+procedureName+ "\n\nContinue?"
else:
msg = "About to execute procedure \n "+procedureName+ "\n\nDetails - \n" + details +"\n\nContinue?"
queryMessage.set_text(msg)
queryDialogue.show()
resp = queryDialogue.run() # get modal response
queryDialogue.hide()
return resp
def _parse(img, lyr, procedureName, options):
# validate and interpret App.Do options' semantics vz gimp
if procedureName == "Selection":
isValid=True
# ...
# parsed = Map({'valid' : True}, isvalid=True, start=Start, width=Width, height=Height, channelOP=ChannelOP ...
# /Selection
# ...
elif procedureName == "SetExecutionMode":
generalOptions = options['GeneralSettings']
newMode = generalOptions['ExecutionMode']
if newMode == Constants.ExecutionMode.Interactive:
msg = "set mode interactive/single-step"
else:
msg = "set mode silent/run"
parsed = Map({'valid' : True}, isvalid=True, detail=msg, mode=newMode)
# /SetExecutionMode
else:
parsed = Map({'valid' : False})
return parsed
def _exec(img, lyr, procedureName, options, o, eNvironment):
global isDialogueAvailable, queryMessage, queryDialogue
#
try:
# -------------------------------------------------------------------------------------------------------------------
if procedureName == "Selection":
# pdb.gimp_rect_select(img, o.start[0], o.start[1], o.width, o.height, o.channelOP, ...
# /Selection
# ...
elif procedureName == "SetExecutionMode":
generalOptions = options['GeneralSettings']
eNvironment.executionMode = generalOptions['ExecutionMode']
if eNvironment.executionMode == Constants.ExecutionMode.Interactive:
if isDialogueAvailable:
queryDialogue.destroy() # then clean-up and refresh
isDialogueAvailable = True
queryDialogue = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, "")
queryDialogue.set_title("psp/APP.Do Emulator")
queryDialogue.set_size_request(450, 180)
aqdContent = queryDialogue.children()[0]
aqdHeader = aqdContent.children()[0]
aqdMsgBox = aqdHeader.children()[1]
aqdMessage = aqdMsgBox.children()[0]
queryMessage = aqdMessage
else:
if isDialogueAvailable:
queryDialogue.destroy()
isDialogueAvailable = False
# /SetExecutionMode
else: # should not get here (should have been screened by parse)
raise AssertionError, "unimplemented PSP procedure: " + procedureName
except:
raise AssertionError, "App.Do("+procedureName+") generated an exception:\n" + sys.exc_info()
return
A skeleton of the plug-in itself. This illustrates incorporating a pspScript which includes a request for single-step/interactive execution mode, and thus the dialogues. It catches the terminate exception raised via the dialogue, and then terminates.
def generateWebImageSet(dasImage, dasLayer, title, mode):
try:
img = dasImage.duplicate()
# ...
bkg = img.layers[-1]
frameWidth = 52
start = bkg.offsets
end = (start[0]+bkg.width, start[1]+frameWidth)
# pspScript: (snippet included verbatim)
# SetExecutionMode / begin interactive single-step through pspScript
App.Do( Environment, 'SetExecutionMode', {
'GeneralSettings': {
'ExecutionMode': App.Constants.ExecutionMode.Interactive
}
})
# Selection
App.Do( Environment, 'Selection', {
'General' : {
'Mode' : 'Replace',
'Antialias' : False,
'Feather' : 0
},
'Start': start,
'End': end
})
# Promote
App.Do( Environment, 'SelectPromote' )
# und_so_weiter ...
except App.appTerminate:
raise AssertionError, "script cancelled"
# /generateWebImageSet
# _generateFloatingCanvasSetWeb.register -----------------------------------------
#
def generateFloatingCanvasSetWeb(dasImage, dasLayer, title):
mode="FCSW"
generateWebImageSet(dasImage, dasLayer, title, mode)
register(
"generateFloatingCanvasSetWeb",
"Generate Floating- Frame GW Canvas Image Set for Web Page",
"Generate Floating- Frame GW Canvas Image Set for Web Page",
"C G",
"C G",
"2019",
"<Image>/Image/Generate Web Imagesets/Floating-Frame Gallery-Wrapped Canvas Imageset...",
"*",
[
( PF_STRING, "title", "title", "")
],
[],
generateFloatingCanvasSetWeb)
main()
I realize that this may seem like a lot of work just to be able to include some pspScripts in a gimp plug-in, and to be able to single-step through the emulation. But we are talking about maybe 10K lines of scripts (and multiple scripts).
However, if any of this helps anyone else with dialogues inside plug-ins, etc., so much the better.

How to solve in ReasonReact - "This has type: (ReasonReact.reactElement, string) => unit But somewhere wanted: at <anonymous>actElement

I have a very compact ReasonReact reducer component, which has a component, initialState, reducer, action, and render function as follows:
type actions =
| DoNothing;
let component = ReasonReact.reducerComponent("ShowHide");
let make = (~name, _children) => {
...component,
initialState: () => 0, /* here, state is an `int` */
reducer: (action, state) =>
switch action {
| DoNothing => ReasonReact.NoUpdate;
},
render: (self) => {
let greeting =
"Hello: " ++ name ++ ". You've clicked the button " ++ string_of_int(self.state) ++ " time(s)!";
<div></div>
}
};
I am trying to render in my app.re file using the ReactDOMRe.renderToElementWithId function:
<div id = "RenderShowHide"></div>
ReactDOMRe.renderToElementWithId(<ShowHide name="hello" />, "RenderShowHide")
However, the Reason/Bucklescript compiler is complaining as follows:
This has type:
(ReasonReact.reactElement, string) => unit
But somewhere wanted:
at <anonymous>actElement
However, I am having a difficulty what an actElement is. Any suggestions as to what an actElement is, and how I can go around fixing the above, would be more than appreciated. Thank you.
I tried the repo you posted: https://github.com/CharlieGreenman/reason-react-razroo
npm install
bsb -make-world
I got the following error message:
We've found a bug for you!
/Users/yawar/src/reason-react-razroo/src/app.re 16:9-40
14 ┆ </div>
15 ┆ <p className="App-intro">
16 ┆ ReactDOMRe.renderToElementWithId(<ShowHide name="hello"/>, "index")
17 ┆ (ReasonReact.stringToElement("To get started, edit"))
18 ┆ <code> (ReasonReact.stringToElement(" src/app.re ")) </code>
This has type:
(ReasonReact.reactElement, string) => unit
But somewhere wanted:
ReasonReact.reactElement
It looks like something in your build tooling was swallowing part of your error message. The main problem is on l. 16; if you get rid of that line the error will go away. If you want to render the ShowHide component, then change the line to just the literal JSX, not the call to ReactDOMRe.renderToElementWithId.
I have two more general recommendations; try to stick with the bsb-provided React skeleton project unless you are expert-level, because it's way simpler and much better supported:
bsb -init my-project -theme react
And, try to post the entire error message for future errors, starting from the 'We've found a bug for you!' line. That will help diagnose a lot.

Mason2 wrong utf8 encoding with the "go" method

Bit long question, because AFAIK Poet/Mason2 isn't the very often used framework - so I'm trying to be detailed.
Two years ago I asked a question how to make Mason2 utf8 clean. As far as i know, here isn't much new in Mason/Poet in this field - and unfortunately today I meet another problem. Simple test case:
$ poet new my #create new poet application
$ cd my
Override some methods, allowing to use utf8 in the components:
add to ./lib/My/Mason/Compilation.pm
override 'output_class_header' => sub {
return join("\n",
super(), qq(
use utf8;
use Encode qw(encode decode);
)
);
};
The above adds to each compiled Mason component the use utf8....
Also need encode the output from Mason (Plack need bytes), so in: ./lib/My/Mason/Request.pm
override 'run' => sub {
my($self, $path, $args) = #_;
my $result = super();
$result->output( Encode::encode('UTF-8', $result->output()) );
return $result;
};
Now, can create a component such page.mc for example with a content:
% sub { uc($_[0]) } {{
a quick brown fox jumps over the lazy dog.
διαφυλάξτε γενικά τη ζωή σας από βαθειά ψυχικά τραύματα.
árvíztűrő tükörfúrógép.
dość gróźb fuzją, klnę, pych i małżeństw!
эх, чужак, общий съём цен шляп (юфть) – вдрызг!
kŕdeľ šťastných ďatľov učí pri ústí váhu mĺkveho koňa obhrýzať kôru a žrať čerstvé mäso.
zwölf boxkämpfer jagen viktor quer über den großen sylter deich.
% }}
After running a poet app bin/run.pl you can go to: http://0:5000/page and will get a correct content.
A QUICK BROWN FOX JUMPS OVER THE LAZY DOG. ΔΙΑΦΥΛΆΞΤΕ ΓΕΝΙΚΆ ΤΗ ΖΩΉ
ΣΑΣ ΑΠΌ ΒΑΘΕΙΆ ΨΥΧΙΚΆ ΤΡΑΎΜΑΤΑ. ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP. DOŚĆ GRÓŹB
FUZJĄ, KLNĘ, PYCH I MAŁŻEŃSTW! ЭХ, ЧУЖАК, ОБЩИЙ СЪЁМ ЦЕН ШЛЯП (ЮФТЬ) –
ВДРЫЗГ! KŔDEĽ ŠŤASTNÝCH ĎATĽOV UČÍ PRI ÚSTÍ VÁHU MĹKVEHO KOŇA OBHRÝZAŤ
KÔRU A ŽRAŤ ČERSTVÉ MÄSO. ZWÖLF BOXKÄMPFER JAGEN VIKTOR QUER ÜBER DEN
GROSSEN SYLTER DEICH.
But when create another component, say go.mc with a content
% $m->go('/page');
the internal redirect (the go method) somewhat mess up the content and will produce:
A QUICK BROWN FOX JUMPS OVER THE LAZY DOG. ÎÎÎΦΥÎÎÎΤÎ
ÎÎÎÎÎΠΤΠÎΩΠΣÎΣ ÎÎ Î ÎÎÎÎÎΠΨΥΧÎÎÎ
ΤΡÎÎÎÎΤÎ. ÃRVÃZTÅ°RÅ TÃKÃRFÃRÃGÃP. DOÅÄ GRÃŹB
FUZJÄ, KLNÄ, PYCH I MAÅÅ»EÅSTW! ЭХ, ЧУÐÐÐ, ÐÐЩÐÐ
СЪÐРЦÐРШÐЯР(ЮФТЬ) â ÐÐРЫÐÐ! KÅDEĽ Å
ŤASTNÃCH ÄATĽOV UÄà PRI ÃSTà VÃHU MĹKVEHO KOÅA OBHRÃZAŤ
KÃRU A ŽRAŤ ÄERSTVà MÃSO. ZWÃLF BOXKÃMPFER JAGEN VIKTOR QUER
ÃBER DEN GROSSEN SYLTER DEICH.
Strange, the $m->visit() works correctly. So, somewhere in Poet/Mason is need do something to get correct output for the go method.
Could anyone help?
I've been working on a plugin for Mason to deal with encoding. $result->output is the wrong place to encode output, because visit will run a subrequest, encoding its own content at the end, before returning to the original component, which then re-encodes everything when it completes. So the content in the visit gets encoded twice. I'm surprised you are having a problem with go, because that discards all previous content and starts again, which should be OK.
Have a look at https://github.com/davebaird/mason-plugin-withencoding