Tell when one and only one key is pressed with logical operators - logical-operators

I'm helping someone with a project on Scratch, and it has a block <if _key_ is pressed>, and I can tell if a key is pressed, (a, b, c, ...) or when ANY key is pressed.
Using these booleans, any and (a, b, c ...), can I tell if one and only one key is pressed without checking every single key individually? (e.g. a and ONLY a is pressed)
Note: I can only use logical operators, not variables or other things.

All I can think of is if you put if key a pressed not key a pressed and key b pressed or key a pressed and key c pressed etc., then it could eventually work. The only problem is what if you pressed key a, b, and c, what would happen. I guess though you are pressing a and b as well as the c so it wouldn't work. You know what? The other answer above is better. Ignore me.

Well it would be very hard to find a short piece of code to do it without using variables...
Your best shot if you don't want to do without variables is to make sure if a key is pressed, the other keys are not as shown below...
When GF clicked
if < <key [a] pressed> and <not <key [b] pressed> >
do stuff
if < <key [b] pressed> and <not <key [a] pressed> >
do stuff
But this is only for keys a and b, so if you want to do it for all 26 alphabetical letters, plus 10 numerals and a space bar, it would be very impractical. I'm not saying it is impossible, it is just very lengthy.
If you want to use variables, make a variable called keysPressed which would be used as a counter of number of keys pressed. You would need to make 38 seperate simple scripts as shown below...
When GF clickedforever
if <key [a] pressed
change keysPressed by (1)
wait until <not <key [a] pressed> >
change keysPressed by (-1)
Then you would need a seperate script after the 38 scripts of mostly copy-paste:
When GF Clicked
Forever
if <keysPressed = (1)>
do stuff
I'm not too sure what you want to do, so I just labelled your code after you pressed only 1 key as do stuff
Conclusion? Unless you are the impractical dude, use variables!

Related

Vim - mapping a key to a function which does something else plus the orginal function of that key

The target is to have the key j doing a possibly complex task and moving to the next line (the latter action performed just like the original function of the j key).
My initial attempt was to map j key this way:
nn j :<C-U>execute "call MyFun(" . v:count . ")"<CR>
(as you can see I intend to make j's behavior depend on the count which is prepended to it)
and to define the function MyFun appropriately:
fu! MyFun(count)
" do more stuff based on a:count
normal j
endf
which is faulty, as hitting j now results in the error E169: Command too recursive, since the non-recursivity of nnoremap, as long as my deduction is correct, applies to the "literal" content of the {rhs} of the mapping, and not to whatever is "inside" it (in other words the function body makes use of the meaning of j at the moment it is called, thus causing the infinte recursion).
Therefore I tried the following
nn , j
nn j :<C-U>execute "call MyFun(" . v:count . ")"<CR>
fu! MyFun(count)
" do more stuff based on a:count
normal ,
endf
However this means that I waste the key ,. I know I can avoid the waste of that mapping doing
nn <Plug>Nobody j
but then I wouldn't know how to use <Plug>Nobody (my understanding is indeed that its use is only in the {rhs} of another, non-nore mapping).
My initial attempt was to map j key this way
Using execute here is redundant. It's enough to do:
nnoremap j :<C-U>call MyFun(v:count)<CR>
now results in the error E169: Command too recursive
That's because of normal. To suppress remapping you must use "bang"-form: normal! j. Please, refere
to documentation for :normal, whose second paragraph describes exactly your use case:
If the [!] is given, mappings will not be used. Without it, when this
command is called from a non-remappable mapping (:noremap), the
argument can be mapped anyway.
Besides, note that j normally supports count, so 2j is expected to move two lines down. So you, probably, should do execute 'normal!' a:count . 'j' instead.

Updating the window in response to CLIM frame commands

While trying to figure out CLIM, I ran into this example program. It's a simple maze game. The author claims to have tested it in LispWorks (and even has #+Genera in there, implying that this program would work on a real Lisp Machine), but I'm trying to get it working in SBCL with McCLIM.
Under SBCL/McCLIM, the window draws, but nothing visible happens when you press the movement keys. Non-movement keys cause text to be entered into the pane with the game instructions.
I figured out that the game command keys are changing the game's internal state, so the only problem is that the screen does not update.
Then I realized that you couldn't write code to redraw the maze from the scope of the code that implements the commands. All the methods that draw receive a stream argument from CLIM, which must be passed to the graphics primitives. For example:
(defun draw-stone (stream x y cell-width cell-height)
(let ((half-cell-width (/ cell-width 2))
(half-cell-height (/ cell-height 2)))
(draw-ellipse* stream
(+ (* x cell-width) half-cell-width)
(+ (* y cell-height) half-cell-height)
half-cell-width 0
0 half-cell-height
:ink +red+)))
But the code that handles keystrokes receives no stream argument:
(defmacro define-stone-move-command (name keystroke dx dy)
`(define-maze-frame-command (,name :keystroke ,keystroke) ()
(let ((maze-array (maze-array *application-frame*)))
(move-stone maze-array ,dx ,dy)
(check-for-win maze-array))))
What I ended up having to do is to save the stream argument from the first (and only) call to draw-maze-array to a global variable, so that I could add update code to the define-stone-command macro as follows:
(defmacro define-stone-move-command (name keystroke dx dy)
`(define-maze-frame-command (,name :keystroke ,keystroke) ()
(let ((maze-array (maze-array *application-frame*)))
(move-stone maze-array ,dx ,dy)
(check-for-win maze-array)
(draw-maze-array *application-frame* *maze-stream*))))
This slight alteration gives the desired behavior on SBCL with McCLIM, but this doesn't seem right, however. After all, the author claimed that the code worked fine on LispWorks. I have a few questions:
Can somebody who has LispWorks confirm that this program works as-is on LispWorks?
Does my alteration to the code make it fail on LispWorks?
What is the accepted way to handle screen updating in CLIM applications?
Drawing the maze in the command is not the right approach. Putting a maze-stream into a global variable is also bad. ;-)
The display pane has a :display-function. The idea is that after a command the whole application frame gets updated automagically. For example for :display-time :command-loop, the display pane would be updated automagically, after a command runs. There are other ways to update panes, but in this case a keystroke runs a command and then the top-level-loop would just call the display-function for each applicable pane. The default toplevel-loop reads a command (via mouse, command lines, keystrokes, ...), executes it and updates the application frame - in a loop.
The whole redisplay thing is extremely tricky/powerful. It allows from fully automagical redisplay mechanisms to extremely fine-grained control.
You can read about it here: CLIM 2 Spec. Note: there might be quite a bit difference between the spec and what implementations provide...

