COTONIC
Cotonic is a Javascript
library which makes it possible to split the javascript code of your
page into truly isolated components. By doing this a crash in one component
can never affect another component.
Cotonic provides tools to make it possible for these components to cooperate
by providing an MQTT publish/subscribe bus. This makes it possible for
components to communicate via topics.
The project is hosted on Github.
You can report bugs and discuss features on the
issues page.
Cotonic is an open-source component of Zotonic.
Installation
Place the cotonic.js,
cotonic-worker.js and
cotonic-service-worker.js scripts on a web-server.
(Right-click and use "Save link as..."), or use one of the download links.
Add the following tag to the page:

Workers
Cotonic uses Web Workers which all run in separate calling context. This
means that they will not block the main user interface thread. They are
also truly isolated from each other. This means that a crash or another
kind of problem in worker A can't crash worker B.
You can run whatever code you like in workers, with some exceptions. You
can't access the DOM, and a lot of things from the window object. This also
makes them more secure because you don't have to worry that worker code
from an external resource can steal the a credit-card number entered
somewhere in the DOM tree.
Cotonic adds a MQTT like publish subscribe mechanism to the standard javascript
web worker api. This makes it easy for web workers to communicate with each other.
// worker-a
"use strict";
self.subscribe("some/topic", function(message) {
self.publish("model/ui/update", "
Worker A got message
")
});
self.publish("model/ui/insert", "
Worker A started
");
// worker-b
"use strict";
self.subscribe("some/topic", function(message) {
self.publish("model/ui/update", "
Worker B got message
")
});
self.publish("model/ui/insert", "
Worker B started
");
let worker_a = cotonic.spawn("worker-a.js", [1, 2]);
let worker_a = cotonic.spawn("worker-b.js");
cotonic.broker.publish("some/topic", "hello workers!");
Page Functions
Cotonics main functions are available in the cotonic namespace on the main page.
The functions are mostly used to control and allow messaging between workers.
cotonic.spawn(url, [args])
Spawn a new worker. The code of the worker should be available at url. The optional
args parameter list will be passed to the worker and can be used to pass information from
the page to the worker. It can be picked up with the on_init
callback. The structured clone algorithm will be used to send the args to the worker. See
worker functions for more information on implementing a worker.
Returns the worker-id of the newly created worker process.
cotonic.spawn("/js/example-worker.js");
=> 1
cotonic.spawn("/js/another-worker.js", ["Arg1", 1]);
=> 2
cotonic.spawn_named(name, src_url, [base], [args])
Spawn a new named worker. Named workers are unique. Use "" or undefined to create a
nameless worker. Return the worker_id of the newly spawned
worker. If the worker was already running, the existing worker_id is returned.
cotonic.spawn_named("example", "example-worker.js");
=> "worker"
cotonic.exit(nameOrwid)
Exit terminates a worker which was previously spawned and has nameOrWid as
worker-id.
const wid = cotonic.spawn("example.worker.js");
cotonic.exit(wid);
=> Worker wid is no longer running.
cotonic.send(nameOrWid, message)
Send message message to worker nameOrWid. The parameter nameOrWid
can either be the name of worker, or a worker id. The structured clone algorithm will
be used to copy the message before sending it to the worker.
cotonic.send(worker_id1, "hello");
cotonic.receive(handler)
Receive messages from workers. The handler should be a function which takes
two parameters, the message, and the worker_id.
cotonic.receive(function(message, worker_id) {
console.log("Received", message, "from worker", worker_id);
});
The page function has one configuration option.
- base_worker_src
- The url for the base worker runtime for cotonic. This runtime provides
the required communication primitives.

Broker
The broker module handles all local publish subscribe connections. The subscriptions
are stored in a trie datastructure allowing quick action. They are available in the
cotonic.broker namespace.
cotonic.broker.find_subscriptions_below(topic)
Find all subscribers below a certain topic. Used by the bridge to collect all subscriptions
after a session restart. Returns a list with subscriptions.
cotonic.broker.find_subscriptions_below("truck");
=> [
{type: "page", wid: 0, callback: function, sub: Object, topic: "truck/+/speed"}
{type: "page", wid: 0, callback: function, sub: Object, topic: "#"}]
cotonic.broker.match(topic)
Collect all subscribers which match the topic. Returns a list with subscriptions.
cotonic.broker.subscribe("truck/+/speed", function(msg) {
console.log("Some trucks speed", msg);
});
cotonic.broker.subscribe("truck/#", function(msg) {
console.log("Some info of a truck", msg);
});
cotonic.broker.subscribe("truck/02/speed", function(msg) {
console.log("Speed of truck 2", msg);
})
cotonic.broker.match("truck/01/speed");
=> [Object, Object] // Returns two subscriptions, truck/+/speed, and truck/#
cotonic.broker.match("truck/01/speed")[0]
=> {type: "page", wid: 0, callback: function, sub: Object, topic: "truck/+/speed"}
cotonic.broker.match("truck/02/speed");
=> [Object, Object, Object] // Returns all subscriptions
cotonic.broker.match("boat/02/speed");
=> [] // Has no subscribers
cotonic.broker.publish(topic, payload, [options])
Publish the message payload on a topic. The possible options are:
- qos
- Quality of service. Can be 0, 1, or 2. 0 means at most once, 1 at least once, and 2 exactly once.
- retain
- When retain is true, the last message sent will be stored, and delivered immediately when
a new client subscribes to the topic.
- properties
- Extra properties which can be attached to the message
cotonic.broker.publish("truck/001/temperature", 88);
=> All subscribers receive the message 88 on the topic.
cotonic.broker.publish("truck/001/speed", 74, {retain: true});
=> All subscribers receive the message 74. New subscribers will immediately receive 74.
cotonic.broker.subscribe(topics, callback, [options])
Subscribe to topics. Argument topics can either be a single topic, or a list of topics.
The function callback will be called when a message which matches
one of the topics is published. It is a function is called with two arguments, message
and info. Argument message is the received mqtt message, and info
the returned information object returned by extract.
This makes it possible to easily extract information from the topic.
Parameter options can be
- wid
- The worker if used for making the scription. Can be used to differentiate
subscriptions from different components on the page. Defaults to: 0
- qos
- The quality-of-service of the subscription. Defaults to: 0
- retain_handling
- [todo]
- retain_as_published
- [todo]
- no_local
- [todo]
- properties
- [todo]
cotonic.broker.subscribe("truck/+truck_id/speed",
function(msg, info) {
console.log("Truck", info.truckid, "speed:", msg.payload);
},
{wid: "example"});
=> The function will now be called when a truck publishes its speed.
cotonic.broker.unsubscribe(topics, [options])
Unsubscribe from the topics. The parameter topics can be a single topic as a string,
or a list of topics. The optional parameter options is an object which has the following
properties.
- wid
- The worker id from which to unsubscribe from. Defaults to: 0
cotonic.broker.unsubscribe("truck/+truck_id/speed",
{wid: "example"});
=> The subscriptions for topic "truck/+truck_id/speed" for worker "example" will not be called anymore.
cotonic.broker.call(topic, payload, [options])
Call is a special kind of publish where the publisher expects an answer back. The payload
will be published on topic using the options as described in
publish.
The caller will be temporarily subscribed to a reply topic. When an answer is received on this
reply topic, the returned promise will be resolved. When no answer is received, the promise will
be rejected with a reason.
The option parameter can have the following extra options:
- timeout
The timeout in milliseconds to use before rejecting
the returned promise. Default: 15000, or
15 seconds.
cotonic.broker.call("model/localStorage/get/username", {}, {timeout: 1000})
.then(function(username) {
console.log("The username is:", username");
})
.catch(function(e) {
console.log("Could not get username within 1 second.", e);
});
MQTT
The mqtt module provides functions to work with mqtt topics. The broker
uses this module as the basis to provide its functionality. This module also has some utility functions
to easily extract information from topics.
cotonic.mqtt.matches(pattern, topic)
Returns true when the pattern matches the topic, false otherwise.
cotonic.mqtt.matches("truck/+/speed", "truck/01/speed");
=> true
cotonic.mqtt.matches("boat/+/speed", "truck/01/speed");
=> false
cotonic.mqtt.matches("+/+/speed", "plane/01/speed");
=> true
cotonic.mqtt.matches("+/+/speed", "plane/01/height");
=> false
cotonic.mqtt.fill(pattern, params)
Fill can use a pattern topic, and use the param object to create
an mqtt topic. Returns a string with the created topic.
cotonic.mqtt.fill("truck/+truck_id/speed", {truck_id: 100});
=> "truck/100/speed"
cotonic.mqtt.extract("truck/+truck_id/speed", "truck/01/speed");
=> {truck_id: "01"}
cotonic.mqtt.extract("truck/+truck_id/#params", "truck/01/speed");
=> {truck_id: "01", params: ["speed"]}
cotonic.mqtt.exec(pattern, topic)
When the pattern matches the topic,
extract the values from the topic. Returns the
extracted values when the pattern matches, null otherwise.
cotonic.mqtt.exec("truck/+truck_id/speed", "truck/01/speed");
=> {truck_id: "01"}
cotonic.mqtt.exec("boat/+truck_id/speed", "truck/01/speed");
=> null
cotonic.mqtt.remove_named_wildcards(pattern)
Remove the special, and non mqtt compliant, wildcards from the pattern and return a compliant
topic.
cotonic.mqtt.remove_named_wildcards("truck/+truck_id/speed");
=> "truck/+/speed"
cotonic.mqtt.remove_named_wildcards("truck/#truck_info");
=> "truck/#"
mqtt_bridge
This module makes it possible to bridge the broker on the local page to
an external MQTT broker.
cotonic.mqtt_bridge.newBridge([remote], [options])
Create a new bridge. This is the hostname of the mqtt broker to connect to. When set to
"origin" the bridge uses the hostname of the document.
When the bridge is connected messages published on the topic matching bridge/+remote/# will
be re-published on the remote broker. Subscriptions on the topic bridge/+remote/#
will be published locally. This makes it possible to connect and communicate with
all clients connected to remote mqtt brokers.
Note: It is possible to connect to multiple brokers.
- protocol
- The protocol to use to connect to the mqtt broker. Defaults to "ws" when the page is
loaded via "http", "wss" otherwise.
- controller_path
- The pathname to use when connecting the web socket to the broker. Default: "mqtt-transport"
- connect_delay
- Default: 20
- periodic_delay
- Default: 1000
- username
- Default: undefined
- password
- Default: undefined
- mqtt_session
- The mqtt_session module which should be used. Default: cotonic.mqtt_session.
cotonic.mqtt_bridge.newBridge("test.mosquitto.org:8081",
{protocol: "wss"});
=> Connect the local broker to test.mosquitto.org via a websocket.
const decoder = new TextDecoder("utf-8");
cotonic.broker.subscribe("bridge/test.mosquitto.org:8081/bbc/subtitles/bbc_news24/raw",
function(m, t) {
console.log(decoder.decode(m.payload));
});
=> Subscribe to a local topic, it will be bridged from the server
to the page. This gets the raw subtitles of bbc news24.
cotonic.mqtt_bridge.findBridge([remote])
Find bridge remote, when remote is not specified, "origin" is used.
Returns the bridge, or undefined when the bridge is not found.
const b = cotonic.mqtt_bridge.findBridge("test.mosquitto.org:8081");
=> returns the bridge, or undefined
cotonic.mqtt_bridge.deleteBridge([remote])
Delete bridge remote, when remote is not specified, "origin" is used.
cotonic.mqtt_bridge.deleteBridge("test.mosquitto.org:8081");
ui
The user interface composer manages html snippets which can be placed in the DOM tree. When an
updated html snippet is delivered to the composer it will render it by using Google's incremental-dom library.
The updates will be applied incrementally directly to the DOM tree. The updates can be
delivered as html text snippets to the interface composer.
cotonic.ui.insert(targetId, mode, initialHTML, [priority])
Insert a new html snippet into the user interface composer. The snippet will be stored under the given
targetId. The element will not be placed in the dom-tree immediately. This will happen when one of the
render functions is called. Parameter mode supports the following options:
- inner or true
- The html-snippets update the innerHTML of the element.
- outer or false
- The html-snippets update the outerHTML of the element.
- shadow-open or shadow
- The html-snippets update the shadow DOM of the element. The element will be the shadow host.
The shadow dom will be put in "open" mode. When the shadow dow was not yet initialised, it will
be initialised when the element is rendered the first time. Using the shadow-dom makes it possible
to isolate the component from the css rules which are present on the page.
- shadow-closed
- Like "shadow-open", with the difference that the shadow dom will be initialised in "closed" mode.
The optional priority parameter indicates the render order of the elements.
Elements with a high priority are rendedered before lower priorities. This makes it possible to nest
elements.
cotonic.ui.insert("root", "outer", "
Hello World!
");
cotonic.ui.insert("shadow-root", "shadow", "
Hello World!
");
cotonic.ui.get(id)
Returns the current html snippet registered at id.
let currentHTML = cotonic.ui.get("root");
=> "Hello World!"
cotonic.ui.remove(id)
Remove the html snippet registered at id. Note that this will not remove the element from the dom-tree,
it will only remove it from the user interface composer. When the element must be removed it should first
be updated and set to a blank string and a render operation should be done.
cotonic.ui.remove("root");
cotonic.ui.update(id, htmlOrTokens)
Update the registered snippet for the registered element with the given id. The new snippet will be visible
after a render operation.
cotonic.ui.update("root", "
Hello Everybody!
");
=> The root element on the page will be updated.
cotonic.ui.render()
Trigger a render of all registered elements.
cotonic.ui.render();
=> All elements will be (re)rendered.
cotonic.ui.renderId(id)
Just render the element with the given id.
cotonic.ui.renderId("root");
cotonic.ui.updateStateData(model, states)
Communicate the state of the model to other non-cotonic components on the page. It can
be used to pass model state to SPA's or other modules. It sets a data attribute on the
html tag of the page.
The parameter model should be a string, states is an object
with values. The values of the states object are set as data attributes
on the html tag like this:
data-ui-<model>-<key>="<value>". When an empty object is
passed all data attributes of the model is cleared.
cotonic.ui.updateStateData("auth", {authorized: true});
=>
...
cotonic.ui.updateStateData("auth", {});
=>
...
cotonic.ui.updateStateClass(model, classes)
Update the class of the html tag. This makes it possible to communicate important
state changes to external components like SPA's. The parameter model should be
a string. Parameter classes a list of classes which must be set.
The following elements will be added to the class attribute
ui-state-<model>-<class>. Passing [] will clear all the class
attributes of the model.
cotonic.ui.updateStateClass("auth", ["unauthorized", "pending"]);
=>
cotonic.ui.updateStateClass("auth", ["authorized"]);
=>
cotonic.ui.on(topic, msg, event, [options])
Publish a DOM event on the local broker. This allows subscribers to react to user interface
events. Parameter topic is the topic on which the event will be published. The parameters
msg and event are included in the message which is published. The event parameter
is expected to be a DOM event. The options parameter is optional, it
can contain a cancel property which can be set to true, false or
"preventDefault" to indicate if the event should be cancelled or prevented.
The other options can be the normal options found in
publish.
document.addEvenListener("click", function(e) {
const topic = event.target.getAttribute("data-topic");
if(!topic) return;
cotonic.ui.on(topic, {foo: "bar"}, e);
}, {passive: true})
=> When somebody clicks on an element with has a data-topic="a/topic"
attribute, the event will be published on that topic.
tokenizer
The tokenizer transforms text to html tokens. The tokenizer is used by the
user interface composer in order to call the incremental-dom api.
It uses incremental-dom to do in-place diffing of the dom-tree.
Note: The tokenizer does not parse or validate the html. It just
tokenizes the input.
cotonic.tokenizer.tokens(text)
Transforms a string with html tags into a list of tokens. The tokens are
objects of the form: {type: "type", [args]}, with type being one of:
- open
-
- Represents an open tag. Contains the attribute tag which is
set to the tagname of the element, and the attribute attributes
which is a list of attributes of the element.
- close
-
- Represents a close tag. Contains the attribute tag which is
set to the tagname of the close element.
- void
-
- Represents a void element. The attribute tag is set to the
tagname of the void element.
- text
-
- Represents a test element. The attribute data is set to the
text data.
- doctype
-
- Represents a doctype element. The attribute attributes is
set to the attributes of the element.
- pi
-
- Represents a processing instruction element. The attribute tag
is set to the tagname of the processing instruction. The attribute
arguments contains the list of attributes.
- comment
-
- Represents a comment element. The attribute data contains
the text in the comment element.
cotonic.tokenizer.tokens("
Tokenizing
 is cool
");
=> [{type: "open", tag: "div", attributes: ["class", "example"]},
{type: "text", data: "Tokenizing"},
{type: "void", tag: "br", attributes: []},
{type: "text", data: " is cool"},
{type: "close", tag: "div"}]
cotonic.tokenizer.charref(text)
Transforms a html charref into a character.
cotonic.tokenizer.charref("#128540");
=> "😜"
cotonic.tokenizer.charref("amp");
=> "&"
Worker Functions
Workers are stand alone processes. They have no shared data with the page, nor
with other workers. Their memory and calling context is isolated. They can easily communicate
with other workers, the page, and servers by publising messages on topics, and subscribing
to them. Cotonic provides models, modules which are loaded and
ready for requests.
self.on_init(arguments)
The callback on_init is called when the worker receives the initialization
message by the page. It can take multiple arguments. The arguments are passed in via
the spawn args argument list.
This function can be used to initialize the worker. The callback is optional.
// Page code.
cotonic.spawn("example_worker", [amount, target]);
// Worker code
let amount = null;
let targetId = null;
self.on_init = function(n, id) {
amount = n;
targetId = id;
}
==> Worker receives the arguments which can be used for initialization.
self.connect(connectOptions)
Connect the worker to the page. Returns a promise. This promise is resolved when
the worker is connected to the page. When is indicated in the connectOptions that
the worker depends on other services the promise is resolved after those dependencies
have become available.
Parameter connectOptions supports the following options:
- name
- The name of the worker.
- depends
- A list of dependencies on which the worker needs. The connect promise will be
resolved, after the dependencies become available.
- provides
- A list of dependencies which is provided by this worker. The are published after
the worker is connected.
self.connect().then(
function() {
console.log("Connected");
}
);
=> The worker is being connected to the page.
self.connect({depends: ["model/ui",
"model/serviceWorker",
"worker/abc"]}).then(
function() {
console.log("Connected, the requested dependencies are available, and worker abc is started.");
}
);
=> The worker is being connected to the page, and the requested dependencies are available.
self.disconnect()
Disconnects the worker from the page. After this step it is no
longer possible to send and receive messages from the page.
self.disconnect();
=> The worker is disconnected from the page.
self.is_connected()
Returns true iff the worker is connected to the page,
false otherwise.
self.is_connected();
=> true
self.whenDependencyProvided(dependency)
Returns a Promise which is resolved when the external dependency is provided.
self.whenDependencyProvided("model/ui").then(
function() {
worker.publish("model/ui/insert/foo", {..});
});
self.whenDependenciesProvided(dependencies)
Returns a Promise which is resolved when all external dependencies are provided.
self.whenDependenciesProvided(["model/ui", "model/x"]).then(
function() {
...
});
==> The promise will be resolved after the ui and x model are provided.
self.provides(modelsAndWorkers)
Indicate to other workers and the page that this worker provides models or workers.
Other workers waiting on these dependencies will get notified when they become
available. The parameter modelsAndWorkers should be a list with model or
worker names this worker provides.
self.provides(["model/a", "model/b", "worker/x"])
==> When the worker connects, it will notify other workers that new models
have become available.
self.subscribe(topics, callback, ack_callback)
Subscribe the worker to the topics. When a message is received, the callback is called.
Callback is a function which receives two parameters. The first parameter is the message, the second
parameter an object returned by extract. This can be used to
easily extract elements from topic paths in an object. The parameter topics can be a string, or
a list of strings. The callback ack_callback is used when the page is subscribed, or when
there is a problem. Returns nothing.
function logSpeed(msg, args) {
if(args.boat_id) {
console.log("boat", args.boat_id, "is now moving at", msg.payload);
}
if(args.truck_id) {
console.log("truck", args.truck_id, "is now moving at", msg.payload);
}
}
self.subscribe(["truck/+boat_id/speed", "boat/+boat_id/speed"], logSpeed);
=> The function logSpeed will be called when somebody sends a message which
matches the topics.
self.unsubscribe(topics, callback, ack_callback)
Unsubscribe the worker from page. The worker will no longer receive messages from the specified topics.
self.unsubscribe();
self.publish(topic, message, options)
Publish message on topic. The options can be used to indicate
the quality of service, or if the message should be retained by the broker.
self.publish("world", "hello", {retain: true});
self.call(topic, message, options)
Publishes message on topic and subscribes itself to a reply topic.
Returns a promise which is fulfilled when a message is received on the reply topic. When
no message arrives, the promise is rejected. Returns a promise.
self.call("model/document/get/all")
.then(...)
.reject(...);
Models
Because workers run as independent components it is not possible to directly
call api's. Some api's are also not available to web workers. Models are
special modules, or workers, which publish their data, or are ready to
receive calls via mqtt topics.
The convention is that models provide their services via the following topic
tree.
- model/+modelName/get/+
- Call topics. When the model receives a publish, it returns the answer
to the reply topic.
- model/+modelName/post/+
- Topics used to post updates to the model.
- model/+modelName/delete/+
- Topics used to delete items managed by the model.
- model/+modelName/event/+
- Topics which the model publishes events on.
model/window
The window model can be used open and close windows.
Open a window. The payload of the message can be set t
- href
- The url of the window. See below.
- data-window
- A JSON string containing properties described below.
Or
- url
- The url of the page to open.
- name
- Specifies the target attribute of the window.
- _blank
- opens a new window.
- _parent
- loads the url in the parent window.
- _self
- replaces the current page.
- _top
- replaces any frameset that maybe loaded.
- name
- the name of the window to load.
- width
- The width of the window in pixels.
- height
- The height of the window in pixels.
- toolbar
- Wether or not to display the browsers toolbar.
- scrollbars
- Wether or not to display scrollbars.
- status
- Wether or not to add a status bar.
- resizable
- Wether or not the window is resizable.
- location
- Wether or not to display the address field.
- menubar
- Wether or not to display the menubar.
- centerBrowser
- Indicate wether or not to center the new window on top of the current active browser window.
- centerScreen
- Indicate wether or not to center the new window on the screen.
- top
- The top position of the window.
- left
- The left position of the window.
Logon in with Example.com
data-window="{'centerBrowser': true}"
==> The click on the link publishes is window open message which will open
a centered logon window.
self.publish("model/window/post/open", {url: "https://example.com/logon",
centerBrowser: true})
==> A worker opens a logon window.
Open a window.
 Close Window
==> Closes the current window.
model/document
The document model can be used to retrieve details about the current document.
Get all information on the current document. Includes screen size, cookies, user agent details.
self.call("model/document/get/all")
.then(function(m) {
console.log(m.payload)
});
=> {screen_width: 1280, screen_height: 800,
inner_width: 1047, inner_height: 292,
is_touch: false, …}
Returns the internationalization details of the current page.
self.call("model/document/get/intl")
.then(function(m) {
console.log(m.payload)
});
=> {timezone: {cookie: "", user_agent: "Europe/Amsterdam"},
language: {cookie: "", user_agent: "en-US", document: null}}
model/location
The location model can be used to retrieve information on the current location
of the page. It also allows subscription to location changes.

Redirect the user to another url
cotonic.broker.call("model/location/post/redirect", {url: "https://cotonic.org"})
=> // The user is redirect to cotonic.org.
Reload the current page. This can be handy when you know something on the server side has
changed.
cotonic.broker.call("model/location/post/reload")
=> // The page will reload.
<button data-onclick-topic="bridge/origin/model/xyz/post/doit"
data-onresponse-topic="model/location/reload">Do It</button>
When the xyz model on the server responds, the page will be reloaded
A message containing the query string part of the url will be published when it changes.
Note: the message is retained
cotonic.broker.subscribe("model/location/event/search",
function(m, a) {
console.log("query string changed", m.payload);
});
A message containing the pathname part of the url will be published when it changes.
Note: the message is retained
cotonic.broker.subscribe("model/location/event/pathname",
function(m, a) {
console.log("pathname changed", m.payload);
});
A message containing the hash part of the url will be published when it changes.
Note: the message is retained
cotonic.broker.subscribe("model/location/event/hash",
function(m, a) {
console.log("hash changed", m.payload);
});
When the location model is enabled, a retained message is published on this
topic. By subscribing to this topic it is possible to see when the model is
enabled. The payload of the message pong.
cotonic.broker.subscribe("model/location/event/ping",
function(m) {
console.log("The location model is enabled", m.payload)
})
=> Logs a message on the console when the location model is enabled.
The location has one configuration option.
- pathname_search
- Set to the current search parameters of the page. Alternatively this setting
can can be done as data-cotonic-pathname-search attribute on the body tag. dd>

...

model/ui
The ui model can be used to update the dom by publishing messages on one of the
model/ui/# topics. Elements can be inserted, deleted and updated. When
elements in the dom-tree are updated, the a message
model/ui/event/dom-updated/+key is published. This can be used to
react to dom-changes when they happen.
Insert a new ui snippet named key into the user interface composer.
Expects a message with the following properties.
- initialData
- The initial data to place in the dom tree.
- inner
- If set to true, the ui composer will update the inner html, when set
to false, the outer html
- priority
- An element with a high priority will be rendered before elements with a low
priority.
self.publish("model/ui/insert/root", {
initialData: "
Loading
",
inner: true
priority: 100
}, {retain: true});
=> When the ui composer receives this message it will add the
loading
Update the contents of ui snippet named key previously registered
by an insert. Expects a message with the html snippet as message.
self.publish("model/ui/update/root",
"");
=> The root element is updated.
Delete ui snippet named key from the user interface composer.
self.publish("model/ui/delete/root");
=> The root element is removed from the composer, but
stays in the DOM tree.
Trigger a render of all registered elements.
self.publish("model/ui/render");
Trigger a render of the element key
self.publish("model/ui/render.root");
Request rendering a template with parameters. A rendering engine must be
available to respond to the render requests. The render result will update
key element. Note: The element must first be inserted with
cotonic.ui.insert or
model/ui/insert/+key.
The payload of the render request should be:
- topic
- The topic on which the render engine is subscribed. Can be a local or a remote topic.
The response of the renderer will be updated on key
- data
- The data which the render engine can use to render the template.
- dedup
- Send the render request via a MQTT QoS 1 message. This means that we can
get multiple responses. Dedup makes sure the result will be rendered only once.
self.publish("model/ui/render-template/root",
{topic: "bridge/origin/model/template/get/render/hello.tpl",
dedup: true,
data: {name: "Bob"}
});
==> The render engine listening at bridge/origin/model/template receives
a render request. The render result will be placed in element root.
A message containing the user's activity status is published regularly
on this topic. The message is an object which contains a
is_active boolean property which indicates if the has been
active over the last period between publishes.
// worker example
self.subscribe("model/ui/event/recent-activity",
function(m) {
const a = m.payload.is_active?"active":"not active";
console.log("The user is: ", a);
}
);
=> Displays the user's activity status.
When the dom-tree is updated a message will be published. The
message is fired after the dom-tree is updated.
cotonic.broker.subscribe("model/ui/event/dom-updated/message-container",
function(m) {
const c = document.getElementById("message-container");
c.scrollTop = c.scrollHeight
}
);
=> Scrolls the messages bubble container to the bottom.
Events send to this topic will result in class and data attributes set on
the html of the document. The model attribute is used in the
data and class attributes. This can be used to signal the state of a model to
the document. This can be used to signal the state of cotonic workers or models to
other ui libraries like Elm or
React. The payload of the message:
- status
- Object with model statuses. Will be set as data attributes.
- classes
- List with model statuses. Will be set as classes.
self.publish("model/auth/event/ui-status", {status: {"auth": "anonymous"},
classes: ["anonymous"]});
==> model.ui adds clas "ui-state-auth-anonymous" and
adds data-ui-state-auth-auth="anonymous" to the html element of the document.
Init the topic event listener when new shadow roots are added.
- id
- Element id
cotonic.broker.subscribe("model/ui/event/new-shadow-root/data-list",
function(m) {
console.log("Init the event listener for", "data-list")
}
);
=> Init the topic event listener when new shadow roots are added.
model/lifecycle
Application lifecycle is a key way that modern operating systems manage resources.
On Android, iOS, and recent Windows versions, apps can be started and stopped at
any time by the OS. This allows these platforms to streamline and reallocate resources
where they best benefit the user.
Modern browsers will also suspend and discard pages. Browsers do not provide this
information in an orderly fashion. There are individual events like: load,
unload, and visibilitychange. The lifecycle model publishes the
different states a page can be in.
- active
-
The page has focus, and is visible in the foreground. It is important that
the page is responsive to user input. It may be needed to move non-important
work from the main thread to a worker.
- passive
-
The page has lost focus, but is still visible. It is important that ui updates
and animations still run smoothly. It may be a good time to store unsaved
application state.
- hidden
-
The page has lost focus, and is no longer visible, but it still exists. It is
likely that this is the end of user interaction with the page. Unsaved state
should be saved. It is also a good time to stop making UI updates, since they
won't be seen by user.
- frozen
-
The page has been cached to memory by the browser. It can resume in a
later stage. Javascript's timers and fetch callbacks no longer work.
Browsers can freeze pages to prevent full page reloads. This is a good time
to close any open Web Socket connections, close WebRTC channels because
the browser want's to conserve energy.
- terminated
-
The page will be terminated shortly.
The lifecycle model publishes the state the page is at on the
model/lifecycle/event/state topic as a retained message. This makes
it possible to get the current state at any moment, and be notified of changes
so the application can scale its resource usage at any moment.
State changes are always done in an orderly way. When a page goes from state
active to state hidden it is made sure that the passive
state is also published.
State transition diagram:
When the lifecycle model sees a state change in the page lifecycle state, its
state is published on this topic. The message is published as a retained message,
and is available when the model is active. Possible states are: active,
passive, hidden, frozen, and terminated.
// Subscribe in a worker
self.subscribe("model/lifecycle/event/state",
function(m) {
switch(m.payload) {
case "active":
case "passive":
// Speed up network usage again.
case "hidden":
// Slow down network usage.
break;
}
});
When the lifecycle model detects a change in the online state of the browser,
the state will be published on this topic. When the browser is online, true
will be published false otherwise.
self.subscribe("model/lifecycle/event/online",
function(m) {
if(m.payload) {
console.log("We are online");
} else {
console.log("We are offline");
}
}
);
When the lifecycle model is enabled it publishes a retained pong
message on this topic. This makes it possible to check if the model is enabled.
// Subscribe in a worker
self.subscribe("model/lifecycle/event/ping",
function() {
console.log("the lifecycle model is enabled")
});
model/autofocus
The autofocus model looks for elements with the autofocus attribute
which are just added to the dom tree. When this happens, it auto focusus them.
The reason for this is is that the autofocus attribute only works
during document render stage, but it is very handy to have available all the
time.
The element with key has just been focussed.
model/serviceWorker
The serviceWorker model makes it possible to communicate with other tabs
from the same site. This makes it possible to communicate important state
to all tabs.
The serviceWorker needs https to work correctly. The Chrome browser
does not accept self-signed certificates for running serviceWorkers.
Either run from localhost, use a real certificate, or follow the instructions
on this page by Dean Hume.
Safari and Firefox accept self-signed certificates for
running the serviceWorker.
Broadcast the message on channel. The message can be received
via the "model/serviceWorker/event/+channel topic. This works
across all open tabs.
// Publish from a worker
self.publish("model/serviceWorker/post/broadcast/background",
{hue: "blue", brightness: 45});
Subscribe to the broadcast channel of the serviceWorker. Messages
posted from other tabs or workers, including messages sent by the publisher
will be received.
// Subscribe on a page
cotonic.broker.subscribe("model/serviceWorker/event/broadcast/background",
function(m) {
console.log("Setting background to", m.payload);
setBackground(m.payload);
})
When the serviceWorker model is enabled it publishes a retained pong
message on this topic. This makes it possible to check if the model is enabled.
// Subscribe on a page
cotonic.broker.subscribe("model/serviceWorker/event/ping",
function() {
console.log("the serviceWorker model is enabled")
});
The service worker model has two configuration options.
- start_service_worker
- When set to false, the service worker will not start.
default true
- service_worker_src
- The url of the service worker which should be started.
default
/cotonic-service-worker.js

model/localStorage
Gets item key from localStorage. Returns the content as payload.
cotonic.broker.call("model/localStorage/get/a")
.then(
function(m) {
console.log("a is set to:", m.payload)
}
);
Update, or insert message under key in localStorage.
cotonic.broker.publish("model/localStorage/post/a", "Hello world!");
Delete item stored under key from localStorage.
cotonic.broker.publish("model/localStorage/delete/a");
Subscribe to changes or deletions from localStorage. When the message payload
is null the item is delete. Otherwise the payload is set to the
newly updated value.
cotonic.broker.subscribe("model/localStorage/event/+key",
function(m, a) {
if(m.payload === null) {
console.log("localStorage item:", a.key, "deleted");
else {
console.log("localStorage item:", a.key, "changed", m.payload);
}
});
=> Logs update to localStorage elements.
When the localStorage model is enabled it publishes a retained message
under the topic model/localStorage/event/ping. It makes it
possible to detect the localStorage model is enabled.
cotonic.broker.subscribe("model/localStorage/event/ping",
function() {
console.log("localStorage is enabled");
});
model.sessionStorage
The sessionStorage model provids access to the sessionStorage of
the browser. It makes it possible to set and retrieve values via
mqtt topics. For more information about the session storage see:
Get the element stored as key from the sessionStorage. Returns the
contents as payload, or null if it is not found.
self.call("model/sessionStorage/get/item-1")
.then(function(m) {
console.log("item-1", m.payload);
});
=> Logs the item-1 on the console, or null otherwise.
Get a sub element stored as key.subkey from the sessionStorage.
self.call("model/sessionStorage/get/item-2/a")
.then(function(m) {
console.log("item-2", m.payload);
});
=> Logs the item-2 on the console, or null otherwise.
Store a message under key in the sessionStorage.
self.publish("model/sessionStorage/post/item-1", "Cucumbers are sometimes green");
=> New value stored.
Store a message under key.subkey in the sessionStorage. When no
item is stored under key a new object is created, and subkey
is added as sub-element. When key exists it must be an object, then
subkey is added or overwritten.
self.publish("model/sessionStorage/post/item-2/a", "hello");
Delete an element stored under key from the sessionStorage.
self.publish("model/sessionStorage/delete/item-2");
Delete an element stored under key.subkey from the sessionStorage.
self.publish("model/sessionStorage/delete/item-2");
Subscribe to sessionStorage updates and deletes. When entry is updated
you will get a notification.
self.subscribe("model/sessionStorage/subscribe/+key",
function(m, a) {
console.log(m, a);
});
self.publish("model/sessionStorage/post/a", "hello");
self.publish("model/sessionStorage/post/b", "world");
=> Logs the update in the console
When the sessionStorage model is enabled a retained message is published
on the model/sessionStorage/event/ping topic.
let storageReady = false;
cotonic.broker.subscribe("model/sessionStorage/event/+key",
function(msg, args) {
switch(args.key)
case "pong":
storageReady = true;
break;
...
});
=> When the storage is ready a pong message will be available
Links
Introduction to Incremental DOM
MQTT Version 5.0 - OASIS
Web Workers API
sessionStorage API
Using shadow DOM
Change Log
— Aug 4, 2023 —
Diff —
Docs —
Download
-
Use esbuild instead of cat to make releases.
-
Moved modules to separate es modules for better adaptability.
— Jun 23, 2023 —
Diff —
Docs —
Download
-
Fixes a problem where the remote client topic was accidentally set to the
remote routing topic.
— May 26, 2023 —
Diff —
Docs —
Download
-
Added skip node functionality to be able to integrate dom-tree changing external
libraries.
— Apr 21, 2023 —
Diff —
Docs —
Download
-
Fix an issue with renaming response topics.
— Apr 17, 2023 —
Diff —
Docs —
Download
-
Fix a bug with queued messages where the routing-id was not known yet, or was
changed.
— Apr 4, 2023 —
Diff —
Docs —
Download
-
The service worker now supports displaying web push notifications.
— Dec 19, 2022 —
Diff —
Docs —
Download
-
Added events which allows seeing when a websocket connection is openend and closed.
— Oct 12, 2022 —
Diff —
Docs —
Download
— Jul 29, 2022 —
Diff —
Docs —
Download
-
If a window close is requested and there is no window.opener then optionally redirect
to the supplied url.
— Jul 26, 2022 —
Diff —
Docs —
Download
-
Added a redirect-local in order to safely redirect to a local url.
-
Documentation and site fixes.
— May 31, 2022 —
Diff —
Docs —
Download
-
Don't de-dup subscriptions from unspecified worker ids (wid).
-
Warn when unsubscribing from a topic, without specifying a worker id (wid).
-
Fix starting the python dev server.
-
Fix a typo in the specification of the page lifecycle state-machine.
Special thanks go to
@williamthome for fixing the
python dev environment.
— Jan 22, 2022 —
Diff —
Docs —
Download
-
Changed the way onclick and and onsubmit topics are handled. When such an event
is fired, cotonic traverers the parents of the target of the event to check for
the topic attribute. When it is found, a message is published with the attributes
of the elements between the target and the element on which the topic was found.
— Dec 6, 2021 —
Diff —
Docs —
Download
-
Cleaned up another couple of IE11 workarounds, and added extra tests.
— Oct 27, 2021 —
Diff —
Docs —
Download
-
Because IE11 is no longer supported, all lazy polyfill loading code has been removed.
— Aug 25, 2021 —
Diff —
Docs —
Download
-
Added model/location/post/reload model post.
— Jul 8, 2021 —
Diff —
Docs —
Download
-
Added model/lifecycle/event/state and model/lifecycle/event/online
events.
-
Various small fixes.
— Mar 15, 2021 —
Diff —
Docs —
Download
-
Added model/ui/event/node-created/+key and model/ui/event/node-deleted/+key
events.
-
Added model/document/post/cookie/+key and model/document/get/cookie/+key
to set and retrieve cookies.
-
Small fixes.
— Mar 14, 2021 —
Diff —
Docs —
Download
-
More documentation.
-
Autofocus model
-
Extend js configuration api to more easily setup the MQTT bridge.
-
Ability to pre-connect the bridge websocket very early to speed up connecting.
-
Ability to collect click and submit events before the bridge is setup to prevent
the loss of interactivity before everything is setup. After the bridge is connected
the click and submit messages collected will be published on origin.
-
And a lot of little fixes.
— Nov 2, 2020 —
Diff —
Docs —
Download
-
More documentation.
-
A js based configuration api.
-
And a lot of little fixes.
— Mar 1, 2020 —
Diff —
Docs —
Download
-
Added more documentation and an example.
-
Load the base worker library via a standard importScripts, instead of url blob.
-
The bridge now supports connecting to any MQTT server.
-
Removed the embedded polyfills, and use an external polyfill provider when needed.
Mostly for IE11.
— Feb 10, 2020 —
Diff —
Docs —
Download
-
Added documentation, and
-
made it possible to use the bridge to connect to mqtt servers
— Jan 30, 2020 —
Diff —
Docs —
Download
-
Fixed all the tests, and
-
made the documentation more readable on mobile.
— Jan 23, 2020 —
Docs —
Download


Contact
Questions?
If you have any questions, please don't hesitate to contact Hops4Hops. We can be reached through these options below or you can send us a question from the form.
Location
The City College of New York
160 Convent Ave.
New York, NY 10031


{% extends 'base.html' %} {% load static %} {% block title %}Register{% endblock %} {% block navbar %}
Toggle nav
The article is the best platform for worth idea spreading so you can start blogging ...
{{ blog.description|truncatewords:"20"|capfirst|safe }}
View details »


Store json data into Mysql using python
2013-10-28
Web services APIs such as weather underground data provided in json format is stored in Mysql table using this python script.
Based on stack overflow answers http://stackoverflow.com/questions/1640715/get-json-data-via-url-and-use-in-python-simplejson http://stackoverflow.com/questions/5687718/python-mysql-insert-data
import urllib2 import json import MySQLdb
req = urllib2.Request(“http://api.wunderground.com/api/YOUR API key/conditions/q/country/town.json”) opener = urllib2.buildopener() f = opener.open(req) data = json.load(f) print data[‘current_observation’][‘observation_location’][‘city’],data[‘currentobservation’][‘observationtimerfc822’]
conn = MySQLdb.connect(host= “localhost”, user=“YOUR username”, passwd=“YOUR password”, db=“database”) x = conn.cursor()
try: x.execute( “INSERT INTO CBEmeterology (Station, DateAP)” “VALUES (%s,%s)”,(data[‘current_observation’][‘observation_location’][‘city’],data[‘currentobservation’][‘observationtimerfc822’])) conn.commit() except: conn.rollback()
conn.close()
the script collects json from URL and then convert into a python object and feed into MySQL table using SQL command.


Home
About us
Gallery
Blog
Contact us
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
View
Info
Download
First
1
2
3
4
Last


Women in Tech
IIIT-Delhi
Menu
Home
Opportunities
Resources
Virtual Events
Blogs
Newsletters
Women in Tech Team
Contact Us
Women in Tech Calendar


Candidate Profile
| Name | Catherine Lister Searle |
| Party | Conservative Party |
| Address | Studio Flat 143 St Margarets Rd St Margarets TW1 1RG |
| Phone | 0208 892 0856 |
Background
Tell us about your education?
Educated in Australia, in a combination of Christian and State Schools, to University Honours Degree level.
What are three jobs you have held?
- Consultant Archaeologist, managing own consultancy in Tasmania, Australia, specialising in Aboriginal Cultural Heritage.
- Political Aide to Ministers/Shadow Secretaries in Australia & UK
- Project Manager in Social Care, Local Government
What are you links to the North Twickenham/St Margarets community?
Have lived in the area for three years
Why did/do you want to be a councilor?
I have a strong sense of commitment to community, wanting to actively do my part to make the world a better place, and wanting to help people in need.
Issues
What do you think are the top three issues for North Twickenham/St Margarets and what do you should be done about them?
- Council Tax – continuing to keep levels down, and communication to residents about what it is spent on and what difference it makes
- Aircraft Noise – continuing to campaign for a cap on volume of flights and no night flights
- Youth Issues – more funding for voluntary sector youth activities and for local youth amenities
What areas are you passionate about and what committees would you like to sit on?
I am passionate about high standards of social care, especially for children & young people, people with disabilities, and older people. I would like to sit on the Overview and Scrutiny Committee for Social Care and Housing.
Are there any big things you are looking to achieve or change?
I want to build on the sense of community St Margarets already enjoys, and ensure Council support and funding for positive community-building initiatives from St Margarets & North Twickenham residents.
If elected, how will you keep in-touch with your constituents?
Email & telephone, occasional surgeries and regular newsletters.
Fun
What is your favorite musical group/band/cd?
Telegraph Road by Dire Straits
What is your favorite book?
The Bible
What is the last book you read?
The Way they Learn, by Cynthia Tobias, exploring different styles of learning
What are three places you have lived?
- Hobart, Tasmania, Australia
- Melbourne, Victoria, Australia
- Docklands, London
What is your favorite meal?
Roast Lamb
What is your favorite place to take a holiday?
Israel, especially Jerusalem


Help
About
Day
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Room
Room 1
Room 2
Room 3
Number of Guests
Additional Guests
Price
Price with Tax


Description
Value of pointer 'varname', which points to allocated memory, is copied in copy constructor in.
Detector / Bug Pattern
Value of pointer 'varname', which points to allocated memory, is copied in copy constructor in.
More Information
Value of pointer 'varname', which points to allocated memory, is copied in copy constructor in.
Bad Code
class Line
{
public:
int getLength( void );
Line( int len );
// simple constructor
Line( const Line &obj);
// copy constructor
Line& operator= (const Line& m);
//Assignment operator
~Line();
// destructor
private:
int *ptr;
};
// Member functions definitions including constructor
Line::Line(int len)
{
cout << "Normal constructor allocating ptr" << endl;
// allocate memory for the pointer;
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj)
{
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
*ptr = *obj.ptr; // copy the value
}
Line::~Line(void)
{
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength( void )
{
return *ptr;
}
void display(Line obj)
{
cout << "Length of line : " << obj.getLength() << endl;
}
// Main function for the program
int main( )
{
Line line(10);
display(line);
return 0;
}
/*
When the above code is compiled and executed, it produces the following result:
Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
*/


|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object edu.internet2.middleware.grouper.privs.NamingPrivilege
public class NamingPrivilege
An instance of a granted naming privilege.
| Field Summary | |
|---|---|
static Set<Privilege> |
ADMIN_PRIVILEGES
any of these constitutes ADMIN on a stem note, keep most common/likely privs toward the front |
static Set<Privilege> |
ALL_ADMIN_PRIVILEGES
any of these constitutes some sort of ADMIN on a stem note, keep most common/likely privs toward the front |
static Set<Privilege> |
ALL_PRIVILEGES
ALL note, keep most common/likely privs toward the front |
static Set<Privilege> |
ATTRIBUTE_READ_PRIVILEGES
any of these constitutes STEM_ATTR_READ on a group note, keep most common/likely privs toward the front |
static Set<Privilege> |
ATTRIBUTE_UPDATE_PRIVILEGES
any of these constitutes STEM_ATTR_UPDATE on a group note, keep most common/likely privs toward the front |
static Privilege |
CREATE
can create objects in this stem |
static Set<Privilege> |
CREATE_IMPLIED_PRIVILEGES
these privileges are implied by CREATE |
static Set<Privilege> |
CREATE_PRIVILEGES
any of these constitutes CREATE on a stem note, keep most common/likely privs toward the front |
static Privilege |
STEM
can create stems in this stem |
static Privilege |
STEM_ATTR_READ
can read attributes on this stem |
static Set<Privilege> |
STEM_ATTR_READ_IMPLIED_PRIVILEGES
these privileges are implied by STEM_ATTR_READ |
static Set<Privilege> |
STEM_ATTR_READ_PRIVILEGES
any of these constitutes STEM_ATTR_READ on a stem note, keep most common/likely privs toward the front |
static Privilege |
STEM_ATTR_UPDATE
can update attributes on this stem |
static Set<Privilege> |
STEM_ATTR_UPDATE_IMPLIED_PRIVILEGES
these privileges are implied by STEM_ATTR_UPDATE |
static Set<Privilege> |
STEM_ATTR_UPDATE_PRIVILEGES
any of these constitutes STEM_ATTR_UPDATE on a stem note, keep most common/likely privs toward the front |
static Set<Privilege> |
STEM_IMPLIED_PRIVILEGES
these privileges are implied by STEM |
static Set<Privilege> |
STEM_PRIVILEGES
any of these constitutes STEM on a stem note, keep most common/likely privs toward the front |
| Constructor Summary | |
|---|---|
NamingPrivilege(Stem stem,
edu.internet2.middleware.subject.Subject subj,
edu.internet2.middleware.subject.Subject owner,
Privilege priv,
String klass,
boolean isRevokable,
String contextId1)
|
| Method Summary | |
|---|---|
int |
compareTo(Object o)
|
boolean |
equals(Object other)
|
String |
getContextId()
optionally link the audit id with the low level action |
GrouperAPI |
getGrouperApi()
get the object this privilege is assigned to (e.g. |
String |
getImplementationName()
Get name of implementation class for this privilege type. |
String |
getName()
Get name of privilege. |
edu.internet2.middleware.subject.Subject |
getOwner()
Get subject which was granted privilege on this object. |
Stem |
getStem()
Get object Stem that the privilege was
granted on. |
edu.internet2.middleware.subject.Subject |
getSubject()
Get subject which has this privilege. |
String |
getType()
get type of privilege (e.g. |
int |
hashCode()
|
void |
internalSetSubject(edu.internet2.middleware.subject.Subject subject)
if we are caching subject objects, then set it here... |
boolean |
isRevokable()
Returns true if privilege can be revoked. |
static Privilege |
listToPriv(String list)
convert a list to a privilege |
static String |
privToList(Privilege privilege)
convert a privilege to a list |
String |
toString()
|
| Methods inherited from class java.lang.Object |
|---|
getClass, notify, notifyAll, wait, wait, wait |
| Field Detail |
|---|
public static final Privilege CREATE
public static final Privilege STEM
public static Set<Privilege> STEM_PRIVILEGES
public static final Privilege STEM_ATTR_READ
public static Set<Privilege> STEM_ATTR_READ_PRIVILEGES
public static final Privilege STEM_ATTR_UPDATE
public static Set<Privilege> STEM_IMPLIED_PRIVILEGES
public static Set<Privilege> CREATE_IMPLIED_PRIVILEGES
public static Set<Privilege> STEM_ATTR_READ_IMPLIED_PRIVILEGES
public static Set<Privilege> STEM_ATTR_UPDATE_IMPLIED_PRIVILEGES
public static Set<Privilege> STEM_ATTR_UPDATE_PRIVILEGES
public static Set<Privilege> CREATE_PRIVILEGES
public static Set<Privilege> ALL_PRIVILEGES
public static Set<Privilege> ATTRIBUTE_READ_PRIVILEGES
public static Set<Privilege> ATTRIBUTE_UPDATE_PRIVILEGES
public static Set<Privilege> ADMIN_PRIVILEGES
public static Set<Privilege> ALL_ADMIN_PRIVILEGES
| Constructor Detail |
|---|
public NamingPrivilege(Stem stem, edu.internet2.middleware.subject.Subject subj, edu.internet2.middleware.subject.Subject owner, Privilege priv, String klass, boolean isRevokable, String contextId1)
| Method Detail |
|---|
public static String privToList(Privilege privilege)
privilege
-
public static Privilege listToPriv(String list)
list
-
public boolean equals(Object other)
equals
in class Object
Object.equals(java.lang.Object)
public int compareTo(Object o)
compareTo
in interface Comparable<Object>
Comparable.compareTo(java.lang.Object)
public int hashCode()
hashCode
in class Object
public String getImplementationName()
getImplementationName
in interface GrouperPrivilege
public boolean isRevokable()
isRevokable
in interface GrouperPrivilege
public String getName()
getName
in interface GrouperPrivilege
public edu.internet2.middleware.subject.Subject getOwner()
getOwner
in interface GrouperPrivilege
Subject
that was granted privilege.public Stem getStem()
Stem
that the privilege was
granted on.
Stem
object.public edu.internet2.middleware.subject.Subject getSubject()
getSubject
in interface GrouperPrivilege
Subject
that has this privilege.public String toString()
toString
in class Object
public GrouperAPI getGrouperApi()
GrouperPrivilege
getGrouperApi
in interface GrouperPrivilege
GrouperPrivilege.getGrouperApi()
public String getType()
GrouperPrivilege
getType
in interface GrouperPrivilege
GrouperPrivilege.getType()
public String getContextId()
public void internalSetSubject(edu.internet2.middleware.subject.Subject subject)
GrouperPrivilege
internalSetSubject
in interface GrouperPrivilege
GrouperPrivilege.internalSetSubject(Subject)
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


--- title: Boolean & Conditionals in Python author: Saurav Das date: '2020-10-12' slug: boolean-conditionals-in-python categories: - Python - Tutorials tags: - Python subtitle: '' summary: '' authors: [] lastmod: '2020-09-28T01:00:01-06:00' featured: no image: caption: '' focal_point: '' preview_only: no projects: [] ---
Boolean are the variable which have two possible values. Like say True and False
Note: I am going to run python chunks in this rmarkdown file and for this you need a package called reticulate.
library(reticulate)
x = True
print(x)
## True
print(type(x))
## <class 'bool'>
However, rather than describing the true or false in the code, we can get the true or false using the boolean operators like;
a== b , a is equal to b a < b, a less than b a <= b, a less than or equal to b a != b, a not equal to be a > b, a greater than b a >= b, a greater than or equal to b
so, lets run a function to see how it works,
Lets define a function which returns whether a candidate can run for presidential election or not based on his age. (Presidential candidate age should be 35)
def can_run_for_president(age):
return age >= 35
print ("Can a 25 year old run for the president?", can_run_for_president(25))
## Can a 25 year old run for the president? False
print("Can a 70 year old run for the president?", can_run_for_president(70))
## Can a 70 year old run for the president? True
Okay, lets make it one level complicated and combine with boolean values “and” “or” and “not”
so, the condition for us presidential candidate should be: he must be a natural born citizen and at least 35 years old
def can_run_for_president(age, is_natural_born_citizen):
return is_natural_born_citizen and (age >= 35)
print(can_run_for_president(19, True))
## False
print(can_run_for_president(55, False))
## False
print(can_run_for_president(55, True))
## True
Lets combine the boolean with conditionals “if”, “else”, and “elif”
def inspect(x):
if x == 0:
print(x, "is zero")
elif x > 0:
print(x, "is positive")
elif x < 0:
print(x, "is negative")
else:
print(x, "is unlike anything I've ever seen...")
inspect(0)
## 0 is zero
inspect(-15)
## -15 is negative
Question 1: In the cell below, define a function called sign which takes a numerical argument and returns -1 if it’s negative, 1 if it’s positive, and 0 if it’s 0.
def sign(x):
if x == 0:
return 0
elif x>0:
return 1
else:
return -1
sign(5)
## 1
sign(0)
## 0
sign(-1)
## -1


--- layout: default title: Resources on Product Design --- Resources on Product Design A personal curated library of resources on product design by Pedro Carmo Table of Contents Accessibility & Inclusivity Approach Copywriting Film Grid Interaction Design Interface & Visual Design Mobile Principles Process Talks Typography UX Web Development Accessibility & Inclusivity {% for accessibility in site.data.accessibility %} {{ accessibility.title }} by {{ accessibility.author }} {% endfor %} Approach {% for approach in site.data.approach %} {{ approach.title }} by {{ approach.author }} {% endfor %} Copywriting {% for copy in site.data.copy %} {{ copy.title }} by {{ copy.author }} {% endfor %} Film {% for film in site.data.films %} {{ film.title }} by {{ film.author }} {% endfor %} Grid {% for grid in site.data.grids %} {{ grid.title }} by {{ grid.author }} {% endfor %} Interaction Design {% for interaction in site.data.interactions %} {{ interaction.title }} by {{ interaction.author }} {% endfor %} Interface & Visual Design {% for interface in site.data.interfaces %} {{ interface.title }} by {{ interface.author }} {% endfor %} iOS Development {% for ios in site.data.ios %} {{ ios.title }} by {{ ios.author }} {% endfor %} Mobile {% for mobile in site.data.mobile %} {{ mobile.title }} by {{ mobile.author }} {% endfor %} Principles {% for principle in site.data.principles %} {{ principle.title }} by {{ principle.author }} {% endfor %} Process {% for process in site.data.process %} {{ process.title }} by {{ process.author }} {% endfor %} Talks {% for talk in site.data.talks %} {{ talk.title }} by {{ talk.author }} {% endfor %} Typography {% for type in site.data.type %} {{ type.title }} by {{ type.author }} {% endfor %} UX {% for ux in site.data.ux %} {{ ux.title }} by {{ ux.author }} {% endfor %} Web Development {% for development in site.data.development %} {{ development.title }} by {{ development.author }} {% endfor %} This web page is a library of resources around the topic of product design. It's open-sourced on github if you wish to contribute in any way. Thanks for stopping by.
A personal curated library of resources on product design by Pedro Carmo
{{ accessibility.title }}
{{ approach.title }}
{{ copy.title }}
{{ film.title }}
{{ grid.title }}
{{ interaction.title }}
{{ interface.title }}
{{ ios.title }}
{{ mobile.title }}
{{ principle.title }}
{{ process.title }}
{{ talk.title }}
{{ type.title }}
{{ ux.title }}
{{ development.title }}
This web page is a library of resources around the topic of product design. It's open-sourced on github if you wish to contribute in any way. Thanks for stopping by.


--- title: Collection Item date: 04-05-1984 tags: - tag1 - tag2 ---
Just to test that we can read the tags


Bingo
Contrary to most of the nonsense conversations I have on a daily basis, this one presented a reasonable opportunity to delve into.  We had the tradition of playing BINGO during the school anniversary festivities. Vividly recall the day when I thought I had won a smaller prize with the “O” pattern: only to realize I had one mistake, unfortunately.
Despite I never won myself the maximum prize (around $2000), attributed to the first player completing the whole board, I witness the excitement of lucky people walking among a big crowd towards the presenter to verify their victory. Among those memories, the following questions appeared in my mind: How difficult was actually to win, afterall? Is it a worthy investment? Is it actually easier to win forming the “N” pattern? Ergo, this post.
Game Description
The U.S. 75-ball bingo game consists of disposable paper cardboards which contain a unique combination of 25 numbers on squares arranged in five vertical columns (corresponding to each of the BINGO letters) and five side to side rows. Each space is covered except the center one, which is free space. The range of printed numbers that can appear on any order on the card is restricted by column. In particular, the column ‘B’ only contains numbers between 1 and 15 inclusive, the column ‘I’ only contains numbers between 16 and 30 inclusive, and so on.
Each of the 75 possible numbers is randomly drawn by a presenter of the game, while each player marks the announced number down on their BINGO card, until a winner is revealed within the audience. The most common winning scenario is a full cover pattern. That is, when each of the 24 numbers is marked on a cardboard, its owner can claim BINGO. This is usually assigned to the highest prize of the event. Other winning scenarios consist of forming particular patterns of marked cells in the board. For example, forming a letter ‘O’ with a fraction of the marked cells. That would require all the numbers in the columns ‘B’ and ‘O’, as well as the first and last elements of each column, to be marked as the picture below shows.
Analysis
Let us define the following variables
- \(X\), number of draws so far
- \(\mathcal{F}\), random event of winning with full cover pattern.
- \(\mathcal{B}\), random event of winning with “B” pattern.
- \(\mathcal{O}\), random event of winning with “O” pattern.
- \(\mathcal{N}\), random event of winning with “N” pattern.
Full Cover Probability
The cumulative probability of winning with a full cover board in less or equal than \(D\) draws is,
\[\mathbb{P}_F ( X \leq D ) = \frac{\binom{51}{D-24}}{\binom{75}{D}}\]The distribution has support only for values \(D\geq 24\). Thus,
\[\mathbb{P}_F[ X = D ] = \mathbb{P}_F[ X \leq D ] - \mathbb{P}_F[X \leq D-1]\] \[\mathbb{P}_F[ X = D ] = \frac{24\binom{51}{D-25}}{ (D-24)\binom{75}{D-1}}\]Pattern Probability
The cumulative probability of winning with a particular pattern \(P\) in less or equal than \(D\) draws is given by
\[\mathbb{P}_P ( X \leq D ) = \sum_{i=P_{size}}^{24} \frac{\binom{24}{i}\binom{51}{D-i}}{\binom{75}{D}} \times \text{Probability of Forming Pattern P with i marked numbers}\]In particular, we have for patterns \(\mathcal{N}, \mathcal{O}\) and \(\mathcal{B}\) the following expressions,
\[\mathbb{P}_B ( X \leq D ) = \sum_{i=12}^{24} \frac{\binom{24}{i}\binom{51}{D-i}}{\binom{75}{D}} \times \frac{\binom{12}{12}\binom{12}{i-12}}{\binom{24}{i}} = \sum_{i=18}^{24} \frac{ \binom{12}{i-12}\binom{51}{D-i}}{\binom{75}{D}}\] \[\mathbb{P}_O ( X \leq D ) = \sum_{i=16}^{24} \frac{\binom{24}{i}\binom{51}{D-i}}{\binom{75}{D}} \times \frac{\binom{16}{16}\binom{8}{i-16}}{\binom{24}{i}} = \sum_{i=16}^{24} \frac{ \binom{8}{i-16}\binom{51}{D-i}}{\binom{75}{D}}\] \[\mathbb{P}_B ( X \leq D ) = \sum_{i=18}^{24} \frac{\binom{24}{i}\binom{51}{D-i}}{\binom{75}{D}} \times \frac{\binom{18}{18}\binom{6}{i-18}}{\binom{24}{i}} = \sum_{i=18}^{24} \frac{ \binom{6}{i-18}\binom{51}{D-i}}{\binom{75}{D}}\]Probability Distributions
We can visually inspect how the cumulative distribution probabilities for the different winning cases look like. We can notice that only after \(60\) draws the chances stop being negligible. This explains why the game lasts that long without winner, even for simpler patterns.
One interesting observation is how close the probability curves are from each other, defying our initial intuition. We expected that winning by full cover represented a much slimmer chance than by an \(\mathcal{O}\) pattern, for instance. Yet, we observe that at \(70\) draws one has around \(0.15\) probability of winning by full cover vs. a \(0.3\) probability of winning by \(\mathcal{O}\) pattern, if playing in isolation.
However, in the most realistic BINGO setting we have a huge crowd (\(N\sim 1000\)) so we care about the probability of at least one person winning given \(X\) draws so far. Thus, we proceed to obtain the cumulative probability distributions of at least one person winning for each pattern.
If the probability of an event happening is \(p\), then the probability that it will happen at least once in \(N\) times is \(1 - (1-p)^N\). Using this formula, we obtained the following results,
The updated results match our intuition: where each cumulative probability curve is drastically spread after \(\sim 40\) draws. From these distributions we can calculate the expected value of draws required to win for each case.
| Pattern | Expected Draws To Win - 1 player | Expected Draws To Win - 1k players |
|---|---|---|
| Full Cover | 72.96 | 58.79 |
| B | 72.00 | 53.16 |
| O | 71.52 | 50.56 |
| N | 70.15 | 43.56 |
Finally, this analysis leads to another open question for the curious reader: what would be the ‘optimal’ way of assigning the prizes’ values given our probabilistic findings?
I am confident that my high school BINGO’s organizers did not think this thoroughly nor did the math. Since \(\mathcal{N}, \mathcal{O}\) and even \(\mathcal{B}\) were given kitchen appliances or TVs as prizes, while the full cover win was rewarded with the highest prize of 2000 dollars, for a 3 dollar BINGO board.
References
- Blog post on Bingo Calculations - link
- Blog post on Computation of Bingo Probabilities Numerically - link
Acknowlegdments
Thanks to Maximilian Montserrat for engaging conversations and running the numerical calculations code to verify results.


(Geo)Parquet
New in version 3.5.
Driver short name
Parquet
Build dependencies
Parquet component of the Apache Arrow C++ library
From https://databricks.com/glossary/what-is-parquet: "Apache Parquet is an open source, column-oriented data file format designed for efficient data storage and retrieval. It provides efficient data compression and encoding schemes with enhanced performance to handle complex data in bulk. Apache Parquet is designed to be a common interchange format for both batch and interactive workloads."
This driver also supports geometry columns using the GeoParquet specification.
Note
The driver should be considered experimental as the GeoParquet specification is not finalized yet.
The GeoParquet 1.0.0-beta1 specification is supported since GDAL 3.6.2
Driver capabilities
Supports Create()
This driver supports the GDALDriver::Create()
operation
Supports Georeferencing
This driver supports georeferencing
Supports VirtualIO
This driver supports virtual I/O operations (/vsimem/, etc.)
Open options
GEOM_POSSIBLE_NAMES=value: (GDAL >= 3.8) Defaults to
geometry,wkb_geometry,wkt_geometry
. Comma separated list of possible names for geometry column(s). Only used for files without GeoParquet dataset-level metadata. Columns are recognized as geometry columns only if they are of type binary (they are assumed to contain WKB encoded geometries), or if they are of type string and contain the "wkt" substring in their name (they are then assumed to contain WKT encoded geometries).CRS=value: (GDAL >= 3.8) To set or override the CRS of geometry columns. The string is typically formatted as CODE:AUTH (e.g "EPSG:4326"), or can be a PROJ.4 or WKT CRS string.
Creation issues
The driver supports creating only a single layer in a dataset.
Layer creation options
COMPRESSION=[NONE/UNCOMPRESSED/SNAPPY/GZIP/BROTLI/ZSTD/LZ4_RAW/LZ4_HADOOP]:
Compression method. Available values depend on how the Parquet library was compiled. Defaults to SNAPPY when available, otherwise NONE.
GEOMETRY_ENCODING=[WKB/WKT/GEOARROW]: Defaults to
WKB
. Geometry encoding. Other encodings (WKT and GEOARROW) are not allowed by the GeoParquet specification, but are handled as an extension, for symmetry with the Arrow driver.ROW_GROUP_SIZE=<integer>: Defaults to
65536
. Maximum number of rows per group.GEOMETRY_NAME=value: Defaults to
geometry
. Name of geometry column.FID=value: Name of the FID (Feature Identifier) column to create. If none is specified, no FID column is created. Note that if using ogr2ogr with the Parquet driver as the target driver and a source layer that has a named FID column, this FID column name will be automatically used to set the FID layer creation option of the Parquet driver (unless
-lco FID=
is used to set an empty name)POLYGON_ORIENTATION=[COUNTERCLOCKWISE/UNMODIFIED]: Defaults to
COUNTERCLOCKWISE
. Whether exterior rings of polygons should be counterclockwise oriented (and interior rings clockwise oriented), or left to their original orientation.EDGES=[PLANAR/SPHERICAL]: Defaults to
PLANAR
. How to interpret the edges of the geometries: whether the line between two points is a straight cartesian line (PLANAR) or the shortest line on the sphere (geodesic line) (SPHERICAL).CREATOR=value: Name of creating application.
SQL support
SQL statements are run through the OGR SQL engine. Statistics can be used to speed-up evaluations of SQL requests like: "SELECT MIN(colname), MAX(colname), COUNT(colname) FROM layername"
Dataset/partitioning read support
Starting with GDAL 3.6.0, the driver can read directories that contain several
Parquet files, and expose them as a single layer. This support is only enabled
if the driver is built against the arrowdataset
C++ library.
Note that no optimization is currently done regarding filtering.
Multithreading
Starting with GDAL 3.6.0, the driver will use up to 4 threads for reading (or the
maximum number of available CPUs returned by CPLGetNumCPUs()
if
it is lower by 4). This number can be configured with the configuration option
GDAL_NUM_THREADS
, which can be set to an integer value or
ALL_CPUS
.
Validation script
The validate_geoparquet.py Python script can be used to check compliance of a Parquet file against the GeoParquet specification.
To validate only metadata:
python3 validate_geoparquet.py my_geo.parquet
To validate metadata and check content of geometry column(s):
python3 validate_geoparquet.py --check-data my_geo.parquet
Conda-forge package
The driver can be installed as a plugin for the libgdal
conda-forge package with:
conda install -c conda-forge libgdal-arrow-parquet


GFTTDetector Wrapping class for feature detection using the goodFeaturesToTrack function.
The function finds the most prominent corners in the image or in the
specified image region, as described in [Shi94]:
- Function calculates the corner quality measure at every source image
pixel using the cv.cornerMinEigenVal or cv.cornerHarris.
- Function performs a non-maximum suppression (the local maximums in
3x3
neighborhood are retained).
- The corners with the minimal eigenvalue less than
QualityLevel * max_{x,y}(qualityMeasureMap(x,y))
are rejected.
- The remaining corners are sorted by the quality measure in the
descending order.
- Function throws away each corner for which there is a stronger
corner at a distance less than
maxDistance
.
References:
[Shi94]:
Jianbo Shi and Carlo Tomasi. "Good features to track".
In Computer Vision and Pattern Recognition, 1994. Proceedings CVPR'94.,
1994 IEEE Computer Society Conference on, pages 593-600. IEEE, 1994.
|
|
addlistener |
Add listener for event. |
|
|
clear |
Clears the algorithm state |
|
|
delete |
Destructor |
|
|
detect |
Detects keypoints in an image or image set. |
|
|
empty |
Checks if detector object is empty. |
|
|
eq |
== (EQ) Test handle equality. |
|
|
findobj |
Find objects matching specified conditions. |
|
|
findprop |
Find property of MATLAB handle object. |
|
|
ge |
>= (GE) Greater than or equal relation for handles. |
|
|
getDefaultName |
Returns the algorithm string identifier |
|
|
gt |
> (GT) Greater than relation for handles. |
| Sealed
|
isvalid |
Test handle validity. |
|
|
le |
<= (LE) Less than or equal relation for handles. |
|
|
load |
Loads algorithm from a file or a string |
|
|
lt |
< (LT) Less than relation for handles. |
|
|
ne |
~= (NE) Not equal relation for handles. |
|
|
notify |
Notify listeners of event. |
|
|
save |
Saves the algorithm parameters to a file |
|
|
typeid |
Name of the C++ type (RTTI) |


--- title: Reading archive image: --- {% assign counter = 0 %} {% for post in site.categories.booknotes %} {% assign counter = counter | plus: 1 %} {% endfor %} {{page.title}} All {{ counter }} book notes {% for post in site.categories.booknotes %} {{ post.title }} {% endfor %}
All {{ counter }} book notes


---
layout: page
title: Predicate Abstraction for Relaxed Memory Models
---
Virtual Machine with our tool CUPEX preinstalled.
- Note: we tested the Virtual Machine, by giving it 14GB of RAM. Make sure your host machine has 16GB or more.
- Download the virtual machine image from here.
- Unzip it and run it in VirtualBox.
- Login
- Open the file run_benchmark.py and select which algorithms to verify (uncomment lines to be executed).
- Run ./run_benchmark.py
- Details are presented in the README.


Shiv Sena says next Maharashtra CM will be from party, rules out NCP role
Shiv Sena will win in fight for justice, says Shiv Sena leader Sanjay Raut.
by Press Trust of IndiaShiv Sena leader Sanjay Raut on Tuesday said Maharashtra's next chief minister will be from his party, as the deadlock to form a new government in state continued after election results on October 28.
"The politics of Maharashtra is changing...in our fight for justice, we will win," said Raut, who is also a member of the Rajya Sabha.
"The decision on Maharashtra will be taken in Maharashtra, the chief minister will be from the Shiv Sena," Raut said in Mumbai, ruling out a role for Nationalist Congress Party (NCP) leader Sharad Pawar.
The Bharatiya Janata Party won 105 seats, its ally Shiv Sena 56, the NCP 54, and Congress 44 in the elections. The Shiv Sena has been demanding the chief minister’s post after elections gave the saffron alliance a combined seat strength of 161, way past the 145 majority mark in the 288-member House.


{% extends 'base.html' %} {% load bootstrap3 %} {% block content %}
{{ image.location }}
Caption : {{ image.caption | safe }}
Likes : {{ image.likes }}
Sign up to see photos and videos from your friends.
Sign Up
By signing up, you agree to our Terms , Data Policy and Cookies Policy .
Have an account? Sign In


{% extends "base.html" %} {% block title %}WattTime: FAQ{% endblock %} {% block content %}
WattTime is a newly-formed nonprofit (501(c)(3) status pending). We also plan to launch a for-profit venture so that we can better expand our capability to help energy consumers make decisions according to their own values. No matter what our legal status is, we will always be devoted to our environmental mission and to our community.
As far as we have been able to determine, WattTime is pursuing a fundamentally novel approach to fighting climate change. While our approach works according to economic theory, we never fully trust theory until it is backed up by hard data and experience. (And neither should you!) By participating in our beta tests, you will help validate the concept and provide critical insight for scaling WattTime to improve the future of energy for yourself and millions of other users. We hope that the excitement of being one of the first to use WattTime's products and services will make up for any occasional glitches that may occur; we'd love to hear your feedback about what's working and what's not.
Fantastic, we're excited to hear from you! Please get in touch.
Yes, yes we do. For example: an iPhone app is under active development, there's a long list of regions we plan to expand to, major breakthroughs in energy economics are on the horizon, and we're investigating a variety of ways to use WattTime data to control the smart devices in your connected home or work (aka "Internet of Things").
You can reach us via the contact page. We’re happy to help! Or you can read the source and even submit a patch if that's how you roll.
You can create a new account here (click on the "sign up" tab).
Your username is your email address. You can reset your password here. Let us know if you run into trouble.
WattTime Alerts is free! Please note however that WattTime Alerts can send occasional text messages (you control the frequency), so if you pay to receive and send text messages, normal rates may apply. Please check with your mobile carrier.
Currently Alerts by SMS are available in California and New England (Massachusetts, Conneticut, Rhode Island, Vermont, New Hampshire, and Maine). Morning Forecast Alerts by email are also available in California. If you'd like to be notified when WattTime Alerts become available in your area, just sign up for an account! In the meantime, if you live in the Pacific Northwest or the Midwest, you can see how clean you electricity is at any time by visiting WattTime Explorer.
To change your settings, including unsubscribing from Alerts, just go to your profile and edit your preferences.
Our goal is to give you maximum control over the environmental impacts of your own energy use in as convenient a fashion as possible. Different kinds of appliances are convenient to control in different ways—for example, sometimes laundry can wait until tomorrow, but you probably wouldn’t want to turn off your thermostat for a whole day! The more we know about your appliances, the more convenient our messaging can be, and the more relevant to you. But we’re only asking to help tailor your experience. If you’d rather not tell us about your particular equipment, you are welcome to opt for the generic messages instead.
We contact you when the grid is particularly clean or dirty, but of course we can't control exactly when that will be. In fact the electricity fuel mix can be quite unpredictable, depending on everything from weather to the strategies of different power plants. (Otherwise we could just hand out calendars!) We’ll do our best not to text you more than about the amount you signed up for, but some days the grid is pretty average all day and there’s just not much to report. You can always see the recent status of your grid using WattTime Explorer.
Currently WattTime Explorer is available in California, New England, the Pacific Northwest, and the Midwest. If you'd like to be notified when WattTime Explorer becomes available in your area, just sign up for an account!
Currently WattTime Shift is only available in California. If you'd like to be notified when WattTime Shift becomes available in your area, just sign up for an account! In the meantime, if you live in New England, the Pacific Northwest, or the Midwest, you can see how clean your electricity is at any time by visiting WattTime Explorer.
Check out your profile! Note that these stats include every time you've used WattTime Shift when you were logged in, and only the times when you were logged in; more accurate impact tracking coming soon.


Recorded Steps |
|
|
|
This file contains all the steps and information that was recorded to help you describe the recorded steps to others. Before sharing this file, you should verify the following:
Passwords or any other text you typed were not recorded, except for function and shortcut keys that you used. You can do the following: |
|
|
Steps |
|
|
|
|
|
Step 1: (11/13/2013 8:06:09 PM) User Comment: "type in correct username, password" |
|
|
|
Step 2: (11/13/2013 8:06:20 PM) User Comment: "press log in" |
|
|
|
Step 3: (11/13/2013 8:06:56 PM) User Comment: "a login success window will pop-up if login info is correct" |
|
|
|
Step 4: (11/13/2013 8:07:27 PM) User Comment: "main interface window will pop-up after user is authenticated" |
|
|
|
Step 5: (11/13/2013 8:07:50 PM) User Comment: "press update to pull the newest records from the database" |
|
|
|
Step 6: (11/13/2013 8:08:32 PM) User Comment: "Click on one record to show the image, patient info, patient history and the response panel" |
|
|
|
Step 7: (11/13/2013 8:09:21 PM) User Comment: "patient info and patient history are located on this pane and can be shown by clicking on the correct tab" |
|
|
|
Step 8: (11/13/2013 8:09:51 PM) User Comment: "radiologists/managers can view the image and leave response on this panel" |
|
|
|
Step 9: (11/13/2013 8:10:23 PM) User Comment: "when response is successful, it will pop-up and display the message" |
|
|
|
Step 10: (11/13/2013 8:10:48 PM) User Comment: "open up the manager panel by clicking on this button" |
|
|
|
Step 11: (11/13/2013 8:11:10 PM) User Comment: "click on this button to update the info" |
|
|
|
Step 12: (11/13/2013 8:11:34 PM) User Comment: "info of all fieldworkers and radiologists are shown here" |
|
|
Additional Details |
|
|
|
The following section contains the additional details that were recorded. These details help accurately identify the programs and UI you used in this recording. This section may contain text that is internal to programs that only very advanced users or programmers may understand. Please review these details to ensure that they do not contain any information that you would not like others to see. |
|
|


Players and Games
New Player Name
Add player
Games
Players
CKthe1
Thunder Julia
Maribelle
Madison WI
VS Opponent:
CKthe1
Thunder Julia
Maribelle
Madison WI
Player Score:
Opponent Score:
Add Games
Player Name
Player Score
Opponent Name
Opponent Score
Winner
Ckthe1
21
Maribelle
20
Ckthe1


aaand a few words to conclude:
Previous (Related) Works: I have worked on a few occasions with API and wearables on both: theoretical and practical grounds:
- Event Locator: Based on Processing, an application matching last.fm and songkick (?) data to visualise upcoming concerts of users' favourite artists in the USA.
More about this at this link.
- Unnamed: a research project utilising Machine Learning (with Python and SpaCy library), Virtual Reality environment built in Unity3D and Processing application made for extracting images with FlickrAPI to project nuanced environments in conjunction with featured songs and its lyrics. I didn't upload the .apk or other packages yet but the
final (semi-finished) paper-format deliverable can be found here
- HCI and smartwatches: I did a mini-(hci)-analysis around this topic and came up with a solution, that users might want to pay with their watches.
My participant liked the idea More info can be found
at this link
Current Issues: I'm still struggling with myself in relation to making myself just do the work as I should be doing, considering I am actually very interested in doing it also in terms of my own spectrum and how much I could potentially learn through this work about myself and the differences between me and how others look at this but the procrastination is still winning this one, hopefully not for long!
Progress? I'm still in the process of getting a grip on the topic, I have a few papers on my mind to go through and I'm also sorting the subpage on my website, where I'll be throwing in what I'm doing. So far, I made a retrospection to when I used Gear S3 for ~3 weeks while I was on exchange in Munich. It seems, that with just a few sensors, a smartwatch can actually gather a quite impressively comprehensive dataset and visualise it in a very informative manner.
I attached some lengthy screenshots with descriptions and translations (as I could not trigger an English version for some reason) it's somewhat a take on a case study but I plan on going more comprehensively very soon and potentially delving into a paper on smartwatches that was featured a while back on Naseem's seminar, which I believe could align with what I'll be researching.
Long story short, I plan on going a bit more technically and thoroughly on the case studies as suggested and preparing a ground-up, in-detail research.
PS: I know I should have limited the post just to research questions but considering the students have provided quite extensive descriptions last week, I felt inclined to catch up with everyone :)


Loops
Problem 4. Lexicographically smallest
- Write a script that finds the lexicographically smallest and largest property in document, window and navigator objects.
Document:
Smallest:
Largest:
Window:
Smallest:
Largest:
Navigator:
Smallest:
Largest:


…or, “The Difference Between a Fad and a Usable, Meaningful Tool is the Teacher.”
I missed #EdChat…again. It’s one of the downsides of living just inside the Central Time Zone border. The 12PM EdChat is during a class, before my lunch hour. The evening EdChat is during the dinner hour, before my work block at home. It’s a no win situation.
It does provide me a chance, though, to scan through the feeds and see some of the comments made during the hour. I can also always go back and read the archive maintained by the amazing Jerry Swiatek. I noticed a couple of tweets immediately this evening when I was catching up concerning the Flipped Classroom, which prompted this post.
I think the flipped classroom is here to stay for a variety of reasons, but I’ll narrow it down to the top three or four I end up discussing most frequently.
1) The Flipped Classroom is more than watching Khan Academy videos at home every night.
This is probably the biggest argument I get against the Flipped Classroom…all we’re doing is moving class time into homework time (I’m not going to get in the homework argument right now). The short answer is yes, we do move instruction to time outside of class, but it is so much more than simply throwing video into the mix. I’m sure that most of the time I’m preaching to the choir on this blog, but we all know that “technology integration” is a much bigger challenge than putting a YouTube video on your class website for kids to watch.
The use of video-as-instruction was best described by my friend, Ramsey Musallam. He says that the purpose of the video is to offset the cognitive load that comes along with learning new material.
There are times where direct instruction (or lecture…you choose) is appropriate for the task you are trying to accomplish (see paragraph 4, about linear regression). We are simply using video to remove that portion of direct instruction. We can then maximize collaboration, interaction, and synthesis of new material or content during class because we aren’t spending 30-40 minutes lecturing at the front.
I teach in an urban district where biology isn’t really important to many of my kids. The flipped classroom helps me increase engagement and interest because they can choose when to do their work. They’ve never been given this choice…they’ve never had the opportunity to set their own schedule (within reason…there is much more than what I’m speaking to at the moment) and because I am trusting them, they are learning about things that matter to them. I truly don’t believe my classes would look the way they do if I were the one driving instruction all day, every day.
2) The Flipped Classroom promotes bad pedagogy.
I agree totally with this statement. I would also argue that traditional classrooms can promote bad pedagogy, but we don’t make a big fuss over those because they’re “tried and tested teachers.” We should always be trying to improve our pedagogy, regardless of what we call our method. The Flipped Classroom does not make you a magical and inspiring teacher…your kids might resent your more for it because you’re pushing them to go beyond the give-and-take education they’ve had up until now.
Looking at the class time we’re opening up by time-shifting content delivery, good teachers will fill it with learning experiences, labs, discussions, problem-solving, assimilation work, and creative work that expands upon and enhances the content. Regardless of the methods, we should be providing those opportunities for learners in our schools. But, we either A) waste time with lecture in class, or B) have the time, but choose to fill it with worksheets because they’re easier.
I can be a bad teacher regardless of what methods I choose to use. Pedagogy must come first, and the flipped classroom is not excused from that expectation.
3) The Flipped Classroom can’t work for English and Social Studies, so it won’t ever become a major tool.
While I do agree that the flipped class is mostly centered in science and math right now, I do know of many other classes in the humanities (English, history, reading or writing workshop classes, economics) that are using flipped classroom ideas.
Remember, the flipped classroom isn’t a prescribed methodology…it is an ideology that uses technology to expand the classroom and allow more time for inquiry, discussion, debate…fill in the rest for your particular class. It is a choice to offset as much direct instruction in a medium that is appropriate for your learners. That may be videos, it may be articles, it might be a project.
* * *
Now, back to my title. Notice that the constant in each section above is a teacher that is working hard for their students. We are not replacing the teacher with the soft glow of a computer screen. We are not relegating kids to computer labs and cubicles. The teacher is present and active…a member of the learning community. Rather than being a dispenser of information, the teacher is an active learner with the group. We are there for support and guidance, not as sages or simply another reference. Our questioning and probing should drive deeper understanding and ownership if the content.
Fads come and go because while they’re fun and work to help engagement in the moment, they don’t do much to push learning in the long run. Meaningful change happens when teachers, students, parents, administrators, and other community members come together to support student growth in any form.
The Flipped Classroom isn’t a passing phase…I think it is a middle-ground from 100% lecture-driving instruction to a mix of direct instruction, creative thinking, collaborative learning, and application of content. I am only in my third year of teaching, so I feel extremely fortunate to have found this so early. This is all I know, and it makes sense to me. For those of you that have been teaching for 10, 20, or even 30 years, the Flipped Classroom is a great bridge to more student-led classes.
There is a continually growing network of people from around the world and across all content that are looking for your expertise. Check the Flipped Class Network out and see what is really going on behind the scenes.
——
For a longer, more in-depth look at the Flipped Classroom, you can read The Flipped Class Manifest written by myself and others that address the issues above and more.
Written on December 7th, 2011 by Brian Bennett Categorized in: All Flipclass Teaching
Leave a comment


--- layout: post title: Windows date: '2013-06-25T14:11:44-04:00' tags: - poem - technology - original tumblr_url: http://poetry.liabogoev.com/post/53857290829/windows ---
If files held dust like archives did,
I’d blow it off like clouds of old,
to show you what I used to write,
and what this binary holds.
Today I found these floppy disks,
in a bin, in the garage,
and punching in the little square,
it seemed like a mirage.
The folders, there they were,
all stacked up like before,
the icons yellowed, 8-bit
just like the days of yore.
The sound it made, so strange
Since I heard it, it’d been years
A whine, a groan, a kind of roar,
it did nothing for my fears.
But there, in the window
I saw the files and folder,
these poems, they’re mine,
Yes, but so much older.
Nine years since little fingers,
on Compaq keyboards clack,
and now all I can think of,
is how to get them back.


All
struct All
Keys that availible for all hits in Google Analytics Measurement Protocol.
-
This will only change when there are changes made that are not backwards compatible.
Note
- Example:
v=1
Declaration
Swift
static let protocolVersion: String
- Example:
-
The format is UA-XXXX-Y. All collected data is associated by this ID.
- Example:
tid=UA-XXXX-Y
Declaration
Swift
static let trackingID: String
- Example:
-
Indicates the data source of the hit. Hits sent from analytics.js will have data source set to ‘web’; hits sent from one of the mobile SDKs will have data source set to ‘app’.
Note
- Example:
ds=app
Declaration
Swift
static let dataSource: String
- Example:
-
This field is required if User ID (uid) is not specified in the request. This anonymously identifies a particular user, device, or browser instance. For the web, this is generally stored as a first-party cookie with a two-year expiration. For mobile apps, this is randomly generated for each particular instance of an application install. The value of this field should be a random UUID (version 4) as described in documentation
- Example:
cid=35009a79-1a05-49d7-b876-2b884d0f825b
Declaration
Swift
static let clientID: String
- Example:
-
Declaration
Swift
static let screenResolution: String
-
Declaration
Swift
static let userLanguage: String
-
Declaration
Swift
static let hitType: String
-
Undocumented
See moreDeclaration
Swift
struct HitType
-
Custom Dimension Each custom dimension has an associated index. There is a maximum of 20 custom dimensions (200 for Analytics 360 accounts). The dimension index must be a positive integer between 1 and 200, inclusive.
Note
- Example:
cd1=Sports cd2=Cooking
Declaration
Swift
static let customDimension: String
- Example: