Hello,
There's probably a trick for that, but I didn't find a way to create a single element dict:
("foo") dict ("bar") => {"f":"b", "o": "r"}
Whereas:
("foo", "baz") dict ("bar", "qux")
does the expected.
A multimedia sketchbook · By
To obtain a list of the cards with a particular group number you could use a query something like
c:extract value where value..widgets.group.text=2 from deck.cards
(Note that if a 'group' field doesn't exist it will behave the same as a card in group "0"; you probably want to count from 1 for your groups)
Given that list, you can pick a random item and navigate to some card like so:
go[random[c]]
Or, all at once,
go[random[extract value where value..widgets.group.text=2 from deck.cards]]
Does that make sense?
You can adjust the widths of the columns of a grid to hide trailing columns. In "Interact" mode, a small draggable handle appears between column headers:
You can reset the columns to their default uniform spacing with the "Reset Widths" button in grid properties.
Manually resizing column widths enforces a minimum size. You can set column widths to 0 programmatically via "grid.widths", but a 0-width column looks a bit odd; I'll make a note to fix that in the next release.
FYI i've patched the problem with 0-width columns in grids; that should now offer a fairly flexible option for visually suppressing columns without physically removing them from the underlying table. You can try it out now at the bleeding-edge source revision, and the fix will be incorporated into the v1.41 release; probably next week.
I'm having a hard time wrapping my head around arrays, maybe it's not what I actually need to be using. Basically I have two fields that I can enter text and I want to take each field and append them to an array that splits it all up by word. So "This is my text" in field1 and "More text" in field2 would be ["This", "is", "my", "text", "More", "text"] that I could then manipulate.
Starting from the two fields you describe:
You can obtain the text of either field through its ".text" attribute. The "split" operator breaks a string on the right at instances of the string on the left and produces a list. Splitting one string on spaces gets us part of the way to what you're asking for. We can then use the comma operator to join a pair of lists.
" " split field1.text
The best way to experiment with this sort of thing is to use The Listener. Ask a "question", get an answer:
Another approach for gathering space-separated words from several fields would be to use an "each" loop:
Does that help point you in the right direction?
In general, for string manipulation the main tools Lil provides are:
...and a few of the more complicated utility functions functions in rtext do also apply to plain strings.
The Lil "comma" operator forms a list by combining the elements of its left and right arguments.
If you use this operator to combine a table and a number, the table will be coerced to its list interpretation (a list of the rows of the table, each a dictionary), and then combined with the number 1 (whose only element is itself), forming a list of several dictionaries and the number 1. Applied to such a list, random[] will occasionally choose the 1.
When you call a Lil function with multiple arguments, commas should not be placed between arguments. You probably meant
random[temp 1]
Instead of
random[temp,1]
Furthermore, note that if you specify 1 as a second argument to random[] you will get a length-1 list as a result, whereas if you call random[] with only a single argument you will get a single value.
In preparing this post I have also observed that there is some inconsistency between native-decker and web-decker with respect to applying random[] to table values, which may have compounded the confusion; I'll have this fixed in the v1.41 release tomorrow. In the meantime the alternative is to explicitly crack the table into rows before making a random selection, like so:
random[(rows temp)]
What’s the best way to filter a list based on some predicate?
I was able to use “extract value where … from somelist” for some basic arithmetic, but when I throw a function into the predicate I get unexpected results (“value < f[value]” always seems to be true even though it definitely isn’t).
I’m wondering if I’ve misunderstood the “where” clause and it is only supposed to be used in table columns or something.
In the context of query clauses, column names refer to the entire column as a list. The "where" clause expects an expression which yields a list of boolean values. Arithmetic operators like =, <, and + conform over list-list and list-scalar arguments.
Depending on how a predicate is written, it might naturally generalize to operating on lists for the same reason. For example:
on iseven x do 0=2%x end iseven[5] # 0 iseven[11,22,33] # (0,1,0) extract value where iseven[value] from 11,24,3,8 # (24,8)
If a predicate is only designed to operate on a single scalar value at a time, you can use the "@" operator to apply it to each element of a column, like so:
on seconde x do x[1]="e" end extract value where seconde@value from "Lemon","Lime","Soda","Demon" # ("Lemon","Demon")
This shorthand is semantically equivalent to
extract value where each v in value seconde[v] end from "Lemon","Lime","Soda","Demon"
(And of course in this particular case the "like" operator would be simpler:)
extract value where value like ".e*" from "Lemon","Lime","Soda","Demon"
Does that clear things up?
Thanks! That does explain why it seemed to work sometimes and not others. I will give it another try. For the record, It looks like my skimming skills failed me, because I now see where this is explicitly noted in the docs:
When computing columns, you're working with lists of elements, and taking advantage of the fact that primitives like<
and+
automatically "spread" to lists. When performing comparisons, be sure to use=
rather than~
! If you want to call your own functions- say, to average within a grouped column- write them to accept a list
It even calls out “where” in the next paragraph.
Hi! I've been having a fun time messing around in Decker, and am now attempting something more game-y.
Specifically, I'd like to know if these are possible to do:
Widgets have an attribute called "show" which controls their visibility; this can be "solid" (the default), "invert" (an alternate color-scheme), "transparent", or "none".
Suppose the button X is on card C1 and the button Y is on card C2.
You could give X a script for toggling Y's visibility:
on click do C2.widgets.Y.toggle["solid"] end
Or a simpler version that just makes Y visible:
on click do C2.widgets.Y.show:"solid" end
There are several other examples of doing this sort of thing in this thread.
To make clicking a button "unlock" dialogue or behavior elsewhere in the deck, you'll need to remember that the button has been clicked, and consult that record at a later time.
Checkboxes are just a special visual appearance for a button, so every button widget has a "value" attribute that can store a single boolean (0 or 1) value. Thus, we can use the button itself to keep track of whether it's been clicked. Suppose you've given the button Z on card C1 a script like so:
on click do me.value:1 end
A script on another card could reset Z's value,
C1.widgets.Z.value:0
Or test its value in a conditional:
if C1.widgets.Z.value # do something special end
If you have lots of "flags" like this, it may be a good idea to centralize them in some kind of "backstage" card so you can keep track of them easily, and perhaps to give yourself a script for resetting the state of the deck.
Does that make sense?