A seemingly silly way of using the Stream API that leads to the need for Predicate<Boolean>

A predicate on booleans seems a little silly to me (well, at least in the following scenario):
static Set<A> aSet = ...;
checkCondition(B b) {
return aSet.stream()
.map(b::aMethodReturningBoolean)
.filter((Boolean check) -> check)
.limit(1).count() > 0;
}
What I am doing is that given the object b, checking whether there is at least one member of aSet that satisfies a certain condition with respect to b.
Everything is working fine, but the line filter((Boolean check) -> check) is like a tiny little pin pricking me! Is there a way I can avoid it? I mean, if I have a line in my code that is literally the identity function, then there must be something wrong with my approach.
All you need is
return aSet.stream().anyMatch(b::aMethodReturningBoolean);
which is much more readable.

PostScript forall on dictionaries

According to the PLRM it doesn't matter in which order you execute a forall on a dict:
(p. 597) forall pushes a key and a value on the operand stack and executes proc for each key-value pair in the dictionary
...
(p. 597) The order in which forall enumerates the entries in the dictionary is arbitrary. New entries put in the dictionary during the execution of proc may or may not be included in the enumeration. Existing entries removed from the dictionary by proc will not be encountered later in the enumeration.
Now I was executing some code:
/d 5 dict def
d /abc 123 put
d { } forall
My output (operand stack) is:
--------top-
/abc
123
-----bottom-
The output of ghostscript and PLRM (operand stack) is:
--------top-
123
/abc
-----bottom-
Does it really not matter in what order you process the key-value pairs of the dict?
on the stack, do you first need to push the value and then the key, or do you need to push the key first? (as the PLRM only talks about "a key and a value", but doesnt tell you anything about the order).
Thanks in advance
It would probably help if you quoted the page number qhen you quote sections from the PLRM, its hard to see where you are getting this from.
When executing forall the order in which forall enumerates the dictionary pairs is arbitrary, you have no influence over it. However forall always pushes the key and then the value. Even if this is implied in the text you (didn't quite) quote, you can see from the example in the forall operator that this is hte case.
when you say 'my output' do you mean you are writing your own PostScript interpreter ? If so then your output is incorrect, when pushing a key/value pair the key is pushed first.

Emacs ESS indentation and auto-completion

There are a number of useful variables to control TAB key indentation and completion in Emacs (R) code chunks, when using ESS mode.
ess-tab-complete-in-script first indents lines and, if there is nothing to indent, autocompletes the word.
"With great power, comes great responsibility", so, when fast indenting your code, you might end up completing code without noticing with catastrophic results. Therefore you can refine things with the variable
ess-first-tab-never-complete. For example: if 'unless-eol, TAB completes only when cursor is at the end of the line; if 'symbol, it completes also in the middle of a line, but not if you are in the middle of a word; etc (read doc for more
with F1vess-first-tab-never-complete).
The problem is that, at least for me, TAB is bound to ess-noweb-indent-line, but the command governing indent-or-complete behaviour is: ess-indent-or-complete. So I use to fix the tab binding with:
(add-hook 'ess-mode-hook
'(lambda()
(local-set-key (kbd "<tab>") 'ess-indent-or-complete)
))
This works, but I wonder if this is the proper way. In the manual I don't see any prompt to hook to ESS mode and reset tab binding.
Do you know which is the canonical way to perform this?
There are a couple of reasonable ways to set the tab key (or any key, for that matter) for a specific mode. The first you alluded to in your answer, by setting the key locally via a mode hook. Note, though, that it's generally preferable to use a named function rather than a lambda so that you can remove the hook later if you want to do so:
(defun ess-keys-hook ()
"Put a bunch of keybindings in here."
(local-set-key [tab] 'ess-indent-or-complete))
(add-hook 'ess-mode-hook 'ess-keys-hook)
The other option is to define the key in the relevant mode map, which you can do like so:
(define-key ess-mode-map [tab] 'ess-indent-or-complete)
Both ways are pretty commonly used, although my own preference is for the latter, as it strikes me as cleaner and more efficient.

Resources