Two sugars with your Contracts for Clojure Maps
Table of Contents
- 1. Introduction
- 2. A quick summary of clojure-contracts-maps
- 3. A few notes on contracts and constraints
- 4. The Code
- 5. Getters with Simple Contracts
- 6. Putters with Simple Contracts
- 7. Using a telltale to aid diagnosis of assertion errors
- 8. Contracts for Keys with multiple constraints
- 9. Contracts for the Map
- 10. Using Transformation Functions (mappers)
- 11. Using a Monitor
- 12. Multi-Level Keys
- 13. Composing Multi-Level Accessors
- 14. Defining both putter and getter
- 15. Final Words
- 16. Final, Final Words
TL;DR: Using Getters and Putters with Contracts on Clojure Maps
1 Introduction
One of the [Clojure][ClojureHome] projects I've been working on uses multi-level (hierarchical) [maps][HashWikipedia] i.e. the values of the keys of a map at one level are often maps themselves.
A common enough use case and as [Fogus][FogusHome] and [Chris Houser][ChouserHome] observe in their book [The Joy of Clojure][BookJoC2ed] (section 5.6):
It’s difficult to write a program of any significant size without the need for a map of some sort.
The use of maps is ubiquitous in writing software because frankly it’s difficult to imagine a more robust data structure.
Maps have been around quite a while. In their book [Introduction To Algorithms][CormenBookIntroductionToAlgorithms] Cormen et al say Donald Knuth [attributed][CormenBookIntroductionToAlgorithmLuhn] the invention of maps to [Hans Peter Luhn][LuhnWikipedia] in early 1953.
Using [maps][HashWikipedia] is very natural and easy in [Clojure][ClojureHome] and indeed many other languages that support them. Clojure takes [Alan Perlis's][PerlisTuringAward] famous quote to heart by providing a rich set of functions to manage maps:
It’s better to have 100 functions operate on one data structure than 10 functions on 10 data structures.
But using deep (multi-level) maps with many levels and many keys with long-ish descriptive names can make the code look very cluttered and prone to typos, misremembered key names, juxtaposition of levels, and similar, often silent, errors as e.g. get and get-in will return a value (nil) rather than raising an error, and assoc and assoc-in wont care at all.
Its very easy in [Clojure][ClojureHome] to write function(s) to encapsulate the accesses to a key's value, especially for multi-level keys, creating "helper" putter and getter accessors.
Arguably, maybe a stretch, you could think of these accessors as [_higher order_][HigherOrderFunctionWikipedia] functions where the (implicit) input functions are e.g. get or assoc.
For example, and as usual a contrived example, where a deep multi-level map holds all the details of a house:
(defn change-kitchen-temperature [house-state new-temperature] (assoc-in house-state [:rooms :kitchen :properties :temperature] new-temperature))
(defn install-kitchen-oven [house-state new-oven] (assoc-in house-state [:rooms :kitchen :appliances :cooking :oven] new-oven))
Which is nice (at least to me): semantically named accessors hiding the details of the key hierarchy. If the hierarchy needs to change for any reason, only the accessor functions have to be changed. A familiar enough paradigm from many languages.
The other thing I've wanted to do has been to apply [contracts][Eiffel Design by Contract] to the leaf values in the map. You could of course just use an [_assert_][ClojureDocsAssert] to apply a contract to a value in "open code". But that means the contract definition (i.e. assertion clause) is scattered over the code base, hard to change, inconsistency may creep in, etc.
[Fogus's][FogusHome] [clojure.core.contracts][ClojureCoreContractsGithub] library uses [Clojure's][ClojureHome] [:pre and post assertions][FogusBlogClojurePreandPost] to apply contracts to a function's arguments and/or its result (return value).
In my recent [sugar post][RumfordBlogClojureContractsSugar] on contracts, I demonstrated a new library I've written [clojure-contracts-sugar][ClojureContractsSugarGithub] to add some productivity macros ("sugar") atop [Fogus's][FogusTwitter] [library][ClojureCoreContractsGithub].
In a nice bit of synergy, if you use putter and getter accessors for a map's leaf values, you can apply also contracts to them.
Enter my new library: [clojure-contracts-maps][ClojureMapAccessorsGithub]
<!-- more -->
2 A quick summary of clojure-contracts-maps
Apart from the ability to apply rich contracts to the leaf values, the new library support some other features.
One feature useful to have is the opportunity to transform map a key's value. In the case of a getter, the mapper is applied before the value is returned effectively returning a view of the value. In the case of a putter, the mapper can e.g. normalise the value in some way before the map is "updated".
Its also useful, in a getter, to support static and (per call) dynamic defaults for the key's value.
You may also want to monitor a key's access, especially when it changes, and have a unique error message - a telltale - when a value fails a contract.
3 A few notes on contracts and constraints
A contract is made up of one or more constraints.

