I need to make a function that will display an image under another image only if the Boolean fire? is #true
here is my code:
(define (render-rocket-fire RocketState FIRE)
(cond
[(or (rocket-state-fire? #true))
(place-image FIRE
(rocket-state-pos-x RocketState)
(+ FIRE-SKIP (rocket-state-pos-y RocketState))
SCENE-WIDTH SCENE-HEIGHT))
[else (
I am confused as to what to put in else to make it so that no image is displayed
This is a really good question, and figuring it out will help you rearrange your brain in a really important way.
What you really need to do is to consult your test cases. Or, if you haven't constructed this test case, write it. Specifically: write a test case that calls render-rocket-fire with a RocketState where the "fire?" field is false. What should the result be? The answer is what should go in the 'else' field.
An outline of a procedure that conditionally combines two images based on the value of a third argument.
(define (maybe-combine-images image1 image2 my-boolean)
(if myboolean
(under image1 image2)
image1)))
The if could be rewritten using a 'two-legged' cond:
(define (maybe-combine-images image1 image2 my-boolean)
(cond
[myboolean (under image1 image2)]
[else image1]))
Related
I want to create helper function that modifies output returned by higher-order function.
Example of higher-order function:
(def use-meta-sub (make-app-fn (make-sub :meta)))
The problem is that when using this in let like this:
(let [meta-sub (use-meta-sub props :get-me-meta-of-this)])
returns map of key-value pairs like this:
{:key-we-almost-never-need-1 nil
:key-we-almost-never-need-2 nil
:key-we-almost-never-need-3 nil
:key-we-almost-never-need-4 nil
:meta-data {:something-useful "foo"
:more-usefull "bar"
:and-so-on "baz"}}
I would like to target only this :meta-data key
I tried this and some other variations:
(defn use-meta-data-sub [props ctrl]
(:meta-data (use-meta-sub props ctrl))) ;; both with get
It does not work because (I think, that returns lazy sequence and I do not know how to actually firs evaluate it and then extract the key from output).
Is this possible without editing 1st higher-order function, and other two it contains?
(I read all documentation on clojure site and clojure-unraveled, either I do not understand them, or they do not cover this)
I am wondering if it is possible to apply Regex-like pattern matching to keys in a plist.
That is, suppose we have a list like this (:input1 1 :input2 2 :input3 3 :output1 10 :output2 20 ... :expand "string here")
The code I need to write is something along the lines of:
"If there is :expand and (:input* or :output*) in the list's keys, then do something and also return the :expand and (:output* or :input*)".
Obviously, this can be accomplished via cond but I do not see a clear way to write this elegantly. Hence, I thought of possibly using a Regex-like pattern on keys and basing the return on the results from that pattern search.
Any suggestions are appreciated.
Normalize your input
A possible first step for your algorithm that will simplify the rest of your problem is to normalize your input in a way that keep the same information in a structured way, instead of inside symbol's names. I am converting keys from symbols to either symbols or lists. You could also define your own class which represents inputs and outputs, and write generic functions that works for both.
(defun normalize-key (key)
(or (cl-ppcre:register-groups-bind (symbol number)
("^(\\w+)(\\d+)$" (symbol-name key))
(list (intern symbol "KEYWORD")
(parse-integer number)))
key))
(defun test-normalize ()
(assert (eq (normalize-key :expand) :expand))
(assert (equal (normalize-key :input1) '(:input 1))))
The above normalize-key deconstructs :inputN into a list (:input N), with N parsed as a number. Using the above function, you can normalize the whole list (you could do that recursively too for values, if you need it):
(defun normalize-plist (plist)
(loop
for (key value) on plist by #'cddr
collect (normalize-key key)
collect value))
(normalize-plist
'(:input1 1 :input2 2 :input3 3 :output1 10 :output2 20 :expand "string here"))
=> ((:INPUT 1) 1
(:INPUT 2) 2
(:INPUT 3) 3
(:OUTPUT 1) 10
(:OUTPUT 2) 20
:EXPAND "string here")
From there, you should be able to implement your logic more easily.
Say I have a set like this:
#{#{"a"} #{"b"} #{"c"}}
Say I wanted to updated the middle set to make s become:
#{#{"a"} #{"be"} #{"c"}}
How would I achieve this?
(-> #{#{"a"} #{"b"} #{"c"}} (disj #{"b"}) (conj #{"be"}))
=> #{#{"a"} #{"be"} #{"c"}}
(of course there's no ordering in sets, it could well be shown in any order).
I would like to select the value from initial-frame-alist, namely the number after width:
initial-frame-alist evals to "((top . 1) (left . 1) (width . 50) (height . 30)))"
I would like to extract the 50, from width. The problem is that for other people this setup might be different, i.e. width would be the first instead of third item (and thus car and the like won't work; positions can be different.
How can I select the part from the list (width . 50) (possibly based on the string "width") after which it is possible to select the second item?
More illustrative example:
(car initial-frame-alist) evaluates to (top . 1)
(car (car initial-frame-alist)) evaluates to top
EDIT: It would also be possible not to care about the list structure, but to treat it as a string, though I would not know how to go about it then either.
(cdr (assoc 'width initial-frame-alist))
assoc is the way to go with alist; it is different from just any list; it is an association list.
i am learning clojure. My question is it posible to use (case) inside (-> ).
For example, i want something like this (this code dont work):
(defn eval-xpath [document xpath return-type]
(-> (XPathFactory/newInstance)
.newXPath
(.compile xpath)
(case return-type
:node-list (.evaluate document XPathConstants/NODESET)
:node (.evaluate document XPathConstants/NODE)
:number (.evaluate document XPathConstants/NUMBER)
)
))
Or will be better to use multimethods instead? What is the right 'clojure way for this?
Thank you.
The arrow macro (->) just rewrites its arguments so that the value of the nth form is inserted as the first argument to the n+1th form. What you are writing is equivalent to:
(case
(.compile
(.newXPath (XPathFactory/newInstance))
xpath)
return-type
:node-list (.evaluate document XPathConstants/NODESET)
:node (.evaluate document XPathConstants/NODE)
:number (.evaluate document XPathConstants/NUMBER)
In a general case you can pick one of the three forms to be your tail form ahead of time using let, and then thread that in at the end of the threading macro. Like so:
(defn eval-xpath [document xpath return-type]
(let [evaluator (case return-type
:node-list #(.evaluate % document XPathConstants/NODESET)
:node #(.evaluate % document XPathConstants/NODE)
:number #(.evaluate % document XPathConstants/NUMBER))]
(-> (XPathFactory/newInstance)
.newXPath
(.compile xpath)
(evaluator))))
However what you are really trying to do is map a keyword to a constant on XPathConstants. This can be done with a map. Consider the following:
(defn eval-xpath [document xpath return-type]
(let [constants-mapping {:node-list XPathConstants/NODESET
:node XPathConstants/NODE
:number XPathConstants/NUMBER}]
(-> (XPathFactory/newInstance)
.newXPath
(.compile xpath)
(.evaluate document (constants-mapping return-type)))))
You have a mapping of keywords to constants, so use Clojure's data structures to express that. Additionally the real value of the threading macro is helping you compile the xpath. Don't be afraid to give the data you're using locally scoped names to help you keep track of what you are doing. It also helps you avoid trying to shoehorn things into the threading macro that really don't want to fit.
Check out the following clojure library for working with xpath expressions: https://github.com/kyleburton/clj-xpath