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?
The "random[]" function can be called in several different ways to produce different kinds of random values. In your case, you want to select a random value from a list of possibilities and then supply that value to the "go[]" function.
The "go[]" function can navigate to cards by index (a number), by name (a string), or by value (a Card interface). We'll go with the latter. Within a script, all the cards of the deck are available as variables of the same name. Commas (,) between values are used to form a list. If we have cards named "cardA", "cardB", and "cardC", and we wish to navigate to one of those cards randomly when a button is clicked, we could give it a script like:
on click do go[random[cardA,cardB,cardC]] end
Does that help?
You might also find some of the examples in this tutorial illustrative: https://itch.io/t/3593043/make-your-own-chicken-generator
You can find documentation for format strings in Lil, The Formatting Language.
The format string of a slider widget is only given its value, which would usually be displayed as an integer (%i) or a floating-point number (%f); the rest of the string could, for example, provide units, like "%f degrees". In this way you *could* hardcode a maximum into the format string, like "%i/20" for an integer between 1 and 20 to be displayed like "7/20".
Extending the current behavior of sliders to make min/max and possibly other attributes of the widget available for formatting could be an interesting feature; I'll mull it over. For now, including that sort of information would require scripting. If you need this functionality in more than one place, perhaps you could use The Enum Contraption as a starting point?
Hi there, I noticed an odd behaviour, not sure if it has been flagged before. It relates to having a button widget with a script. If the button already has a script, and you go to the Action area to add a sound or pick a card etc. it overwrites the old script with the new action instead of just adding it into any existing script. Possibly there are good reasons for that, but thought I'd point it out just in case!
When you open the "Action..." dialog, Decker will attempt to "unpack" any script already attached to the button and reflect it in the settings you see in that dialog, and when you confirm it writes an entirely new script. This dialog exists purely as a convenience for composing simple scripts without writing code, and is not intended to manipulate or append to arbitrary user-generated scripts.