Getters have spit contracts as the value of the key (or its default) is the result of the getter.
If you want to use a mnemonic (see later) for a contract to apply to both the getter and putter, the mnemonic must have identical constraints for both suck and spit.
The macro define-mnemonics will define a symmetric contract. For example, to define a symmetric mnemonic :key-value-is-a-map-with-numeric-values
(define-mnemonics key-mnemonics {:key-value-is-a-map-with-numeric-values [map? (every? number? (vals arg0))]})
This is the same as the explicit call below to configure-contracts-store in clojure-contracts-sugar
(configure-contracts-store aspect-mnemonic-definitions {:key-value-is-a-map-with-numeric-values {:suck [map? (every? number? (vals arg0))] :spit [map? (every? number? (vals arg0))]}})
Note you can define multiple mnemonics is the call to define-mnemonics, just add more key-value pairs in the key-mnemonics map.
4 The Code
4.1 Jar is on Clojars
The jar is on [Clojars][ClojarsClojureContractsMaps]:
[Leiningen][LeiningenHome] dependency information:
[name.rumford/clojure-contracts-maps "0.1.0"]
[Maven][MavenHome] dependency information:
<dependency> <groupId>name.rumford</groupId> <artifactId>clojure-contracts-maps</artifactId> <version>0.1.0</version> </dependency>
4.2 Code is on Github
The code can be found on [github][ClojureMapAccessorsGithub] as a [Leiningen][LeiningenHome] project so you'll want Leiningen [installed][LeiningenGithub].
The project structure is Maven style but there is only Clojure today i.e. ./src/main/clojure and ./src/test/clojure.
4.3 Tests
There are a number of tests that can be run offering reasonable coverage:
lein test
4.4 Examples
The examples below can be found in the repo's examples folder (specifically ./examples/map-examples) and they can be run using lein:
cd ./examples/map-examples lein run -m map-examples1
The examples use a couple of harness functions - will-work and will-fail - to run tests.
will-work takes as arguments the expected result, the accessor function and a list of the accessor's arguments.
will-fail takes just the accessor function and its arguments and catches the AssertionError expected to be thrown.
;; Helper for accessor examples expected to work. Returns the expected result, else fails (defn will-work [expected-result fn-accessor & fn-args] (assert (= expected-result (apply fn-accessor fn-args))) (println "will-work" "worked as expected" "expected-result" expected-result "fn-accessor" fn-accessor "fn-args" fn-args) expected-result) ;; Helper for accessor examples expected to fail. Catches the expected AssertionError, else fails. (defn will-fail [fn-accessor & fn-args] (try (do (apply fn-accessor fn-args) (assert (println "will-fail" "DID NOT FAIL" "did not cause AssertionError" "fn-accessor" fn-accessor "fn-args" fn-args))) (catch AssertionError e (println "will-fail" "failed as expected" "fn-accessor" fn-accessor "fn-args" fn-args))))
The ./doc folder contains the source of this post: it is an [emacs][emacshome] [org][orgmodehome] file [tangled][orgmodemanualextractsourcecode] to generate the examples project.
5 Getters with Simple Contracts
To define a getter call the define-map-get-accessor macro with its (minimum) arguments:
- the key's name; and
- the contract (constraints) to enforce on the key's value
Remember: getter contracts have spit constraints - the contract is applied to the result of the getter.
5.1 Example - a getter for a key with a numeric value
For example to ensure the value of key :a is a number:
;; Example - a getter for a key with a numeric value ;; This example shows how to define a getter function that ensures the ;; returned value of key :a is a number: (def get-key-a (define-map-get-accessor :a :number)) ;; Explcitly call the function (get-key-a {:a 1}) ;; => 1 ;; But lets use the will-work helper to ensure the result is as expected (will-work 1 get-key-a {:a 1}) ;; => 1
Its worth noting that :number here implies {:spit number?}
5.2 Example - a getter using static and/or dynamic defaults
You can define the getter accessor with a static default value to be returned if the key is not present in the map (exact the same semantics as get with a default value).
Note the contract is applied to the result of the accessor so defaults must comply with the contract.
This is lazy though - if a default is never needed, the contract will never be applied to it.
To provide a static default use the optional parameter default on the call to define-map-get-accessor.
;; Example - a getter with a static default for key :d (def get-key-d (define-map-get-accessor :d :number default 42)) ;; This will work (will-work 42 get-key-d {}) ;; => 42 ;; Note the key is present but its value of nil will fail the :number contract (will-fail get-key-d {:d nil})
Alternatively a dynamic default can be provided as the second argument in a call to the getter.
The dynamic default takes precedence over the static one (if supplied).
;; Example - a getter called with a dynamic, per call, default for key :d ;; The key's value, if present, alway takes precedence over any default (will-work 55 get-key-d {:d 55} 99) ;; => 55 ;; The static default (if supplied) is used if the key is not present (will-work 42 get-key-d {}) ;; => 42 ;; But a per-call dynamic default take precedence over the static one (will-work 99 get-key-d {} 99) ;; => 99 (will-work 567 get-key-d {} 567) ;; => 567
6 Putters with Simple Contracts
A simple putter uses Clojure's assoc function and returns the updated map; the original map is, of course, unchanged.
You can define equivalent putter accessors, constrained in the same way as getters, by calling the define-map-put-accessor macro with its (minimum) parameters (same as for a getter):
- the key's name; and
- the contract (constraints) to enforce on the key's value
Remember: putter contracts have suck constraints - the contract is applied to the argument with (new) value of the key.
6.1 Example - a putter for a key with a numeric value
;; Example - define a putter for the value of key :d which must be a number (def put-key-d (define-map-put-accessor :d :number)) ;; Create a new map with the new value for key :d (def map-with-old-value-of-d {:d 99}) (def map-with-new-value-of-d (put-key-d map-with-old-value-of-d 123)) ;; Using the getter on the updated map will return the new value of :d (will-work 123 get-key-d map-with-new-value-of-d) ;; => 123 ;; The old map is of course unchanged (will-work 99 get-key-d map-with-old-value-of-d) ;; => 99
7 Using a telltale to aid diagnosis of assertion errors
Errors generated by Clojure's [pre and post assertions][FogusBlogClojurePreAndPost] are of type AssertionError.
Although they produce a (Java) stack track and precisely specify the assertion causing the error, they do not provide any information to identify the context of the error i.e. which key suffered the error?
As an aid to providing some context and help identify the cause of the error, you can provide an optional telltale parameter to the accessor function definition. The telltale is a description (string) to be printed if/when an AssertionError occurs.
7.1 Example - a getter with a telltale
;; Example - a getter with a telltale (def get-key-d (define-map-get-accessor :d :number default 42 telltale "The value of key :d was not a number")) ;; The call to get-key-d below will fail with an asertion error (will-fail get-key-d {:d "value of d must be a string else will fail"}) ;; => will fail with message something like: ;; Contract Failure Value >class clojure.lang.PersistentArrayMap< >{:d "value of d must be a string else will fail"}< REASON The value of key :d was not a number
7.2 Example - a putter with a telltale
;; Example - a putter with a telltale (def put-key-e (define-map-put-accessor :e :string telltale "The new value of key :e was not a string")) ;; The call to put-key-e below will fail with an asertion error (will-fail put-key-e {:e ":e is always a string"} 123) ;; => will fail with message something like: ;; Contract Failure Value >class clojure.lang.PersistentArrayMap< >{:d ":e is always a string"}< REASON The new value of key :e was not a string
8 Contracts for Keys with multiple constraints
In the examples so far the contract (constraints) applied to the value of a key has been simple - e.g. just a number or string.
In fact, contracts can be far "richer": You can use anything supported by [clojure-contracts-sugar][ClojureContractsSugarGithub].
Rich contracts were illustrated in my [contracts sugar post][RumfordBlogClojureContractsSugar] and allow one or more constraints to be applied to the key's value.
Multiple constraints can be specified in the definition of the accessor simply as a vector of the individual constraints.
Or you can use mnemonics to "package" rich, complex contracts with multiple constraints, again as described in the [sugar post][RumfordBlogClojureContractsSugar].
Some examples should help flesh this out.
8.1 Example - a getter for a positive numeric key value
To ensure a key's value is a positive number, the contract's vector of constraints would be:
[:number :pos]
;; Example - a getter for a positive numeric key value (def get-key-m (define-map-get-accessor :m [:number :pos] telltale ":m must be a positive number")) ;; This works (will-work 3 get-key-m {:m 3}) ;; => 3 ;; But this will fail (will-fail get-key-m {:m -3}) ;; => And should produce a message like: ;; Contract Failure Value >class clojure.lang.PersistentArrayMap< >{:m -3}< KEY :m REASON :m must be a positive number
8.2 Example - a getter to ensure a key's value is a map with keyword keys and numeric values
Using an example based on one in the [sugar post][RumfordBlogClojureContractsSugar], this one needs to ensure a key's new value is a map, and its keys are keywords and the values are numbers. The contract is:
[:map (every? keyword? (keys arg0)) (every? number? (vals arg0))]
Note the key's value is available for use explicitly in the contract as arg0 - see the [sugar post][RumfordBlogClojureContractsSugar] for an explanation of the use of relative argument names such as arg0.
;; Example - a getter to ensure a key's value is a map with keyword keys and numeric values ;; Note the constraint form uses arg0 to refer to the passed map (def get-key-n (define-map-get-accessor :n [:map (every? keyword? (keys arg0)) (every? number? (vals arg0))] telltale ":n must be a map with keywords keys and numeric values")) ;; This works (will-work {:a 1 :b 2 :c 3} get-key-n {:n {:a 1 :b 2 :c 3}}) ;; => {:a 1 :b 2 :c 3} ;; But this will fail (will-fail get-key-n {:n {"x" 1 "y" 2 "z" 3}}) ;; => And should produce a message like: ;; Contract Failure Value >class clojure.lang.PersistentArrayMap< >{:n {"x" 1, "y" 2, "z" 3}}< KEY :n REASON :n must be a map with keywords keys and numeric values
8.3 Example - a getter with a custom predicate
You can define your own predicate functions, not just use [Clojure's][ClojureHome] "built-ins" (e.g. map?, number?, string?, etc). For example, a predicate function to ensure the value is a map with keywords keys and numeric values would be something like this:
;; Example - a custom predicate to ensure a map's keys are keywords and values are numeric (defn is-map-with-keyword-keys-and-numeric-values? [source-map] {:pre [(map? source-map) (every? keyword? (keys source-map)) (every? number? (vals source-map))]} source-map)
The custom predicate can be used in the accessor definition just like a "built-in":
;; Example - a rich getter using a custom predicate (def get-key-p (define-map-get-accessor :p is-map-with-keyword-keys-and-numeric-values? telltale ":p failed predicate is-map-with-keyword-keys-and-numeric-values?"))
This example again is based loosely on one in my [sugar post][RumfordBlogClojureContractsSugar] and demonstrates how to implement the is-map-with-keyword-keys-and-numeric-values? predicate function using a mnemonic.
Note the example uses the sugar macro define-mnemonics to simplify the definition of a symmetric (i.e. suck and spit) contract suitable for use in the definition of both a getter (spit) and putter (suck).
;; Define a custom mnemonic map-special ensuring a map with keyword keys and numeric values. ;; Note the mnemonic is suitable for a both a getter and putter i.e it has the same *suck* and *spit* constraints (define-mnemonics key-mnemonics {:key-value-is-a-map-with-numeric-values [map? (every? number? (vals arg0))]})
The example:
;; Example - a getter with a custom mnemonic for the key ;; Use the :key-value-is-a-map-with-numeric-values mnemonic for the key contract ;; to ensure the key's value is a map with numeric values. (def get-key-q (define-map-get-accessor :q :key-value-is-a-map-with-numeric-values telltale ":q failed contract key-value-is-a-map-with-numeric-values")) ;; This works (will-work {:a 1 :b 2 :c 3} get-key-q {:q {:a 1 :b 2 :c 3}}) ;; => {:a 1 :b 2 :c 3} ;; But this will fail (will-fail get-key-q {:q {:a :one :b :two :c :three}}) ;; => And should produce a message like: ;; Contract Failure Value >class clojure.lang.PersistentArrayMap< >{:q {:a :one :b :two :c :three}}< KEY :q REASON :q failed contract key-value-is-a-map-with-numeric-values
9 Contracts for the Map
So far, I've not said anything about the map argument itself, or whether a contract (constraints) is applied to it.
In fact, behind the scenes, a contract is applied automatically to the map but its minimal: just map?
But the default contract for the map can be overidden using the map-contract parameter on the call to e.g. define-map-get-accessor.
Just like contracts for a key, map contracts can be anything supported by [clojure-contracts-sugar][ClojureContractsSugarGithub], especially mnemonics.
9.1 Example - applying a contract to the map itself
In the example below the sugar macro define-mnemonics defines a contract suitable for the map argument (specifically a suck-only contract).
It also defines a key mnemonic to ensure the key's value is a map with positive numeric values.
;; Example - applying a contract to the map itself ;; Define the mnemonics (define-mnemonics map-mnemonics {:map-with-keyword-keys [map? (every? keyword? (keys arg0))]} key-mnemonics {:key-is-a-map-with-positive-numeric-values [map? (every? number? (vals arg0)) (every? pos? (vals arg0))] }) ;; Use both contracts (def get-key-q (define-map-get-accessor :q :key-is-a-map-with-positive-numeric-values map-contract :map-with-keyword-keys telltale ":q failed key contract key-is-a-map-with-positive-numeric-values or map contract map-with-keyword-keys")) ;; This works (will-work {:a 1 :b 2 :c 3} get-key-q {:q {:a 1 :b 2 :c 3}}) ;; => {:a 1 :b 2 :c 3} ;; But this will fail as the value of :a is -1 (will-fail get-key-q {:q {:a -1 :b 2 :c 3}}) ;; => And should produce a message like: ;; Contract Failure Value >class clojure.lang.PersistentArrayMap< >{:q {:a -1 :b 2 :c 3}}}< KEY :q REASON :q failed key contract :key-is-a-map-with-positive-numeric-values or map contract map-with-keyword-keys
10 Using Transformation Functions (mappers)
10.1 Example - putters with mappers
Sometimes its useful to be also to transform - map - the (new) value of a key before putting into the map. For example to normalise the value in some way (e.g. - trivially - string-ify and lower case).
To provide a transformation function, use the mapper parameter on the call to define-map-putter. Your can specify more than one mapper - just provide a vector of them. Multiple mappers are applied in the same order as [comp][ClojureDocsComp] i.e. rightmost first.
Note the key's contract is applied to the transformed value.
The example has a mapper that just converts the argument into a string and counts the number of characters. (Note the stringified keyword includes the leading colon.)
;; Example - putters with mappers (def put-key-f (define-map-put-accessor :f :number mapper (fn [s] (count (str s))) telltale ":f must be a number")) ;; These will work (will-work {:f 6} put-key-f {} "6chars") (will-work {:f 7} put-key-f {} :7chars)
10.2 Example - getters with mappers
In a similar vein, for a getter, there may be times when it is useful to transform the key's value before it is returned.
For example, defining additional getters for the same key that holds a map to return views of the value e.g. just the keys, just the values, the sum of the values, whatever. Or, perhaps, create a derivative value e.g. instantiate a Java class instance.
When using a mapper with a getter, the contract (e.g. :number) is applied to the transformed value, not the value itself (e.g. :map). (You could apply a contract to the key's actual value using the map contract.)
Note in the example below a key mnemonic is applied to the map. This is ok; only the suck constraints in the key mnemonic will be applied to the map.
The example also shows how mnemonics can be composed - see the [sugar post][RumfordBlogClojureContractsSugar] for details. Composed mnemonics in the call to define-mnemonics are:
:key-is-a-map-with-keyword-keys-and-postive-numeric-values [:map-with-keyword-keys :map-with-positive-numeric-values]
and
:collection-of-positive-numeric-values [:collection-of-numeric-values (every? pos? arg0)]
The example:
;; Example - getters with mappers ;; Define some mnemonics. Note a key contract mnemonic is applied to the ;; map. Also mnemonics are composed (define-mnemonics key-mnemonics {:map-with-keyword-keys [map? (every? keyword? (keys arg0))] :map-with-positive-numeric-values [map? (every? number? (vals arg0)) (every? pos? (vals arg0))] :key-is-a-map-with-keyword-keys-and-postive-numeric-values [:map-with-keyword-keys :map-with-positive-numeric-values] :collection-of-keywords [(coll? arg0) (every? keyword? arg0)] :collection-of-numeric-values [(coll? arg0) (every? number? arg0)] :collection-of-positive-numeric-values [:collection-of-numeric-values (every? pos? arg0)]}) (def get-key-g (define-map-get-accessor :g :key-is-a-map-with-keyword-keys-and-postive-numeric-values map-contract :map-with-keyword-keys telltale ":g must be a map with keyword keys and postivie values")) ;; Define extra getters for the keys and values of :g's map, ;; both of which must be collections (coll?) of keywords or positive ;; numeric values (def get-key-g-keys (define-map-get-accessor :g :collection-of-keywords map-contract :map-with-keyword-keys mapper (fn [m] (keys m)) telltale ":g keys must be a collection")) (def get-key-g-vals (define-map-get-accessor :g :collection-of-positive-numeric-values map-contract :map-with-keyword-keys mapper (fn [m] (vals m)) telltale ":g values must be a collection")) ;; Test data (def test-map1 {:g {:a 1 :b 2 :c 3}}) (def test-map1-g-keys (keys (:g test-map1))) (def test-map1-g-vals (vals (:g test-map1))) ;; Test the keys (will-work test-map1-g-keys get-key-g-keys test-map1) ;; => '(:a :c :b) ;; Test the values (will-work test-map1-g-vals get-key-g-vals test-map1) ;; => '(1 3 2) ;; Another getter to sum the values (def get-key-g-sum-vals (define-map-get-accessor :g :number mapper (fn [m] (apply + (vals m))) telltale ":g values sum must be a number")) (will-work 6 get-key-g-sum-vals test-map1) ;; => 6
11 Using a Monitor
A monitor provides a hook to call an arbitrary function in an accessor. The result of a monitor is ignored. Monitors can be used for any purpose e.g. logging, diagnostics, communications with other processes, whatever.
A monitor is specified using the monitor parameter.
11.1 Example - a getter with a monitor
If provided, the monitor function in a getter is called with at least the following arguments:
- the key name;
- the key value (transformed if required); and
- the original (argument) map.
You can, optionally, add your own additional arguments using the monitor-args parameter, and these are passed "as-is" to the monitor function after the other arguments. The monitor-args should be a vector.
;; Example - a getter with a monitor ;; This is the monitor function (defn monitor-get-key-j [key-name key-value arg-map & opt-args] (println "monitor-get-key-j" "key-name" key-name "key-value" key-value "arg-map" arg-map "opt-args" (count opt-args) opt-args)) (def get-key-j (define-map-get-accessor :j :number monitor monitor-get-key-j monitor-args ["opt arg1" 2 :three])) ;; The getter works as usual (will-work 456 get-key-j {:j 456}) ;; => 456 ;; And should display the monitor message: ;; monitor-get-key-j key-name :j key-value 456 arg-map {:j 456} opt-args 3 (opt-arg1 2 :three)
11.2 Example - a putter with a monitor
If provided, a putter's monitor function is called always with the following arguments:
- the key name;
- the key value (transformed if require);
- the original (argument) map; and
- the new (updated) map.
As with a getter, and optionally, you pass your own additional arguments using the monitor-args parameter.
;; Example - a putter with a monitor ;; This is the monitor function (defn monitor-put-key-k [key-name key-value arg-map new-map] (println "monitor-put-key-k" "key-name" key-name "key-value" key-value "arg-map" arg-map "new-map" new-map)) (def put-key-k (define-map-put-accessor :k :string monitor monitor-put-key-k)) ;; The putter works as usual (will-work {:k "new value of key :k"} put-key-k {:k "old value of key :k"} "new value of key :k") ;; => {:k "new value of key :k"} ;; And should produce message like: ;; monitor-put-key-k key-name :j key-value 456 arg-map {:k "old value of key :k"} new-map {:k "new value of key :k"}
12 Multi-Level Keys
You can also define accessors with multilevel keys and use (define) them in an equivalent way as when using get-in and assoc-in directly by providing a vector containing the key hierarchy in a call to e.g. define-map_get_accessor.
12.0.1 Example - Explicit Multi-Level Getters
In these getter examples the value of multilevel key [:a :b :c] must be a string:
;; Example - Explicit Multi-Level Getters ;; This example shows how to define a getter function that ensures the ;; returned value of multi-level key [:a :b :c] is a string. It also supplies a ;; static default. (def get-key-abc (define-map-get-accessor [:a :b :c] :string default "static default for multilevel key [:a :b :c]" telltale "The value of multilevel key [:a :b :c] must be a string")) (will-work "value for multilevel key [:a :b :c]" get-key-abc {:a {:b {:d 4 :c "value for multilevel key [:a :b :c]"}}}) ;; => "value for multilevel key [:a :b :c]" ;; The below will fail as [:a :b :c] is not a string (will-fail get-key-abc {:a {:b {:d "value of [:a :b :d]" :c 99}}}) ;; => message something like ;; Contract Failure Value >class clojure.lang.PersistentArrayMap< >{:a {:b 99}}< KEY :a :b REASON The value of multilevel key [:a :b :c] must be a string ;; Static Defaults work as expected (will-work "static default for multilevel key [:a :b :c]" get-key-abc {}) ;; => "static default for multilevel key [:a :b :c]" ;; Dynnamic Defaults work as expected (will-work "dynamic default for multilevel key [:a :b :c]" get-key-abc {} "dynamic default for multilevel key [:a :b :c]") ;; => "dynamic default for multilevel key [:a :b :c]" ;; This will also work because, although the map does not have enough levels, the static default will be returned (will-work "static default for multilevel key [:a :b :c]" get-key-abc {:a {:b "value of b is not a map so key c can not exist"}}) ;; => "static default for multilevel key [:a :b :c]"
12.0.2 Example - Explicit Multi-Level Putters
Multilevel putters works equivalently.
;; Example - Explicit Multi-Level Putters ;; This example shows how to define a putter function for the string multilevel key [:a :b]: (def put-key-ab (define-map-put-accessor [:a :b] :string telltale "The value of multilevel key [:a :b] must be a string")) (will-work {:a {:b "cd"}} put-key-ab {:a {:b "ab"}} "cd") ;; => {:a {:b "cd"}} ;; The below will fail as [:a :b] is not a string (will-fail put-key-ab {:a {:b "ab"}} 99) ;; => message something like ;; Contract Failure Value >class clojure.lang.PersistentArrayMap< >{:a {:b "ab"}}< KEY :a :b REASON The value of multilevel key [:a :b] must be a string
13 Composing Multi-Level Accessors
You might find it useful to be able to compose a (new) accessor using an existing one.
For example you may want to define a "leaf" accessor for a key at the lowest level and then compose the leaf accessor with keys from the other, higher levels. The point being that if the leaf key is used in more than one multilevel map, the leaf accessor only has to be defined once.
Your can also e.g. use a mapper with a composed accessor and enforce a different contract on the mapped (derived) key value. In the example below the composed accessor get-key-z-from-pq defines a mapper to count the characters in the expected string and applies a :number contract to the mapped value. The leaf accessor get-key-z ensures the value fed into the mapper is a :string. (Note you can't use a dynamic default in this case because the :number contract will fail a :string supplied as the dynamic default.)
13.0.1 Example - composing a getter
In this example the leaf accessor is for key :z.
;; Example - composing a getter ;; Define the leaf accessor for key :z (def get-key-z (define-map-get-accessor :z :string default "static default for key :z" telltale "The value of :z must be a string")) ;; Compose the leaf with a keys [:a :b] (def get-key-z-from-ab (compose-map-get-accessor [:a :b] get-key-z)) ;; This will work (will-work "multilevel key [:a :b :z] value" get-key-z-from-ab {:a {:b {:d 4 :z "multilevel key [:a :b :z] value"}}}) ;; => "multilevel key [:a :b :z] value" ;; The below will fail as [:a :b :z] is not a string (will-fail get-key-z-from-ab {:a {:b {:d "value of [:a :b :d]" :z 99}}}) ;; Defaults are hierachical and the "leafiest" one wins (will-work "static default for key :z" get-key-z-from-ab {}) ;; => "static default for key :z" (will-work "dynamic default for key :z" get-key-z-from-ab {} "dynamic default for key :z") ;; => "dynamic default for key :z" ;; Compose the leaf with keys [:p :q] *and* use a mapper to return a number (def get-key-z-from-pq (compose-map-get-accessor [:p :q] get-key-z mapper (fn [x] (count x)) key-contract :number)) (will-work 20 get-key-z-from-pq {:p {:q {:z "a string of 20 chars"}}} ) ;; => 20
Finally, there is no actual restriction on leaf accessors being for just one level; they can be multilevel.
14 Defining both putter and getter
The definitions of a getter and putter for the same key share common arguments and its likely both accessors would be required. As a convenience, you can define both the putter and getter in one call to the define-map-accessors macro.
The base name of the accessors can be supplied using the optional name argument and the getter and putter names are generated from it. For example if name is the-v-key then the putter name will be put-the-v-key and the getter get-the-v-key. The value of name can be anything, it is "stringified" (using str) as necessary.
Alternatively, you can explicitly specify the names of each accessor using the get-name and put-name parameters respectively. These take priority over name.
If no name, get-name or put-name parameters are provided, the name will be derived from the name of the key. So if the key's name is :x, the accessors will be get-x and put-x.
Other, accessor-specific parameters can be provided using the regular parameter (e.g. telltale monitor mapper etc) prefixed by get- or put-.
14.0.1 Example - defining both accessors together
;; Example - defining both accessors together ;; The base name of the accessors has been provided: "the-v-key" (define-map-accessors :v is-map-with-keyword-keys-and-numeric-values? name the-v-key telltale ":p failed predicate is-map-with-keyword-keys-and-numeric-values?")
Using the library, its possible to apply Clojure's [pre and post conditions][FogusBlogClojurePreAndPost] to a map's key accesses in the same way as they can be applied to a function's arguments. The power of [clojure-contracts-sugar][ClojureContractsSugarGithub] (and implicitly [core.contracts][ClojureCoreContractsGithub]) allows for a very rich sets of constraints to be applied to a key's value.
The opportunity to define the access "semantics" of a map's key via regular functions, ensuring the semantics are adhered to and/or applied consistently, is a useful and easy-to-use program-correctness aid.
Using mappers with a getter provide a simple way of generating views of a key's value, without affecting the original value. Conversely, mappers with a putter facilitate e.g normalising the key's (new) value before storing in the (updated) map.
Monitors provide a simple way of adding arbitrary, but neutral non-affecting logic, to the key's access. And a telltale helps pin down where things went wrong.
16 Final, Final Words
I've done a fair amount of Ruby meta programming. An essential difference is [Clojure][ClojureHome] macros are compile-time whereas Ruby is run-time.
But doing macro metaprogramming feels quite different: [Clojure][ClojureHome] works with values ([homoiconicity][HomoiconicityWikipedia]) whereas Ruby metaprogramming works with text that is eval-ed.
One of the most noticeable differences I've found though (maybe just my style) is whereas in Ruby you build the complete code-as-text, with macros you can take an iterative approach i.e a top level macro returns one or more "calls" to lower level more-focused macros.
There does seem to be a bit of a meme in the community along the lines of "If you are using a macro you are doing it wrong". But, used wisely, macros are a fantastic (and sometimes essential) tool.
But the objectives are the same whether Ruby or Clojure - removing boilerplate and getting to the heart of the problem rather than distracted by implementation details.
[ClojureHome]: http:///clojure.org [JavaHome]: http://www.java.com [LeiningenHome]: http://leiningen.org/ [LeiningenGithub]: https://github.com/technomancy/leiningen [MavenHome]: http://maven.apache.org/ [ClojarsHome]: http://clojars.org [ClojarsClojureContractsMaps]: https://clojars.org/name.rumford/clojure-contracts-maps [ClojureCoreContractsGithub]: https://github.com/clojure/core.contracts [ClojureContractsSugarGithub]: https://github.com/ianrumford/clojure-contracts-sugar [ClojureMapAccessorsGithub]: https://github.com/ianrumford/clojure-contracts-maps [ClojureCoreContractsPostFirstTake]: http://ianrumford.github.io/blog/2012/11/17/first-take-on-contracts-in-clojure/ [FogusBlogClojurePreAndPost]: http://blog.fogus.me/2009/12/21/clojures-pre-and-post/ [EmerickHome]: http://cemerick.com/ [GrandHome]: http://clj-me.cgrand.net/ [CarperHome]: http://briancarper.net/ [ClojureProgrammingBook]: http://www.clojurebook.com/ [FogusHome]: http://blog.fogus.me [FogusTwitter]: https://twitter.com/fogus [CHouserHome]: http://old.n01se.net/chouser [BookJoC2ed]: http://www.manning.com/fogus2 [RumfordBlogClojureContractsSugar]: http://ianrumford.github.io/blog/2014/02/19/a-little-sugar-with-your-clojure-aspect-contracts/ [RumfordBlogClojureContractsFirstTake]: http://ianrumford.github.io/blog/2012/11/17/first-take-on-contracts-in-clojure/ [emacshome]: http://www.gnu.org/software/emacs/ [orgmodehome]: http://orgmode.org/ [orgmodemanualextractsourcecode]: http://orgmode.org/org.html#Extracting-source-code [PerlisTuringAward]: http://amturing.acm.org/award_winners/perlis_0132439.cfm [HashWikipedia]: http://en.wikipedia.org/wiki/Hash_table [CormenBookIntroductionToAlgorithms]: http://www.amazon.co.uk/Introduction-Algorithms-Thomas-H-Cormen/dp/0262032937/ref=sr_1_1?s=books&ie=UTF8&qid=1392992028&sr=1-1&keywords=0262032937 [CormenBookIntroductionToAlgorithmLuhn]: http://books.google.co.uk/books?id=NLngYyWFl_YC&pg=PA252&lpg=PA252&dq=luhn+hash+tables&source=bl&ots=BxWoJG3mJa&sig=cTpYRKlO-rNe8TDar3ko8bv4MQ8&hl=en&sa=X&ei=0UIHU662DKap7Abp1IHgCA&ved=0CFoQ6AEwBg#v=onepage&q=luhn%20hash%20tables&f=false [LuhnWikipedia]: http://en.wikipedia.org/wiki/Hans_Peter_Luhn [JavaWikiHashmap]: http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html [HigherOrderFunctionWikipedia]: http://en.wikipedia.org/wiki/Higher-order_function [Eiffel Design by Contract]: http://en.wikipedia.org/wiki/Eiffel_(programming_language)#Design_by_Contract [ClojureDocsAssert]: http://clojuredocs.org/clojure_core/clojure.core/assert [ClojureDocsComp]: http://clojuredocs.org/clojure_core/clojure.core/comp [HomoiconicityWikipedia]: http://en.wikipedia.org/wiki/Homoiconicity


smoke.js
i made a simple smoke library in javascript.
you can download it from github
and use it make a customizable smoke effect on any website as simply as including the following:
<script src="url/for/smoke.js"></script>
<script>
new Smoke();
</script>
here's what it looks like:
by default it will appear in the center of the page or the center of a specified html element.
you can make it appear in a particular position within an html element with code like this:
<script>
new Smoke({
parent: document.querySelector('.some-element-class-name'),
x: 100,
y: 100
});
</script>
you can change the size and number of sprites (the circles that make up the smoke).
the default sprite radious is 50 pixels and the default number of sprites is 16.
<script src="url/for/smoke.js"></script>
<script>
new Smoke({
spriteCount: 30,
spriteRadious: 25,
});
</script>
you can also adjust the color.
the simplest way to do so is by specifying the foreground property as an array of integers [RED, GREEN, BLUE]
.
each integer should be between 0 and 255 and will determine how much red green or blue to add to the color.
for example, to make green smoke:
<script src="url/for/smoke.js"></script>
<script>
new Smoke({
foreground: [0, 255, 0]
});
</script>
you can also get more complicated.
the sprites are drawn using a css radial-gradient.
the foreground property determines the color at the center of each sprite and as we go from the center outwards to the circumference the color will fade first the midground color then to the background color.
by default the midground and background properties will simply be the same as the foreground but with a lower alpha value (aka opacity).
we can specify opacity as a fourth element of each array that is between 0 and 1 (default 1 for foreground, 0.6 for midground, 0 for background).
you could for example make each sprite yellow in the center, green in a ring around then and then finally red (and we'll increase the opacity of the background so that we can see it):
<script src="url/for/smoke.js"></script>
<script>
new Smoke({
foreground: [255, 255, 0],
midground: [0, 255, 0],
background: [255, 0, 0, 0.3]
});
</script>
you can also more simply modify the overall opacity of the smoke:
<script src="url/for/smoke.js"></script>
<script>
new Smoke({
foreground: [0, 255, 0],
opacity: 0.4
});
</script>
you can make the smoke move at a different speed. by default there is a 200 milisecond delay between animation frames.
<script src="url/for/smoke.js"></script>
<script>
new Smoke({
foreground: [0, 144, 255],
animationMiliseconds: 1000
});
</script>
you can even customize the way that the smoke moves and fades.
you do this by defining the functions that determine how each sprite's x and y coordinates, radious, and opacity changes each frame.
below for reference are the relevant options with their default functions.
smoke.random
takes a minimum value and a maximum value and returns a randome number in between the two.
<script src="url/for/smoke.js"></script>
<script>
new Smoke({
deltaRadious: (smoke) => {
return - smoke.options.spriteRadious / smoke.options.spriteCount;
},
deltaY: (smoke, sprite) => {
return (sprite.y - smoke.y > 5) ? -10 : smoke.random(-25, 10);
},
deltaX: (smoke, sprite) => {
return smoke.random(-20, 15);
},
deltaOpacity: (smoke) => {
return - 1 / smoke.options.spriteCount;
}
});
</script>
you could also change things up as follows:
have the radious decrease half as slowly so they stay bigger longer
have each sprite rise at a constant rate of 10 pixels per frame
have each sprite move to the right a random number of pixels between 0 and 10
keep the opacity at 1 for each sprite until it disappears
<script src="url/for/smoke.js"></script>
<script>
new Smoke({
deltaRadious: (smoke) => {
return - 0.5 * smoke.options.spriteRadious / smoke.options.spriteCount;
},
deltaY: () => {
return -10;
},
deltaX: (smoke, sprite) => {
return smoke.random(0, 10);
},
deltaOpacity: (smoke) => {
return 0;
}
});
</script>


[GJC-4] Create genjava-xmlparser and genjava-props | |
| Status: | Closed |
| Project: | Genjava |
| Component/s: | |
| Affects Version/s: | |
| Fix Version/s: |
| Type: | Task | Priority: | Major |
| Reporter: | Henri Yandell | Assignee: | Henri Yandell |
| Resolution: | Fixed | ||
| Environment: |
| Description |
| I'd like to take the properties implementations out of the simple-jndi setup. I'd then like to make them their own jar, though would also need the XML parser as its own jar again. So idea is to experiment with lots of small jars. Now that I'm better at handling releases etc. genjava-core would become a multi-project, so would need some maven learning there. |
| Comment by bayard [ Mon, 15 Sep 2003 21:36:09 -0700 (PDT) ] |
| genjava-scraper is a possible to take out. It would end up with XmlW, HtmlW, HtmlScraper. Also worth removing is the beans package and the random package. All the proxy stuff together. Unsure what the name would be. The jdbc package really ought to die in favour of dbutils. io stuff needs to go in various directions. math be folded into lang? or just folded? Mailer should go into its own piece. Would need some more work then. |
| Comment by bayard [ Tue, 18 Nov 2003 18:02:11 -0800 (PST) ] |
| Also genjava-csv. |
| Comment by bayard [ Sat, 6 Dec 2003 13:34:09 -0800 (PST) ] |
| This is all now done in the new genjava/ cvs module and not the genjava-core/ module. Ready for release and a new site. |


Listening.
I have had a great opportunity to practice mindful listening this weekend as I have taken some friends up to the tropical KC. They have spent two months traveling around the south island and have had a truly wonderful experience. They have so many tales to tell of their trip and also of news/gossip from home to share with my wife, as she spent a few years over there.
I didn’t let them in on the fact that I was doing it to begin with to be fair but I’m sure they wouldn’t have minded. It was interesting to watch the dynamic of the three of them all trying to share their thoughts simultaneously. In an innocent and non competitive way to be sure, but still I wondered how much information was lost as the conversation skipped and jumped to one subject to another. Some threads followed and some potentially fascinating ones lost entirely.
Afterwards I practiced in earnest with da missus for the three minutes and after a brief feeling of self consciousness we really enjoyed it.
Walking.
I also had the luxury of Waikanae beach to practice mindful walking. I walk a lot. In fact I decided at age 15 not to ever have credit cards or car keys. So I walk a lot.
Back in the day I read about a group of Zen monks in japan who practiced walking meditation (as well as gravel raking) and the aim was to reach a stage where there was no differentiation between the monk, the path or anything else really. There was just ‘walking’. I have always remembered that and am glad that it’s now part of my homework.
I generally spend my walking time to gather my thoughts and mull over things ( as well as being mindful of pesky distractions like traffic ) but this week I have had a good crack at not thinking. Instead of concentrating on just breathing I used the sound of the waves which is probably cheating but hey use it or lose it right ?


{% extends "layout.html" %} {% block body %} Search by Genre Here are the top genres that users search for: {% for genre in genre_names %} {{ genre[1] }} {% endfor %} Search by Popularity Here are the most popular podcasts peoplea are listening to: Top 25 Podcasts {% endblock %}


Back to GitHub Repo
Bulma Switch Controls
No JS.


a web developer
Tribute Page
Random Quote Machine
javascript calculator
Map
Wikipedia
Tic Tac Toe Game
How do you take your coffee?
Let's work together...
How do you take your coffee?


|
BL3 SDK
0.0.1
Borderlands 3 Class Documentation
|
#include <BL3_GbxTest_classes.hpp>
Static Public Member Functions | |
| static UClass * | StaticClass () |
| Static Public Member Functions inherited from UAssetTraitMesh | |
| static UClass * | StaticClass () |
| Static Public Member Functions inherited from UAssetTrait | |
| static UClass * | StaticClass () |
| Static Public Member Functions inherited from UDataAsset | |
| static UClass * | StaticClass () |
| Static Public Member Functions inherited from UObject | |
| static FChunkedFixedUObjectArray & | GetGlobalObjects () |
| template<typename T > | |
| static T * | FindObject (const std::string &name) |
| static UClass * | FindClass (const std::string &name) |
| template<typename T > | |
| static T * | GetObjectCasted (std::size_t index) |
| static UClass * | StaticClass () |
Additional Inherited Members | |
| Public Member Functions inherited from UObject | |
| std::string | GetName () const |
| std::string | GetFullName () const |
| bool | IsA (UClass *cmp) const |
| void | ProcessEvent (class UFunction *function, void *parms) |
| void | ExecuteUbergraph (int EntryPoint) |
| Static Public Attributes inherited from UObject | |
| static FUObjectArray * | GObjects |
|
inlinestatic |
| struct FOptionalBool CastShadow |
| struct FOptionalBool EnableCollision |
| struct FOptionalLODGroup LODGroup |
| struct FOptionalInt32 MaxLightMapIndex |
| struct FOptionalInt32 MaxLightmapResolution |
| struct FOptionalInt32 MaxPrimitiveCount |
| struct FOptionalInt32 MinLightMapIndex |
| struct FOptionalInt32 MinLightmapResolution |
| struct FOptionalInt32 MinPrimitiveCount |
| unsigned char UnknownData00[0x4] |


Multi-Unit ROI Calculator
load list
remove last
clear list
clear page
add to list
ROI
Address
Downpayment
Mortgage
Monthly Income


"Run as Specific User" restricts the job configuration only to the specified user. Other users cannot configure the job even if the Jenkins access control configuration allows it.
This option disabled that feature, and the job configuration is controlled by the Jenkins access control.
Use this feature carefully, for a malicious user can run unintended commands without authentication by changing configuration of the job. Check the access control configuration, and ensure that the CONFIGURE permission for this job is granted only to proper users.


The Antarctica image was from here:
https://www.abercrombiekent.com/travel-destinations/antarctica-cruise/
The css reset used in the css code was found on
http://meyerweb.com/eric/tools/css/reset/
The polar bear is from http://www.sciencepart.com/tag/global-warming/
The gif of global temperature change from 1850-2016 is from http://www.dailymail.co.uk/sciencetech/article-3587124/Climate-change-summed-one-animation-Gif-shows-world-warmed-past-76-years.html"
The pixelated gif of the earth was created by Adam Robertson
This site was programmed by Adam Robertson, "Bubadabado", "SpoonMan", "globalwarming" (all the same person)
Note: the code in this site is protected by the MIT license:
Copyright (c) 2017 Adam Robertson, "Bubadabado", "SpoonMan", "globalwarming"
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
 IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


Create a new repository on your favourite version control platform (for example GitHub, GitLab or BitBucket). This repository will become the forked repository that contains the content and versioning history of the original repository you already had.
Clone your new repository to have a local copy that we can modify.
git clone https://github.com/USERNAME/FORKED_REPO.git
Go to the new directory that was created by cloning the repository. It bears the name of your forked repository.
cd forked-repo
Now that your are in the directory of your forked repository, we can add the original repository as a remote upstream repository to our forked repository. This means we can update the forked repository with the content and versioning history of original repository.
git remote add upstream https://github.com/USERNAME/ORIGIANL_REPO.git
Before we add the code from the original repository, it's a good idea to verify we have added the correct upstream. We wouldn't want to add the wrong code and versioning history in our forked repository, right?!
$ git remote -v
> origin https://github.com/YOUR_USERNAME/FORKED_REPO.git (fetch)
> origin https://github.com/YOUR_USERNAME/FORKED_REPO.git (push)
> upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPO.git (fetch)
> upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPO.git (push)
A last thing we need to do before updating the forked repository is to tell git how we want the commits of the original repository to be applied, namely as a merge
or a rebase
:
git config pull.rebase false # merge (the default strategy)
git config pull.rebase true # rebase
Finally we are ready to update our forked repository with all the commits and history of our original repository. We pull the changes from the upstream remote into our main branch of the local forked repository.
git pull upstream main
Because all the changes we've done (pulling the commits from the original repository into our forked repository) are done on our local copy of the forked repository, we still need to push our local version to the remote version of the new forked repository:
git push
Now, your forked repository on your versioning platform should also contain the commits of your original repository. Later, if you want to update your repository with the new commits of the original repository, you can do step 6. and 7. again.


Function
| Static Public Summary | ||
| public |
Clears all saved containers. |
|
| public |
composeContainers(root: Element | Container, containers: ...Element | Container | String): Container Compose a container from containers or DOM elements. |
|
| public |
createContainer(domElement: Element, initialState: Object, reducers: ...Function): Container Create a new Container instance with optional initial state and n reducers. |
|
| public |
Generates a unique hex ID for Container instances. |
|
| public |
fetchContainer(arg: String | Element | Object): class Container Fetch a saved container by container ID, DOM element, or by a container instance. |
|
| public |
forEachContainer(fn: Function, scope: Object) Execute a function for each container. |
|
| public |
getAllContainers(): MapIterator<String, Container> Returns an interator for all containers. |
|
| public |
getContainerData(arg: Container | Element | String): Object Returns immutable private stardux data for a given input. |
|
| public |
makeContainer(domElement: Element): Container Creates a or returns a new Container instance from a given DOM element. |
|
| public |
realignContainerTree(container: Container, recursive: Boolean, forceOrphanRestoration: Boolean) Realign container DOM tree by removing containers not found in container DOM tree. |
|
| public |
Removes a container from the internal tree. |
|
| public |
replaceDOMElement(container: Container, domElement: Element): Container Replace container element with another. |
|
| public |
restoreContainerFromJSON(json: Object, initialState: Object, reducers: ...Function): Container Create or restore a Container instance from a JSON object with an optional state object a reducers. |
|
| public |
restoreOrphanedTree(container: Container | Element, recursive: Boolean) Restores orphaned children containers still attached to a container. |
|
| public |
saveContainer(container: Container | Element): Boolean Save a container to the known containers map. |
|
| public |
traverseContainer(container: Container, fn: Function, scope: Object) Traverse a container's tree recursively. |
Static Public
public clearContainers(): undefined source
import {clearContainers} from 'stardux/src/index.js'
Clears all saved containers. This will call removeContainer for every saved container.
public composeContainers(root: Element | Container, containers: ...Element | Container | String): Container source
import {composeContainers} from 'stardux/src/index.js'
Compose a container from containers or DOM elements. If a Container or Element is given as first argument then it is treated as the root and all subsequent arguments are treated as direct descendants of the root. If the second argument is an array or an "array like" object then it is treated as direct descendants of the root and all subsequent arguments are ignored. If an array or "array like" object is passed as the first argument a new root container is created and the first argument is treated as direct descendants of the newly created root container. The root container, newly created or restored is returned.
Example:
const a = createContainer()
const b = createContainer()
const composed = composeContainers([a, b])
const a = createContainer()
const b = createContainer()
const c = createContainer()
const composed = composeContainers(a, [b, c])
public createContainer(domElement: Element, initialState: Object, reducers: ...Function): Container source
import {createContainer} from 'stardux/src/index.js'
Create a new Container instance with optional initial state and n reducers.
Example:
const container = createContainer()
const container = createContainer(domElement)
const container = createContainer(domElement, {value: 0})
const container = createContainer(domElement, {value: 0}, (state = {}, action) => {
if (UPATE == action.type) {
return {
value: state.action + action.data.value
}
}
})
public createContainerUid(): String source
import {createContainerUid} from 'stardux/src/index.js'
Generates a unique hex ID for Container instances.
Example:
const id = createContainerUid()
public fetchContainer(arg: String | Element | Object): class Container source
import {fetchContainer} from 'stardux/src/index.js'
Fetch a saved container by container ID, DOM element, or by a container instance.
Return:
| class Container |
Example:
const container = fetchContainer(id)
const container = fetchContainer(domElement)
const container = fetchContainer({id: id})
public forEachContainer(fn: Function, scope: Object) source
import {forEachContainer} from 'stardux/src/index.js'
Execute a function for each container.
Example:
forEachContainer(container => {
console.log(container)
})
public getAllContainers(): MapIterator<String, Container> source
import {getAllContainers} from 'stardux/src/index.js'
Returns an interator for all containers.
Example:
const it = getAllContainers()
for (let pair of [ ...it ])
console.log(pair)
public getContainerData(arg: Container | Element | String): Object source
import {getContainerData} from 'stardux/src/index.js'
Returns immutable private stardux data for a given input. Input can be a container, an Element, or a string representing a container ID. If data is not found then null is returned.
Example:
const data = getContainerData(container)
const data = getContainerData(container)
const data = getContainerData(id)
public makeContainer(domElement: Element): Container source
import {makeContainer} from 'stardux/src/index.js'
Creates a or returns a new Container instance from a given DOM element.
If a DOM element is already associated with a container then the container is just returned, otherwise a new one is created.
Params:
| Name | Type | Attribute | Description |
| domElement | Element |
Example:
const container = makeContainer(document.body)
public realignContainerTree(container: Container, recursive: Boolean, forceOrphanRestoration: Boolean) source
import {realignContainerTree} from 'stardux/src/index.js'
Realign container DOM tree by removing containers not found in container DOM tree. If recursive is set to true then realignment is applied to all subsequent child containers. If forceOrphanRestoration is set to true then orphan containers are restored.
public removeContainer(arg: String | Container | Element, recursive: Boolean): Boolean source
import {removeContainer} from 'stardux/src/index.js'
Removes a container from the internal tree. The container is also removed from its parent if it is attched to one. A string ID, DOM element, or Container may be used as an argument.
Example:
removeContainer(id)
removeContainer(domElement)
removeContainer({id: id})
public replaceDOMElement(container: Container, domElement: Element): Container source
import {replaceDOMElement} from 'stardux/src/index.js'
Replace container element with another. This will remove all children containers and realign the container tree.
public restoreContainerFromJSON(json: Object, initialState: Object, reducers: ...Function): Container source
import {restoreContainerFromJSON} from 'stardux/src/index.js'
Create or restore a Container instance from a JSON object with an optional state object a reducers.
Containers are created if they do not already exist internally.
Example:
const container = restoreContainerFromJSON(json)
const container = restoreContainerFromJSON(json, {value: 0})
const container = restoreContainerFromJSON(json, {value: 0}, ...reducers)
public restoreOrphanedTree(container: Container | Element, recursive: Boolean) source
import {restoreOrphanedTree} from 'stardux/src/index.js'
Restores orphaned children containers still attached to a container. An orphan container is a container who belongs to a set of containers and it's DOM element is not attched to a DOM tree (The parent container's DOM element).
public saveContainer(container: Container | Element): Boolean source
import {saveContainer} from 'stardux/src/index.js'
Save a container to the known containers map. A DOM element may be passed if it has been claimed by a Container instance.
Example:
saveContainer(container)
saveContainer(domElement)
public traverseContainer(container: Container, fn: Function, scope: Object) source
import {traverseContainer} from 'stardux/src/index.js'
Traverse a container's tree recursively.
Example:
traverseContainer(container, child => {
console.log(child)
})


| DOSE: T+ 0:00 |
3/4 tsp |
oral |
Smarts - Phenibut |
(powder / crystals) |
| T+ 1:00 |
1/2 tsp |
oral |
Piracetam |
(powder / crystals) |
| T+ 1:00 |
|
oral |
Smarts - Phenibut |
(powder / crystals) |
I don't write trip reports often but seeing as there is a lack of information on recreational use of this substance I will try to contribute my two cents to the collective. I have about six years of experience in being a psychonaut in which I have done weed, lsd, mushrooms, dxm, ketamine, lsa, lsd, DOC, 4-ho-det, 5-meo-dmt, hydro/oxycodone, morphine, methadone, benzos, mdma, and others I am currently unable to recall. I am taking nootropics currently, piracetam and oxiracetam which not only have synergistic effects upon each other but also upon phenibut. I mix them for an improved experience, also.
The dose range seems to vary widely for different individuals, I recommend one begin with a dose ranging from 600-800 mg just to get their feet wet. Also building up a bit will help eliminate any hangover effects seen in the higher dose ranges for phenibut. Some day insufflating about 50 mg is similar to eating up to 10x that amount but I personally do not feel nearly the same, I would recommend against it. It is also worth mentioning phenibut has a nasty burn and taste. Enough background information, and on to the report.
+0:00 -- Ingested approx 3/4 tsp. [1.6-1.8g ] phenibut dissolved in a Dr. Pepper on a pretty empty stomach. It has a slightly sour and bitter taste, not pleasant but I've had worse. Going to dose this amount once more as I've heard it is much better than just taking a larger dose.
+0:45 -- Experiencing placebo and just a hint of euphoria. I sit back and watch the drug work its magic as Armin Van Buuren graces my eardrums with his melodic goodness. I have a slight tolerance mind you, nothing too strong, after taking 1 tsp the previous day and 1/2 the two before that.
+1:00 -- I fixed myself a nice nasty cocktail of 1/2 tsp. piracetam and right in between 3/4 and 1 tsp phenibut. I will consume it over the next 10-15 minutes. Warning this is the reported hangover zone, if you are drinking it has been told that you can get pretty messed up pretty quick. Please always take care to moderate your usage.
+1:15 -- Feeling a few subtle rushes of excitement and picking at some dessert as to avoid the aftertaste of my now almost completed soda. I've heard energy drinks can affect the experience, I was drinking the Full Throttle brand last night after my peak, though it didn't noticeably change anything. Come to think of it I do recall the energy buzz to be a little more smooth than usual.
+1:25 -- A subtle yet pronounced inebriation is upon me, it's creeping slowly. At +3-4 hours peak intensity is expected also to be accompanied with a good time ,). Beginning to fall into the music a bit (Way Out West - Intensify 02). I'm enjoying this and would say phenibut is a pleasant and worthy legal high. I will probably become a regular user not only for its feelings of well being but also for its anxiolytic properties.
+1:50 -- Feeling about the same subtle euphoria. Feels nice to lay or stand in a breeze, appetite is appreciated. It's odd, one must not quite concentrate on the effects for them to be the most noticeable. Relaxing into it feels wonderful, will be pleasant to undergo the peak.
+2:10 -- Slight modification of vision and balance.
+2:40 -- Not much change, I've kind of become used to it so it almost seems absent but there's still some feeling there.
+3:50 -- Peak seems not much different than before though there is almost an emotional aspect to it now. Will attempt to boost by insufflating a few lines. Lost track of time for a while. The high actually is less hollow now. Feeling pretty damn good actually, nothing extravagant. Had the munchies so I fixed myself a large meal and indulged.
+5:00 -- Exhausted, feel like I'll have a great rest.
After nearly two weaks of no phenibut I had taken 3/4 tsp of phenibut and had a euphoric and joyful trip which I am still stuck in the middle of. I had mixed in kava and kratom tea which all seemed to go well. I'd rate phenibut as an overall worthy drug with benefits that I find rewarding when used properly.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


INSERT
Section: SQL Commands (7)Updated: 2012-08-14
Index Return to Main Contents
NAME
INSERT - create new rows in a tableSYNOPSIS
INSERT INTO table [ ( column [, ...] ) ] { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query } [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
DESCRIPTION
INSERT inserts new rows into a table. One can insert one or more rows specified by value expressions, or zero or more rows resulting from a query.
The target column names can be listed in any order. If no list of column names is given at all, the default is all the columns of the table in their declared order; or the first N column names, if there are only N columns supplied by the VALUES clause or query. The values supplied by the VALUES clause or query are associated with the explicit or implicit column list left-to-right.
Each column not present in the explicit or implicit column list will be filled with a default value, either its declared default value or null if there is none.
If the expression for any column is not of the correct data type, automatic type conversion will be attempted.
The optional RETURNING clause causes INSERT to compute and return value(s) based on each row actually inserted. This is primarily useful for obtaining values that were supplied by defaults, such as a serial sequence number. However, any expression using the table's columns is allowed. The syntax of the RETURNING list is identical to that of the output list of SELECT.
You must have INSERT privilege on a table in order to insert into it. If a column list is specified, you only need INSERT privilege on the listed columns. Use of the RETURNING clause requires SELECT privilege on all columns mentioned in RETURNING. If you use the query clause to insert rows from a query, you of course need to have SELECT privilege on any table or column used in the query.
PARAMETERS
- table
- The name (optionally schema-qualified) of an existing table.
- column
- The name of a column in table. The column name can be qualified with a subfield name or array subscript, if needed. (Inserting into only some fields of a composite column leaves the other fields null.)
- DEFAULT VALUES
- All columns will be filled with their default values.
- expression
- An expression or value to assign to the corresponding column.
- DEFAULT
- The corresponding column will be filled with its default value.
- query
- A query (SELECT statement) that supplies the rows to be inserted. Refer to the SELECT [select(7)] statement for a description of the syntax.
- output_expression
- An expression to be computed and returned by the INSERT command after each row is inserted. The expression can use any column names of the table. Write * to return all columns of the inserted row(s).
- output_name
- A name to use for a returned column.
OUTPUTS
On successful completion, an INSERT command returns a command tag of the form
INSERT oid countThe count is the number of rows inserted. If count is exactly one, and the target table has OIDs, then oid is the OID assigned to the inserted row. Otherwise oid is zero.
If the INSERT command contains a RETURNING clause, the result will be similar to that of a SELECT statement containing the columns and values defined in the RETURNING list, computed over the row(s) inserted by the command.
EXAMPLES
Insert a single row into table films:
INSERT INTO films VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');
In this example, the len column is omitted and therefore it will have the default value:
INSERT INTO films (code, title, did, date_prod, kind) VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
This example uses the DEFAULT clause for the date columns rather than specifying a value:
INSERT INTO films VALUES ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes'); INSERT INTO films (code, title, did, date_prod, kind) VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama');
To insert a row consisting entirely of default values:
INSERT INTO films DEFAULT VALUES;
To insert multiple rows using the multirow VALUES syntax:
INSERT INTO films (code, title, did, date_prod, kind) VALUES ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'), ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
This example inserts some rows into table films from a table tmp_films with the same column layout as films:
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
This example inserts into array columns:
-- Create an empty 3x3 gameboard for noughts-and-crosses INSERT INTO tictactoe (game, board[1:3][1:3]) VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}'); -- The subscripts in the above example aren't really needed INSERT INTO tictactoe (game, board) VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');
Insert a single row into table distributors, returning the sequence number generated by the DEFAULT clause:
INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets') RETURNING did;
COMPATIBILITY
INSERT conforms to the SQL standard, except that the RETURNING clause is a PostgreSQL extension. Also, the case in which a column name list is omitted, but not all the columns are filled from the VALUES clause or query, is disallowed by the standard.
Possible limitations of the query clause are documented under SELECT [select(7)].
Index
This document was created by man2html, using the manual pages.
Time: 05:34:15 GMT, December 24, 2015


"Design of Integrated Circuits using T.F.T.s within the
framework "PYTHAGORAS: Study and Development of T.F.T.s
models – Design and Development of Li-ion batteries for
their supply"
Scientific Assistant
Funded by the Ministry of National Education and Religious
Affairs.
Aristotle University of Thessaloniki, Greece
Oct. 2004 - Sept. 2005


I am a Junior Fullstack Developer specialising is Javascript and Nodejs. I have a deep seated passion for learning and constantly trying to upskill myself. Before getting into IT, I worked as an L&D coordinator then after as a medical receptionist.
I've always been interested in IT and started off in this journey using Youtube videos and online tutorials.
My passion for programming has led me to WeThinkCode bootcamp, Umuzi Academy and also, online learning opprtunities such as the Google Africa Schorlarship, in which, I honed in my javascript and Jquery skills and more recently I was on the ALC with Google in aprtnership with Plurasight - Mobile Web App specialist.
for more information please download my CV.
Basic chat app, to send and receive messages built using socket.io
Close ProjectMemory Game
This is a card flip memory game, with only 6 pairs to match. The images are from The Witcher series by cd projektredClick here to view page
Close Project


Reprehenderit exercitationem beatae ipsam similique assumenda nemo quis quod ut aspernatur rerum nam. omnis dolores nostrum voluptas nulla corporis quasi accusamus. placeat nesciunt rerum velit et rem corporis vel
A knotted stitch is any embroidery technique in which the yarn or thread is knotted around itself. Common knotted stitches include French knots and coral stitch. Knotted stitches can be subdivided into individual or detached knots, continuous knotted stitches, and knotted edgings.
Individual knots are often found used as detached filling stitches. Knotted edgings are used as a decorative trims, and can also be used to fill open spaces in cutwork and in needlelace.
The long and short stitch is a form of free style embroidery, often used for shading flower petals and bird feathers. The characteristic feature of this stitch is that the stitches of the first row are worked in such a way that they are alternately long and short. The stitches in the ensuing rows are all of the same length and fit into the first row.
Also sometimes known as: Algerian filling stitch; brick stitch; embroidery stitch; feather stitch; Kensington stitch; plumage stitch; shading stitch.


You open a door and see a stairwell and some brooms. Wow, this place has stairs? You think as you close the door.
It doesn't look like I will find the Culinary Arts Coordinator is in here.


To show or hide the toolbox
To show the toolbox, click the View menu and make sure a check mark appears next to Tool Box. To hide the toolbox, click to clear the check mark.
Note


Afternoon showers wreck havoc in Kampala
by Patrick KibirangoRoads and businesses flooded, and pedestrians having to wade through muddy waters
Activities in some areas Kampala’s busiest areas came to a standstill on Friday afternoon following the rains that lasted for about an hour.
Despite the shower not lasting long, pedestrians, cyclists and motorists had to contend with floods at Clock Tower on Entebbe Road. Enterprising men were seen making a quick buck by carrying pedestrians who didn’t want to wade through the water, on their backs for a fee.
Business in Owino Market also came to a standstill as Nakivubo Channel overflowed and left shops submerged in muddy waters.


Consider a general continuous-time
(1)
or discrete-time dynamical system
(2)
wherein is time [1], is the state, is the control, and is a measurable vector function taking values in . [2] The control values are restricted to a closed compact control set . An open-loop control does not depend on the state, ; for a closed-loop control, .
Definition. The (forward) reach set at time from the initial position is the set of all states reachable at time by system (1), or (2), with through all possible controls , . For a given set of initial states , the reach set is
(3)
Here are two facts about forward reach sets.
is the same for open-loop and closed-loop control.
satisfies the semigroup property,
(4)
For linear systems
(5)
with matrices in and in . For continuous-time linear system the state transition matrix is
which for constant simplifies as
For discrete-time linear system the state transition matrix is
which for constant simplifies as
If the state transition matrix is invertible, . The transition matrix is always invertible for continuous-time and for sampled discrete-time systems. However, if for some , , is degenerate (singular), , is also degenerate and cannot be inverted.
Following Cauchy’s formula, the reach set for a linear system can be expressed as
(6)
in continuous-time, and as
(7)
in discrete-time case.
The operation ‘’ is the geometric sum, also known as Minkowski sum. [3] The geometric sum and linear (or affine) transformations preserve compactness and convexity. Hence, if the initial set and the control sets , , are compact and convex, so is the reach set .
Definition. The backward reach set for the target position is the set of all states for which there exists some control , , that steers system (1), or (2) to the state at time . For the target set at time , the backward reach set is
(8)
The backward reach set is the largest weakly invariant set with respect to the target set and time values and . [4]
Remark. Backward reach set can be computed for continuous-time system only if the solution of (1) exists for ; and for discrete-time system only if the right hand side of (2) is invertible [5].
These two facts about the backward reach set are similar to those for forward reach sets.
is the same for open-loop and closed-loop control.
satisfies the semigroup property,
(9)
For the linear system (5) the backward reach set can be expressed as
(10)
in the continuous-time case, and as
(11)
in discrete-time case. The last formula makes sense only for discrete-time linear systems with invertible state transition matrix. Degenerate discrete-time linear systems have unbounded backward reach sets and such sets cannot be computed with available software tools.
Just as in the case of forward reach set, the backward reach set of a linear system is compact and convex if the target set and the control sets , , are compact and convex.
Remark. In the computer science literature the reach set is said to be the result of operator post, and the backward reach set is the result of operator pre. In the control literature the backward reach set is also called the solvability set.
Consider the continuous-time dynamical system with disturbance
(12)
or the discrete-time dynamical system with disturbance
(13)
in which we also have the disturbance input with values restricted to a closed compact set .
In the presence of disturbances the open-loop reach set (OLRS) is different from the closed-loop reach set (CLRS).
Given the initial time , the set of initial states , and terminal time , there are two types of OLRS.
Definition. The maxmin open-loop reach set is the set of all states , such that for any disturbance , there exist an initial state and a control , , that steers system (12) or (13) from to .
Definition. The minmax open-loop reach set is the set of all states , such that there exists a control that for all disturbances , , assigns an initial state and steers system (12), or (13), from to .
In the maxmin case the control is chosen after knowing the disturbance over the entire time interval , whereas in the minmax case the control is chosen before any knowledge of the disturbance. Consequently, the OLRS do not satisfy the semigroup property.
The terms ‘maxmin’ and ‘minmax’ come from the fact that is the subzero level set of the value function
(14)
i.e., , and is the subzero level set of the value function
(15)
in which denotes Hausdorff semidistance. [6] Since , .
Note that maxmin and minmax OLRS imply guarantees: these are states that can be reached no matter what the disturbance is, whether it is known in advance (maxmin case) or not (minmax case). The OLRS may be empty.
Fixing time instant , , define the piecewise maxmin open-loop reach set with one correction,
(16)
and the piecewise minmax open-loop reach set with one correction,
(17)
The piecewise maxmin OLRS is the subzero level set of the value function
(18)
with given by (14), which yields
and thus,
On the other hand, the piecewise minmax OLRS is the subzero level set of the value function
(19)
with given by (15), which yields
and thus,
We can now recursively define piecewise maxmin and minmax OLRS with corrections for . The maxmin piecewise OLRS with corrections is
(20)
which is the subzero level set of the corresponding value function
(21)
The minmax piecewise OLRS with corrections is
(22)
which is the subzero level set of the corresponding value function
(23)
From (18), (19), (21) and (23) it follows that
Hence,
(24)
We call
(25)
the maxmin closed-loop reach set of system (12) or (13) at time , and we call
(26)
the minmax closed-loop reach set of system (12) or (13) at time .
Definition. Given initial time and the set of initial states , the maxmin CLRS of system (12) or (13) at time , is the set of all states , for each of which and for every disturbance , there exist an initial state and a control , such that the trajectory satisfying and
in the continuous-time case, or
in the discrete-time case, with , is such that .
Definition. Given initial time and the set of initial states , the maxmin CLRS of system (12) or (13), at time , is the set of all states , for each of which there exists a control , and for every disturbance there exists an initial state , such that the trajectory satisfying and
in the continuous-time case, or
in the discrete-time case, with , is such that . By construction, both maxmin and minmax CLRS satisfy the semigroup property (4).
For some classes of dynamical systems and some types of constraints on initial conditions, controls and disturbances, the maxmin and minmax CLRS may coincide. This is the case for continuous-time linear systems with convex compact bounds on the initial set, controls and disturbances under the condition that the initial set is large enough to ensure that is nonempty for some small .
Consider the linear system case,
(27)
where and are as in (5), and takes its values in .
The maxmin OLRS for the continuous-time linear system can be expressed through set valued integrals,
(28)
and for discrete-time linear system through set-valued sums,
(29)
Similarly, the minmax OLRS for the continuous-time linear system is
(30)
and for the discrete-time linear system it is
(31)
The operation ‘’ is geometric difference, also known as Minkowski difference. [7]
Now consider the piecewise OLRS with corrections. Expression (20) translates into
(32)
in the continuous-time case, and for the discrete-time case into
(33)
Expression (22) translates into
(34)
in the continuous-time case, and for the discrete-time case into
(35)
Since for any it is true that
from (32), (34) and from (33), (35), it is clear that (24) is true. For linear systems, if the initial set , control bounds and disturbance bounds , , are compact and convex, the CLRS and are compact and convex, provided they are nonempty. For continuous-time linear systems, .
Just as for forward reach sets, the backward reach sets can be open-loop (OLBRS) or closed-loop (CLBRS).
Definition. Given the terminal time and target set , the maxmin open-loop backward reach set of system (12) or (13) at time , is the set of all , such that for any disturbance there exists a terminal state and control , , which steers the system from to .
is the subzero level set of the value function
(36)
Definition. Given the terminal time and target set , the minmax open-loop backward reach set of system (12) or (13) at time , is the set of all , such that there exists a control that for all disturbances , , assigns a terminal state and steers the system from to . is the subzero level set of the value function
(37)
Remark. The backward reach set can be computed for a continuous-time system only if the solution of (12) exists for , and for a discrete-time system only if the right hand side of (13) is invertible.
Similarly to the forward reachability case, we construct piecewise OLBRS with one correction at time , . The piecewise maxmin OLBRS with one correction is
(38)
and it is the subzero level set of the function
(39)
The piecewise minmax OLBRS with one correction is
(40)
and it is the subzero level set of the function
(41)
Recursively define maxmin and minmax OLBRS with corrections for . The maxmin OLBRS with corrections is
(42)
which is the subzero level set of function
(43)
The minmax OLBRS with corrections is
(44)
which is the subzero level set of the function
(45)
From (39), (41), (43) and (45) it follows that
Hence,
(46)
We say that
(47)
is the maxmin closed-loop backward reach set of system (12) or (13) at time .
We say that
(48)
is the minmax closed-loop backward reach set of system (12) or (13) at time .
Definition. Given the terminal time and target set , the maxmin CLBRS of system (12) or (13) at time , is the set of all states , for each of which for every disturbance there exists terminal state and control that assigns trajectory satisfying
in continuous-time case, or
in discrete-time case, with , such that and .
Definition. Given the terminal time and target set , the minmax CLBRS of system (12) or (13) at time , is the set of all states , for each of which there exists control that for every disturbance assigns terminal state and trajectory satisfying
in the continuous-time case, or
in the discrete-time case, with , such that and .
Both maxmin and minmax CLBRS satisfy the semigroup property (9).
The maxmin OLBRS for the continuous-time linear system can be expressed through set valued integrals,
(49)
and for the discrete-time linear system through set-valued sums,
(50)
Similarly, the minmax OLBRS for the continuous-time linear system is
(51)
and for the discrete-time linear system it is
(52)
Now consider piecewise OLBRS with corrections. Expression (42) translates into
(53)
in the continuous-time case, and for the discrete-time case into
(54)
Expression (44) translates into
(55)
in the continuous-time case, and for the discrete-time case into
(56)
For continuous-time linear systems under the condition that the target set is large enough to ensure that is nonempty for some small .
Computation of backward reach sets for discrete-time linear systems makes sense only if the state transition matrix is invertible.
If the target set , control sets and disturbance sets , , are compact and convex, then CLBRS and are compact and convex, if they are nonempty.
Reachability analysis is concerned with the computation of the forward and backward reach sets (the reach sets may be maxmin or minmax) in a way that can effectively meet requests like the following:
For the given time interval , determine whether the system can be steered into the given target set . In other words, is the set nonempty? And if the answer is ‘yes’, find a control that steers the system to the target set (or avoids the target set). [8]
If the target set is reachable from the given initial condition in the time interval , find the shortest time to reach ,
Given the terminal time , target set and time find the set of states starting at time from which the system can reach within time interval . In other words, find .
Find a closed-loop control that steers a system with disturbances to the given target set in given time.
Graphically display the projection of the reach set along any specified two- or three-dimensional subspace.
For linear systems, if the initial set , target set , control bounds and disturbance bounds are compact and convex, so are the forward and backward reach sets. Hence reachability analysis requires the computationally effective manipulation of convex sets, and performing the set-valued operations of unions, intersections, geometric sums and differences.
Existing reach set computation tools can deal reliably only with linear systems with convex constraints. A claim that certain tool or method can be used effectively for nonlinear systems must be treated with caution, and the first question to ask is for what class of nonlinear systems and with what limit on the state space dimension does this tool work? Some “reachability methods for nonlinear systems” reduce to the local linearization of a system followed by the use of well-tested techniques for linear system reach set computation. Thus these approaches in fact use reachability methods for linear systems.
Consider the system
(57)
in which is the state, is the control and is the disturbance. , and are continuous and take their values in , and respectively. Control and disturbance are measurable functions restricted by ellipsoidal constraints: and . The set of initial states at initial time is assumed to be the ellipsoid .
The reach sets for systems with disturbances computed by the Ellipsoidal Toolbox are CLRS. Henceforth, when describing backward reachability, reach sets refer to CLRS or CLBRS. Recall that for continuous-time linear systems maxmin and minmax CLRS coincide, and the same is true for maxmin and minmax CLBRS.
If the matrix , the system (57) becomes an ordinary affine system with known . If , the system becomes linear. For these two cases ( or ) the reach set is as given in definition (3), and so the reach set will be denoted as .
The reach set is a symmetric compact convex set, whose center evolves in time according to
(58)
Fix a vector , and consider the solution of the adjoint equation
(59)
which is equivalent to
If the reach set is nonempty, there exist tight external and tight internal approximating ellipsoids and , respectively, such that
(60)
and
(61)
The equation for the shape matrix of the external ellipsoid is
(62)
(63)
in which
and the orthogonal matrix () is determined by the equation
In the presence of disturbance, if the reach set is empty, the matrix becomes sign indefinite. For a system without disturbance, the terms containing and vanish from the equation (62).
The equation for the shape matrix of the internal ellipsoid is
(64)
(65)
in which
and the orthogonal matrix is determined by the equation
Similarly to the external case, the terms containing and vanish from the equation (64) for a system without disturbance.
The point where the external and internal ellipsoids touch the boundary of the reach set is given by
The boundary points form trajectories, which we call extremal trajectories. Due to the nonsingular nature of the state transition matrix , every boundary point of the reach set belongs to an extremal trajectory. To follow an extremal trajectory specified by parameter , the system has to start at time at initial state
(66)
In the absence of disturbances, the open-loop control
(67)
steers the system along the extremal trajectory defined by the vector . When a disturbance is present, this control keeps the system on an extremal trajectory if and only if the disturbance plays against the control always taking its extreme values.
Expressions (60) and (61) lead to the following fact,
In practice this means that the more values of we use to compute and , the better will be our approximation.
Analogous results hold for the backward reach set.
Given the terminal time and ellipsoidal target set , the CLBRS , , if it is nonempty, is a symmetric compact convex set whose center is governed by
(68)
Fix a vector , and consider
(69)
If the backward reach set is nonempty, there exist tight external and tight internal approximating ellipsoids and respectively, such that
(70)
and
(71)
The equation for the shape matrix of the external ellipsoid is
(72)
(73)
in which
and the orthogonal matrix satisfies the equation
The equation for the shape matrix of the internal ellipsoid is
(74)
(75)
in which
and the orthogonal matrix is determined by the equation
Just as in the forward reachability case, the terms containing and vanish from equations (72) and (74) in the absence of disturbances. The boundary value problems (68), (72) and (74) are converted to the initial value problems by the change of variables .
Remark. In expressions (62), (64), (72) and (74) the terms and may not be well defined for some vectors , because matrices and may be singular. In such cases, we set these entire expressions to zero.
Consider the discrete-time linear system,
(76)
in which is the state, is the control bounded by the ellipsoid , is disturbance bounded by ellipsoid , and matrices , , are in , , respectively. Here we shall assume to be nonsingular. [9] The set of initial conditions at initial time is ellipsoid .
Ellipsoidal Toolbox computes maxmin and minmax CLRS and for discrete-time systems.
If matrix , the system (76) becomes an ordinary affine system with known . If matrix , the system reduces to a linear controlled system. In the absence of disturbance ( or ), , the reach set is as in definition (3).
Maxmin and minmax CLRS and , if nonempty, are symmetric convex and compact, with the center evolving in time according to
(77)
Fix some vector and consider that satisfies the discrete-time adjoint equation, [10]
(78)
or, equivalently
There exist tight external ellipsoids , and tight internal ellipsoids , such that
(79)
(80)
and
(81)
(82)
The shape matrix of the external ellipsoid for maxmin reach set is determined from
(83)
(84)
(85)
wherein
and the orthogonal matrix is determined by the equation
Equation (84) is valid only if , otherwise the maxmin CLRS is empty.
The shape matrix of the external ellipsoid for minmax reach set is determined from
(86)
(87)
(88)
where
and is orthogonal matrix determined from the equation
Equations (86), (87) are valid only if , otherwise minmax CLRS is empty.
The shape matrix of the internal ellipsoid for maxmin reach set is determined from
(89)
(90)
(91)
where
and is orthogonal matrix determined from the equation
Equation (90) is valid only if .
The shape matrix of the internal ellipsoid for the minmax reach set is determined by
(92)
(93)
(94)
wherein
and the orthogonal matrix is determined by the equation
Equations (92), (93) are valid only if .
The point where the external and the internal ellipsoids both touch the boundary of the maxmin CLRS is
and the bounday point of minmax CLRS is
Points , , form extremal trajectories. In order for the system to follow the extremal trajectory specified by some vector , the initial state must be
(95)
When there is no disturbance ( or ), and , and the open-loop control that steers the system along the extremal trajectory defined by is
(96)
Each choice of defines an external and internal approximation. If is nonempty,
Similarly for ,
Similarly, tight ellipsoidal approximations of maxmin and minmax CLBRS with terminating conditions can be obtained for those directions satisfying
(97)
with some fixed , for which they exist.
With boundary conditions
(98)
external and internal ellipsoids for maxmin CLBRS at time , and , are computed as external and internal ellipsoidal approximations of the geometric sum-difference
and
in direction from (97). Section Geometric Sum-Difference describes the operation of geometric sum-difference for ellipsoids.
External and internal ellipsoids for minmax CLBRS at time , and , are computed as external and internal ellipsoidal approximations of the geometric difference-sum
and
in direction from (97). Section Geometric Difference-Sum describes the operation of geometric difference-sum for ellipsoids.
| [1] | In discrete-time case assumes integer values. |
| [2] | We are being general when giving the basic definitions. However, it is important to understand that for any specific continuous-time dynamical system it must be determined whether the solution exists and is unique, and in which class of solutions these conditions are met. Here we shall assume that function is such that the solution of the differential equation (1) exists and is unique in Fillipov sense. This allows the right-hand side to be discontinuous. For discrete-time systems this problem does not exist. |
| [3] | Minkowski sum of sets is defined as . Set is nonempty if and only if both, and are nonempty. If and are convex, set is convex. |
| [4] | is weakly invariant with respect to the target set and times and , if for every state there exists a control , , that steers the system from at time to some state in at time . If all controls in , steer the system from every at time to at time , set is said to be strongly invariant with respect to , and . |
| [5] | There exists such that . |
| [6] | Hausdorff semidistance between compact sets is defined as where denotes inner product. |
| [7] | The Minkowski difference of sets is defined as . If and are convex, is convex if it is nonempty. |
| [8] | So-called verification problems often consist in ensuring that the system is unable to reach an ‘unsafe’ target set within a given time interval. |
| [9] | The case when is singular is described in [VAR2007]. The idea is to substitute with the nonsingular , in which and are obtained from the singular value decomposition The parameter can be chosen based on the number of time steps for which the reach set must be computed and the required accuracy. The issue of inverting ill-conditioned matrices is also addressed in [VAR2007]. |
| [10] | Note that for (78) must be invertible. |
| [VAR2007] | (1, 2) P. Varaiya A. A. Kurzhanskiy. Ellipsoidal techniques for reachability analysis of discrete-time linear systems. IEEE Transactions on Automatic Control, 52(1):26–38, 2007. linear systems. IEEE Transactions on Automatic Control, 52(1):26–38, 2007. |


Shutdown in progress ...
Please wait.
Transaction details
dashboard
Dashboard
account_balance_wallet
Wallet
history
History
map
Merchants
settings
Settings
info
About
build
Tools
power_settings_new
Log out
keyboard_arrow_right
keyboard_arrow_left
{{appTitle$ | async}}


This page contains an evil script-snippet and try to overwrite the location of the window.opener.
Oops..! You have been redirected!
Great! Redirect was blocked.


|
|
||
| Value | Description | Notes |
|---|---|---|
|
|
||
| 01 | HTML | |
| 02 | ||
| 03 | Microsoft Reader | ‘.LIT’ file format used by Microsoft Reader software |
| 04 | RocketBook | |
| 05 | Rich text format (RTF) | |
| 06 | Open Ebook Publication Structure (OEBPS) format standard | |
| 07 | XML | |
| 08 | SGML | |
| 09 | EXE | ‘.EXE’ file format used when an epublication is delivered as a self-executing package of software and content |
| 10 | ASCII | ‘.TXT’ file format |
| 11 | MobiPocket format | Proprietary file format used for the MobiPocket reader software |
|
|


group
12,345 Followers
person_add
Follow
Featured User
Ariana Grande
file_upload
12,345 Uploads
thumb_up
12,345 Likes
Twitter
@ArianaGrande
arrow_forward
Show
Links
group
12,345 Followers
person_outline
Follow
Featured User
Jessie J
file_upload
12,345 Uploads
thumb_up
12,345 Likes
Twitter
@jessiej
arrow_forward
Instagram
@isthatjessiej
arrow_forward
Website
www.jessiejofficial.com
arrow_forward
Show
Links
group
12,345 Followers
person_add
Follow
Featured User
Nicki Minaj
file_upload
12,345 Uploads
thumb_up
12,345 Likes
Twitter
@NICKIMINAJ
arrow_forward
Instagram
@nickiminaj
arrow_forward
Show
Links