Class: Concurrent::Agent
- Inherits:
-
Synchronization::LockableObject
- Object
- Synchronization::LockableObject
- Concurrent::Agent
- Includes:
- Concern::Observable
- Defined in:
- lib/concurrent/agent.rb
Overview
Agent
is inspired by Clojure's agent
function. An agent is a shared, mutable variable providing independent,
uncoordinated, asynchronous change of individual values. Best used when
the value will undergo frequent, complex updates. Suitable when the result
of an update does not need to be known immediately. Agent
is (mostly)
functionally equivalent to Clojure's agent, except where the runtime
prevents parity.
Agents are reactive, not autonomous - there is no imperative message loop
and no blocking receive. The state of an Agent should be itself immutable
and the #value
of an Agent is always immediately available for reading by
any thread without any messages, i.e. observation does not require
cooperation or coordination.
Agent action dispatches are made using the various #send
methods. These
methods always return immediately. At some point later, in another thread,
the following will happen:
- The given
action
will be applied to the state of the Agent and theargs
, if any were supplied. - The return value of
action
will be passed to the validator lambda, if one has been set on the Agent. - If the validator succeeds or if no validator was given, the return value
of the given
action
will become the new#value
of the Agent. See#initialize
for details. - If any observers were added to the Agent, they will be notified. See
#add_observer
for details. - If during the
action
execution any other dispatches are made (directly or indirectly), they will be held until after the#value
of the Agent has been changed.
If any exceptions are thrown by an action function, no nested dispatches
will occur, and the exception will be cached in the Agent itself. When an
Agent has errors cached, any subsequent interactions will immediately throw
an exception, until the agent's errors are cleared. Agent errors can be
examined with #error
and the agent restarted with #restart
.
The actions of all Agents get interleaved amongst threads in a thread pool.
At any point in time, at most one action for each Agent is being executed.
Actions dispatched to an agent from another single agent or thread will
occur in the order they were sent, potentially interleaved with actions
dispatched to the same agent from other sources. The #send
method should
be used for actions that are CPU limited, while the #send_off
method is
appropriate for actions that may block on IO.
Unlike in Clojure, Agent
cannot participate in Concurrent::TVar
transactions.
Example
def next_fibonacci(set = nil)
return [0, 1] if set.nil?
set + [set[-2..-1].reduce{|sum,x| sum + x }]
end
# create an agent with an initial value
agent = Concurrent::Agent.new(next_fibonacci)
# send a few update requests
5.times do
agent.send{|set| next_fibonacci(set) }
end
# wait for them to complete
agent.await
# get the current value
agent.value #=> [0, 1, 1, 2, 3, 5, 8]
Observation
Agents support observers through the Observable mixin module. Notification of observers occurs every time an action dispatch returns and the new value is successfully validated. Observation will not occur if the action raises an exception, if validation fails, or when a #restart occurs.
When notified the observer will receive three arguments: time
, old_value
,
and new_value
. The time
argument is the time at which the value change
occurred. The old_value
is the value of the Agent when the action began
processing. The new_value
is the value to which the Agent was set when the
action completed. Note that old_value
and new_value
may be the same.
This is not an error. It simply means that the action returned the same
value.
Nested Actions
It is possible for an Agent action to post further actions back to itself. The nested actions will be enqueued normally then processed after the outer action completes, in the order they were sent, possibly interleaved with action dispatches from other threads. Nested actions never deadlock with one another and a failure in a nested action will never affect the outer action.
Nested actions can be called using the Agent reference from the enclosing
scope or by passing the reference in as a "send" argument. Nested actions
cannot be post using self
from within the action block/proc/lambda; self
in this context will not reference the Agent. The preferred method for
dispatching nested actions is to pass the Agent as an argument. This allows
Ruby to more effectively manage the closing scope.
Prefer this:
agent = Concurrent::Agent.new(0)
agent.send(agent) do |value, this|
this.send {|v| v + 42 }
3.14
end
agent.value #=> 45.14
Over this:
agent = Concurrent::Agent.new(0)
agent.send do |value|
agent.send {|v| v + 42 }
3.14
end
NOTE Never, under any circumstances, call any of the "await" methods
(#await, #await_for, #await_for!, and #wait) from within an action
block/proc/lambda. The call will block the Agent and will always fail.
Calling either #await or #wait (with a timeout of nil
) will
hopelessly deadlock the Agent with no possibility of recovery.
Thread-safe Variable Classes
Each of the thread-safe variable classes is designed to solve a different problem. In general:
- Agent: Shared, mutable variable providing independent, uncoordinated, asynchronous change of individual values. Best used when the value will undergo frequent, complex updates. Suitable when the result of an update does not need to be known immediately.
- Atom: Shared, mutable variable providing independent, uncoordinated, synchronous change of individual values. Best used when the value will undergo frequent reads but only occasional, though complex, updates. Suitable when the result of an update must be known immediately.
- AtomicReference: A simple object reference that can be atomically. Updates are synchronous but fast. Best used when updates a simple set operations. Not suitable when updates are complex. AtomicBoolean and AtomicFixnum are similar but optimized for the given data type.
- Exchanger: Shared, stateless synchronization point. Used when two or more threads need to exchange data. The threads will pair then block on each other until the exchange is complete.
- MVar: Shared synchronization point. Used when one thread must give a value to another, which must take the value. The threads will block on each other until the exchange is complete.
- ThreadLocalVar: Shared, mutable, isolated variable which holds a different value for each thread which has access. Often used as an instance variable in objects which must maintain different state for different threads.
- TVar: Shared, mutable variables which provide coordinated, synchronous, change of many stated. Used when multiple value must change together, in an all-or-nothing transaction.
Defined Under Namespace
Classes: Error, ValidationError
Constant Summary
Instance Attribute Summary (collapse)
-
- (undocumented) error_mode
readonly
The error mode this Agent is operating in.
Class Method Summary (collapse)
-
+ (Boolean) await(*agents)
Blocks the current thread (indefinitely!) until all actions dispatched thus far to all the given Agents, from this thread or nested by the given Agents, have occurred.
-
+ (Boolean) await_for(timeout, *agents)
Blocks the current thread until all actions dispatched thus far to all the given Agents, from this thread or nested by the given Agents, have occurred, or the timeout (in seconds) has elapsed.
-
+ (Boolean) await_for!(timeout, *agents)
Blocks the current thread until all actions dispatched thus far to all the given Agents, from this thread or nested by the given Agents, have occurred, or the timeout (in seconds) has elapsed.
Instance Method Summary (collapse)
-
- (Concurrent::Agent) <<(action)
Dispatches an action to the Agent and returns immediately.
-
- (Object) add_observer(observer = nil, func = :update, &block)
included
from Concern::Observable
Adds an observer to this set.
-
- (Boolean) await
Blocks the current thread (indefinitely!) until all actions dispatched thus far, from this thread or nested by the Agent, have occurred.
-
- (Boolean) await_for(timeout)
Blocks the current thread until all actions dispatched thus far, from this thread or nested by the Agent, have occurred, or the timeout (in seconds) has elapsed.
-
- (Boolean) await_for!(timeout)
Blocks the current thread until all actions dispatched thus far, from this thread or nested by the Agent, have occurred, or the timeout (in seconds) has elapsed.
-
- (Integer) count_observers
included
from Concern::Observable
Return the number of observers associated with this object.
-
- (Object) delete_observer(observer)
included
from Concern::Observable
Remove
observer
as an observer on this object so that it will no longer receive notifications. -
- (Observable) delete_observers
included
from Concern::Observable
Remove all observers associated with this object.
-
- (nil, Error) error
(also: #reason)
When #failed? and #error_mode is
:fail
, returns the error object which caused the failure, elsenil
. -
- (Boolean) failed?
(also: #stopped?)
Is the Agent in a failed state?.
-
- (Agent) initialize(initial, opts = {})
constructor
Create a new
Agent
with the given initial value and options. - - (Boolean) restart(new_value, opts = {})
-
- (Boolean) send(*args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately.
-
- (Boolean) send!(*args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately.
-
- (Boolean) send_off(*args, &action) {|agent, value, *args| ... }
(also: #post)
Dispatches an action to the Agent and returns immediately.
-
- (Boolean) send_off!(*args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately.
-
- (Boolean) send_via(executor, *args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately.
-
- (Boolean) send_via!(executor, *args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately.
-
- (Object) value
(also: #deref)
The current value (state) of the Agent, irrespective of any pending or in-progress actions.
-
- (Boolean) wait(timeout = nil)
Blocks the current thread until all actions dispatched thus far, from this thread or nested by the Agent, have occurred, or the timeout (in seconds) has elapsed.
-
- (Observable) with_observer(observer = nil, func = :update, &block)
included
from Concern::Observable
As
#add_observer
but can be used for chaining.
Constructor Details
- (Agent) initialize(initial, opts = {})
Create a new Agent
with the given initial value and options.
The :validator
option must be nil
or a side-effect free proc/lambda
which takes one argument. On any intended value change the validator, if
provided, will be called. If the new value is invalid the validator should
return false
or raise an error.
The :error_handler
option must be nil
or a proc/lambda which takes two
arguments. When an action raises an error or validation fails, either by
returning false or raising an error, the error handler will be called. The
arguments to the error handler will be a reference to the agent itself and
the error object which was raised.
The :error_mode
may be either :continue
(the default if an error
handler is given) or :fail
(the default if error handler nil or not
given).
If an action being run by the agent throws an error or doesn't pass
validation the error handler, if present, will be called. After the
handler executes if the error mode is :continue
the Agent will continue
as if neither the action that caused the error nor the error itself ever
happened.
If the mode is :fail
the Agent will become #failed? and will stop
accepting new action dispatches. Any previously queued actions will be
held until #restart is called. The #value method will still work,
returning the value of the Agent before the error.
219 220 221 222 |
# File 'lib/concurrent/agent.rb', line 219 def initialize(initial, opts = {}) super() synchronize { ns_initialize(initial, opts) } end |
Instance Attribute Details
- (undocumented) error_mode (readonly)
The error mode this Agent is operating in. See #initialize for details.
183 184 185 |
# File 'lib/concurrent/agent.rb', line 183 def error_mode @error_mode end |
Class Method Details
+ (Boolean) await(*agents)
Blocks the current thread (indefinitely!) until all actions dispatched
thus far to all the given Agents, from this thread or nested by the
given Agents, have occurred. Will block when any of the agents are
failed. Will never return if a failed Agent is restart with
:clear_actions
true.
NOTE Never, under any circumstances, call any of the "await" methods
(#await, #await_for, #await_for!, and #wait) from within an action
block/proc/lambda. The call will block the Agent and will always fail.
Calling either #await or #wait (with a timeout of nil
) will
hopelessly deadlock the Agent with no possibility of recovery.
448 449 450 451 |
# File 'lib/concurrent/agent.rb', line 448 def await(*agents) agents.each { |agent| agent.await } true end |
+ (Boolean) await_for(timeout, *agents)
Blocks the current thread until all actions dispatched thus far to all the given Agents, from this thread or nested by the given Agents, have occurred, or the timeout (in seconds) has elapsed.
NOTE Never, under any circumstances, call any of the "await" methods
(#await, #await_for, #await_for!, and #wait) from within an action
block/proc/lambda. The call will block the Agent and will always fail.
Calling either #await or #wait (with a timeout of nil
) will
hopelessly deadlock the Agent with no possibility of recovery.
462 463 464 465 466 467 468 469 |
# File 'lib/concurrent/agent.rb', line 462 def await_for(timeout, *agents) end_at = Concurrent.monotonic_time + timeout.to_f ok = agents.length.times do |i| break false if (delay = end_at - Concurrent.monotonic_time) < 0 break false unless agents[i].await_for(delay) end !!ok end |
+ (Boolean) await_for!(timeout, *agents)
Blocks the current thread until all actions dispatched thus far to all the given Agents, from this thread or nested by the given Agents, have occurred, or the timeout (in seconds) has elapsed.
NOTE Never, under any circumstances, call any of the "await" methods
(#await, #await_for, #await_for!, and #wait) from within an action
block/proc/lambda. The call will block the Agent and will always fail.
Calling either #await or #wait (with a timeout of nil
) will
hopelessly deadlock the Agent with no possibility of recovery.
481 482 483 484 |
# File 'lib/concurrent/agent.rb', line 481 def await_for!(timeout, *agents) raise Concurrent::TimeoutError unless await_for(timeout, *agents) true end |
Instance Method Details
- (Concurrent::Agent) <<(action)
Dispatches an action to the Agent and returns immediately. Subsequently, in a thread from a thread pool, the #value will be set to the return value of the action. Appropriate for actions that may block on IO.
330 331 332 333 |
# File 'lib/concurrent/agent.rb', line 330 def <<(action) send_off(&action) self end |
- (Object) add_observer(observer = nil, func = :update, &block) Originally defined in module Concern::Observable
Adds an observer to this set. If a block is passed, the observer will be created by this method and no other params should be passed.
- (Boolean) await
Blocks the current thread (indefinitely!) until all actions dispatched
thus far, from this thread or nested by the Agent, have occurred. Will
block when #failed?. Will never return if a failed Agent is #restart
with :clear_actions
true.
Returns a reference to self
to support method chaining:
current_value = agent.await.value
NOTE Never, under any circumstances, call any of the "await" methods
(#await, #await_for, #await_for!, and #wait) from within an action
block/proc/lambda. The call will block the Agent and will always fail.
Calling either #await or #wait (with a timeout of nil
) will
hopelessly deadlock the Agent with no possibility of recovery.
349 350 351 352 |
# File 'lib/concurrent/agent.rb', line 349 def await wait(nil) self end |
- (Boolean) await_for(timeout)
Blocks the current thread until all actions dispatched thus far, from this thread or nested by the Agent, have occurred, or the timeout (in seconds) has elapsed.
NOTE Never, under any circumstances, call any of the "await" methods
(#await, #await_for, #await_for!, and #wait) from within an action
block/proc/lambda. The call will block the Agent and will always fail.
Calling either #await or #wait (with a timeout of nil
) will
hopelessly deadlock the Agent with no possibility of recovery.
362 363 364 |
# File 'lib/concurrent/agent.rb', line 362 def await_for(timeout) wait(timeout.to_f) end |
- (Boolean) await_for!(timeout)
Blocks the current thread until all actions dispatched thus far, from this thread or nested by the Agent, have occurred, or the timeout (in seconds) has elapsed.
NOTE Never, under any circumstances, call any of the "await" methods
(#await, #await_for, #await_for!, and #wait) from within an action
block/proc/lambda. The call will block the Agent and will always fail.
Calling either #await or #wait (with a timeout of nil
) will
hopelessly deadlock the Agent with no possibility of recovery.
376 377 378 379 |
# File 'lib/concurrent/agent.rb', line 376 def await_for!(timeout) raise Concurrent::TimeoutError unless wait(timeout.to_f) true end |
- (Integer) count_observers Originally defined in module Concern::Observable
Return the number of observers associated with this object.
- (Object) delete_observer(observer) Originally defined in module Concern::Observable
Remove observer
as an observer on this object so that it will no
longer receive notifications.
- (Observable) delete_observers Originally defined in module Concern::Observable
Remove all observers associated with this object.
- (nil, Error) error Also known as: reason
When #failed? and #error_mode is :fail
, returns the error object
which caused the failure, else nil
. When #error_mode is :continue
will always return nil
.
239 240 241 |
# File 'lib/concurrent/agent.rb', line 239 def error @error.value end |
- (Boolean) failed? Also known as: stopped?
Is the Agent in a failed state?
401 402 403 |
# File 'lib/concurrent/agent.rb', line 401 def failed<EMAIL_ADDRESS>end |
- (Boolean) restart(new_value, opts = {})
When an Agent is #failed?, changes the Agent #value to new_value
then un-fails the Agent so that action dispatches are allowed again. If
the :clear_actions
option is give and true, any actions queued on the
Agent that were being held while it was failed will be discarded,
otherwise those held actions will proceed. The new_value
must pass the
validator if any, or restart
will raise an exception and the Agent will
remain failed with its old #value and #error. Observers, if any, will
not be notified of the new state.
423 424 425 426 427 428 429 430 431 432 433 434 |
# File 'lib/concurrent/agent.rb', line 423 def restart(new_value, opts = {}) clear_actions = opts.fetch(:clear_actions, false) synchronize do raise Error.new('agent is not failed') unless failed? raise ValidationError unless ns_validate(new_value) @current.value = new_value @error.value = nil @queue.clear if clear_actions ns_post_next_job unless @queue.empty? end true end |
- (Boolean) send(*args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately. Subsequently, in a thread from a thread pool, the #value will be set to the return value of the action. Action dispatches are only allowed when the Agent is not #failed?.
The action must be a block/proc/lambda which takes 1 or more arguments.
The first argument is the current #value of the Agent. Any arguments
passed to the send method via the args
parameter will be passed to the
action as the remaining arguments. The action must return the new value
of the Agent.
- #send and #send! should be used for actions that are CPU limited
- #send_off, #send_off!, and #<< are appropriate for actions that may block on IO
- #send_via and #send_via! are used when a specific executor is to be used for the action
277 278 279 |
# File 'lib/concurrent/agent.rb', line 277 def send(*args, &action) enqueue_action_job(action, args, Concurrent.global_fast_executor) end |
- (Boolean) send!(*args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately. Subsequently, in a thread from a thread pool, the #value will be set to the return value of the action. Action dispatches are only allowed when the Agent is not #failed?.
The action must be a block/proc/lambda which takes 1 or more arguments.
The first argument is the current #value of the Agent. Any arguments
passed to the send method via the args
parameter will be passed to the
action as the remaining arguments. The action must return the new value
of the Agent.
- #send and #send! should be used for actions that are CPU limited
- #send_off, #send_off!, and #<< are appropriate for actions that may block on IO
- #send_via and #send_via! are used when a specific executor is to be used for the action
286 287 288 289 |
# File 'lib/concurrent/agent.rb', line 286 def send!(*args, &action) raise Error.new unless send(*args, &action) true end |
- (Boolean) send_off(*args, &action) {|agent, value, *args| ... } Also known as: post
Dispatches an action to the Agent and returns immediately. Subsequently, in a thread from a thread pool, the #value will be set to the return value of the action. Action dispatches are only allowed when the Agent is not #failed?.
The action must be a block/proc/lambda which takes 1 or more arguments.
The first argument is the current #value of the Agent. Any arguments
passed to the send method via the args
parameter will be passed to the
action as the remaining arguments. The action must return the new value
of the Agent.
- #send and #send! should be used for actions that are CPU limited
- #send_off, #send_off!, and #<< are appropriate for actions that may block on IO
- #send_via and #send_via! are used when a specific executor is to be used for the action
293 294 295 |
# File 'lib/concurrent/agent.rb', line 293 def send_off(*args, &action) enqueue_action_job(action, args, Concurrent.global_io_executor) end |
- (Boolean) send_off!(*args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately. Subsequently, in a thread from a thread pool, the #value will be set to the return value of the action. Action dispatches are only allowed when the Agent is not #failed?.
The action must be a block/proc/lambda which takes 1 or more arguments.
The first argument is the current #value of the Agent. Any arguments
passed to the send method via the args
parameter will be passed to the
action as the remaining arguments. The action must return the new value
of the Agent.
- #send and #send! should be used for actions that are CPU limited
- #send_off, #send_off!, and #<< are appropriate for actions that may block on IO
- #send_via and #send_via! are used when a specific executor is to be used for the action
301 302 303 304 |
# File 'lib/concurrent/agent.rb', line 301 def send_off!(*args, &action) raise Error.new unless send_off(*args, &action) true end |
- (Boolean) send_via(executor, *args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately. Subsequently, in a thread from a thread pool, the #value will be set to the return value of the action. Action dispatches are only allowed when the Agent is not #failed?.
The action must be a block/proc/lambda which takes 1 or more arguments.
The first argument is the current #value of the Agent. Any arguments
passed to the send method via the args
parameter will be passed to the
action as the remaining arguments. The action must return the new value
of the Agent.
- #send and #send! should be used for actions that are CPU limited
- #send_off, #send_off!, and #<< are appropriate for actions that may block on IO
- #send_via and #send_via! are used when a specific executor is to be used for the action
310 311 312 |
# File 'lib/concurrent/agent.rb', line 310 def send_via(executor, *args, &action) enqueue_action_job(action, args, executor) end |
- (Boolean) send_via!(executor, *args, &action) {|agent, value, *args| ... }
Dispatches an action to the Agent and returns immediately. Subsequently, in a thread from a thread pool, the #value will be set to the return value of the action. Action dispatches are only allowed when the Agent is not #failed?.
The action must be a block/proc/lambda which takes 1 or more arguments.
The first argument is the current #value of the Agent. Any arguments
passed to the send method via the args
parameter will be passed to the
action as the remaining arguments. The action must return the new value
of the Agent.
- #send and #send! should be used for actions that are CPU limited
- #send_off, #send_off!, and #<< are appropriate for actions that may block on IO
- #send_via and #send_via! are used when a specific executor is to be used for the action
318 319 320 321 |
# File 'lib/concurrent/agent.rb', line 318 def send_via!(executor, *args, &action) raise Error.new unless send_via(executor, *args, &action) true end |
- (Object) value Also known as: deref
The current value (state) of the Agent, irrespective of any pending or in-progress actions. The value is always available and is non-blocking.
228 229 230 |
# File 'lib/concurrent/agent.rb', line 228 def value @current.value # TODO (pitr 12-Sep-2015): broken unsafe read? end |
- (Boolean) wait(timeout = nil)
Blocks the current thread until all actions dispatched thus far, from this thread or nested by the Agent, have occurred, or the timeout (in seconds) has elapsed. Will block indefinitely when timeout is nil or not given.
Provided mainly for consistency with other classes in this library. Prefer
the various await
methods instead.
NOTE Never, under any circumstances, call any of the "await" methods
(#await, #await_for, #await_for!, and #wait) from within an action
block/proc/lambda. The call will block the Agent and will always fail.
Calling either #await or #wait (with a timeout of nil
) will
hopelessly deadlock the Agent with no possibility of recovery.
392 393 394 395 396 |
# File 'lib/concurrent/agent.rb', line 392 def wait(timeout = nil) latch = Concurrent::CountDownLatch.new(1) enqueue_await_job(latch) latch.wait(timeout) end |
- (Observable) with_observer(observer = nil, func = :update, &block) Originally defined in module Concern::Observable
As #add_observer
but can be used for chaining.


--- layout: post title: Jamis Buck is working on Basecamp categories: - jobs author: admin published: true date: 2005-01-07 20:19:53.000000000 +00:00 ---
Along with the announcement of the latest major upgrade to Basecamp, I’ve unveiled who the mysterious programmer we’ve brought on at 37signals is. So I thought I’d also wish him a warm welcome on landing a Rails-based job from the Rails weblog.
Congratulations on landing a contract working with Rails, Jamis Buck :)
You may recognize the name from his many contributions to the Ruby community. Most recently, the SQLite3 bindings that’s taking the dream of self-contained Rails applications a big step closer to reality.
UPDATE: Jamis shares a few more details.


I produced the designs from my mood board. I thought about their manufacturing standards and materials. I used the Euro design language and metric system as the standard due to a change in the sphere of influence.
I based the Five CRED on €1 dimensions and the Ten CRED on €2 dimensions. (European Central Bank, 2020) . However, coins will be made of metallic polymer plastic reducing precious metals usage similar to the German €5 released in 2016. (Sparrow, 2015)
Bills will be in portrait, making it look suitable for e-me. Polymer plastic will still be used due to its recylable nature. The 100 CRED note follow the €100 dimensions and 500 CRED follow the €500 dimensions.
Currency embeds circuitry allowing it to transmit Bluetooth signal to the e-me device when currency changes hands. The integrated circuit exists in both coins and notes.
Bank Cards contain biometric security to authenticate owners when making transactions.


IICSA Esrever
More projects like this (need to allow popups)Encode/Decode
Result:
Note: there are no seperate encoding/decoding areas as encoding is a reversing operation, meaning that encoding is actually the same as decoding. Therefore if you encode something twice, you actually decode it.


Authenticator for UI dashboard.
UI dashboard authenticator based on configuration file.
UI dashboard authenticator based on configuration file.
It has three categories of users: admins, users, and guests. admins have unlimited permission, like shutdown a cluster, add/remove machines. users have limited permission to submit an application and etc.. guests can not submit/kill applications, but can view the application status.
see conf/gear.conf section gearpump.security.config-file-based-authenticator to find information about how to configure this authenticator.
[Security consideration] It will keep one-way sha1 digest of password instead of password itself. The original password is NOT kept in any way, so generally it is safe.
digesting flow (from original password to digest): random salt byte array of length 8 -> byte array of (salt + sha1(salt, password)) -> base64Encode
verification user input password with stored digest: base64Decode -> extract salt -> do sha1(salt, password) -> generate digest: salt + sha1 -> compare the generated digest with the stored digest.
Util to verify whether user input password is valid or not.
Util to verify whether user input password is valid or not. It use sha1 to do the digesting.
Authenticator for UI dashboard.
Sub Class must implement a constructor with signature like this: this(config: Config)


|
GrimEngine
|
Handles input bindings. More...
#include <InputManager.hpp>
Public Member Functions | |
| InputManager () | |
| Default constructor. | |
| ~InputManager () | |
| Default destructor. | |
| void | bind (std::string name, sf::Keyboard::Key key, std::function< void(void)> action) |
| Binds a key to an action and is accessed by a given name. More... | |
| bool | unbind (std::string name) |
| Unbinds a certain action from its action. More... | |
| void | processEvents () |
| Checks to see if any binding key has been pressed and performs the related action. | |
Handles input bindings.
The InputManager class handles mapping keys to specific actions in the game. It makes it simple to add custom key bindings for actions in-game.
| void InputManager::bind | ( | std::string | name, |
| sf::Keyboard::Key | key, | ||
| std::function< void(void)> | action | ||
| ) |
Binds a key to an action and is accessed by a given name.
| name | Specifier for the binding |
| key | Key to be bound |
| action | Callback function to be executed when bound key is pressed |
| bool InputManager::unbind | ( | std::string | name | ) |
Unbinds a certain action from its action.
| name | Binding name to be unbound |


Simple Login
Username
Password
Login
Sign up!
Lost Password?
arrow_back
Sign up
Username
Password
Password repeat
Sign up


Hello, and welcome to the Turnip Prophet app on your Nook Phone.
This app lets you track your island's turnip prices daily, but you'll have to put the prices in yourself!
After that, the Turnip Prophet app will magically predict the turnip prices you'll have for the rest of the week.
| Pattern | % Chance | Sunday |
Monday
|
Tuesday
|
Wednesday
|
Thursday
|
Friday
|
Saturday
|
Guaranteed Minimum | Potential Maximum |
|---|
After you've listed some turnip prices, the Turnip Prophet will run some numbers and display the different possible patterns that your island may experience.
This app is still in development, but will improve over time!
None of this would have been possible without Ninji's work figuring out just how Timmy and Tommy value their turnips.
Support, comments and contributions are available through Github
Oh! And let's not forget to thank those who have contributed so far!
Contributors:


GPA: 3.68
As a student I like to handle information and manipulate data in systems. Since April 2019, I have been a full stack student web developer at UCI's Office of Information and Technology. Through this job I have learned what it is like to be on an agile development team. I have participated in sprint planning meetings, daily stand-up meetings, and sprint retrospective meetings.
Apart from being a student and developer, I like to spend time playing basketball with friends or working out together. When I'm at home I like to watch several shows as well as play different video games.


Returns a feature column that represents sequences of numeric data.
tf.compat.v1.feature_column.sequence_numeric_column
tf.compat.v2.feature_column.sequence_numeric_column
tf.feature_column.sequence_numeric_column( key, shape=(1,), default_value=0.0, dtype=tf.dtypes.float32, normalizer_fn=None )
temperature = sequence_numeric_column('temperature') columns = [temperature] features = tf.io.parse_example(..., features=make_parse_example_spec(columns)) sequence_feature_layer = SequenceFeatures(columns) sequence_input, sequence_length = sequence_feature_layer(features) sequence_length_mask = tf.sequence_mask(sequence_length) rnn_cell = tf.keras.layers.SimpleRNNCell(hidden_size) rnn_layer = tf.keras.layers.RNN(rnn_cell) outputs, state = rnn_layer(sequence_input, mask=sequence_length_mask)
key
: A unique string identifying the input features.shape
: The shape of the input data per sequence id. E.g. if shape=(2,)
,
each example must contain 2 * sequence_length
values.default_value
: A single value compatible with dtype
that is used for
padding the sparse data into a dense Tensor
.dtype
: The type of values.normalizer_fn
: If not None
, a function that can be used to normalize the
value of the tensor after default_value
is applied for parsing.
Normalizer function takes the input Tensor
as its argument, and returns
the output Tensor
. (e.g. lambda x: (x - 3.0) / 4.2). Please note that
even though the most common use case of this function is normalization, it
can be used for any kind of Tensorflow transformations.A SequenceNumericColumn
.
TypeError
: if any dimension in shape is not an int.ValueError
: if any dimension in shape is not a positive integer.ValueError
: if dtype
is not convertible to tf.float32
.


Toggle navigation
Pi Camera
Home
About
Contact
Dropdown
Action
Another action
Something else here
Nav header
Separated link
One more separated link
DATE


|
CQRS - Command Query Responsibility Segregation
This architecture is only useful if your application process huge amounts of data. Further, the views that present the data to the user are complex and cannot be generated real-time. In this architecture reading and writing information is separated into two separate models. Examples
Where does it come from?CQRS was created by Greg Young. When should you use it?
How does it work?A CQRS system separates a Command Model from a Query Model. Whenever the system executes an action, an Action object is created and this is stored in the command model. A signal is then sent to the Query Model and all models that depend on this command are updated, asynchronously. Data entering the system is written only to the Command Model. When an application needs to show data, it is read from the Query model. The Query Models are "throw away" and may be recreated from the Command Model. However, it may take (considerable) time to recreate the Query Models. Problems
Common implementation techniques
Links |


Control
One of my triggers is not knowing where to begin when reading a code task. If I have no idea where to begin this usually sets me off. I feel this does this because I already feel like I am a bit behind where I need to be, so when I have no idea where to begin I think back to how I feel I need to know more. If I just settled down and looked into what needed to be done a bit more I would find that the solution is far away if I just have a good mindset.
The Seberian North Railroad Exercise (stop, breathe, notice, reflect, respond) was pretty good and makes a lot of sense. It forces you not to act and to calmly think about what is going on. By slowing down the fast paced trigger when the room feels like it's spinning or you are out of control in a tunnel going 150km/ph, it brings you back to reality where you can make decisions with a clear unclouded mindstate.


Welcome to our Music Trivia
Would like to change user?
Let's see what you do really know?
Submit
Question
of
Your Score:
out of
Retake the quiz!
Contribute to questions set!
Add a Question:
or Reset the Quiz list!
Correct Answer:
Choice A
Choice B
Choice C
Choice D
Submit Question
Take the quiz!


---
layout: post
title: 1/26
date: '2013-01-26T21:29:00.000-07:00'
author: Jacob .
tags:
modified_time: '2013-01-26T22:04:45.456-07:00'
blogger_id: tag:blogger.com,1999:blog-6400085873105072120.post-2069922460601021117
blogger_orig_url: http://www.svlark.com/2013/01/126.html
---
Len just came into town, so now we'll get some stuff done!
I spent some time researching FSBO stuff this evening.
Big step today, as recommended by the Live on the Margin guys -- we ditched our TV bill...
-33.6 @ 237.6


Follow
Link
About
The Rubin Way
Personal thoughts on software & technology & UI
{{ content }}
{% include google_analytics.html %}


Doctor Finder
Use the typeaheads to find a doctor in your area
Action
Another action
Something else here
Separated link
Portland
San Francisco
Seattle
Chicago
New York
Search


BALD heads forgetful of their sins,
Old, learned, respectable bald heads
Edit and annotate the lines
That young men, tossing on their beds,
Rhymed out in love’s despair
To flatter beauty’s ignorant ear.
They’ll cough in the ink to the world’s end;
Wear out the carpet with their shoes
Earning respect; have no strange friend;
If they have sinned nobody knows.
Lord, what would they say
Should their Catullus walk that way?
- W.B. Yeats, 1919


LambertW: Probabilistic Models to Analyze and Gaussianize Heavy-Tailed,
Skewed Data
Lambert W x F distributions are a generalized framework to analyze
skewed, heavy-tailed data. It is based on an input/output system, where the
output random variable (RV) Y is a non-linearly transformed version of an input
RV X ~ F with similar properties as X, but slightly skewed (heavy-tailed).
The transformed RV Y has a Lambert W x F distribution. This package contains
functions to model and analyze skewed, heavy-tailed data the Lambert Way:
simulate random samples, estimate parameters, compute quantiles, and plot/
print results nicely. Probably the most important function is 'Gaussianize',
which works similarly to 'scale', but actually makes the data Gaussian.
A do-it-yourself toolkit allows users to define their own Lambert W x
'MyFavoriteDistribution' and use it in their analysis right away.
| Version: |
0.6.4 |
| Depends: |
MASS, ggplot2 |
| Imports: |
lamW (≥ 1.0.0), stats, graphics, grDevices, RColorBrewer, reshape2, Rcpp |
| LinkingTo: |
Rcpp, lamW |
| Suggests: |
boot, Rsolnp, nortest, numDeriv, testthat, moments |
| Published: |
2016-03-29 |
| Author: |
Georg M. Goerg |
| Maintainer: |
Georg M. Goerg <im at gmge.org> |
| License: |
GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| URL: |
http://www.gmge.org http://arxiv.org/abs/0912.4554
http://arxiv.org/abs/1010.2265 http://arxiv.org/abs/1602.02200 |
| NeedsCompilation: |
yes |
| Citation: |
LambertW citation info |
| Materials: |
NEWS |
| In views: |
Distributions |
| CRAN checks: |
LambertW results |
Downloads:
Reverse dependencies:
Linking:
Please use the canonical form
https://CRAN.R-project.org/package=LambertW
to link to this page.


ID
State
Created
Last Updated
Resources Used
Recommendation
Value
Reason
Recovery Suggestion
Breakdown
Sub Check
Result
Details
Generated Media
ID
Type


Class CustomOleDbCommandBuilder
Custom Command builder for OleDB to avoid primary key problems with builtin ones derived (transposed into VB.NET) from https://www.cogin.com/articles/CustomCommandBuilder.php Copyright by Dejan Grujic 2004. http://www.cogin.com
Namespace: DBaddin
Assembly: DBaddin.dll
Syntax
public class CustomOleDbCommandBuilder : CustomCommandBuilder
Constructors
| Improve this Doc View SourceCustomOleDbCommandBuilder(DataTable, OleDbConnection, DataColumn[], Collection)
Declaration
public CustomOleDbCommandBuilder(DataTable dataTable, OleDbConnection connection, DataColumn[] allColumns, Collection schemaDataTypeCollection)
Parameters
| Name | Description |
|---|---|
| dataTable | |
| connection | |
| allColumns | |
| schemaDataTypeCollection |
Methods
| Improve this Doc View SourceDeleteCommand()
Creates Delete command
Declaration
public override DbCommand DeleteCommand()
Returns
| Description |
|---|
OleDbCommand for deleting |
Overrides
| Improve this Doc View SourceInsertCommand()
Creates Insert command with support for Autoincrement (Identity) fields
Declaration
public override DbCommand InsertCommand()
Returns
| Description |
|---|
OleDbCommand for inserting |
Overrides
| Improve this Doc View SourceUpdateCommand()
Creates Update command
Declaration
public override DbCommand UpdateCommand()
Returns
| Description |
|---|
OleDbCommand for updating |


The Passsion Within
This wonderful collection of heartfelt, passionate poetry and short story book excerpts describe the feelings, life struggles and triumphs of the urban man and woman.
This work includes tributes to loved ones, release and struggling through life pressures, religion, racial injustice, and of course - last but not least, the ultimate passion between lovers, among others.
Some features that made us unique
We strive to offer book enthusiasts the best possible buying experience
2354
Happy Customers
6784
Cups Coffe
2567
Tickets Submited
2567
collection Books
Download our app dor all plataforms
Each purchased book makes a difference in someone's life
Desktop
On website
Mobile
On play store
What our reader's say about us...
Jhon Smith
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint iure autem recusandae, veniam, illo dolor soluta assumenda minima quia velit officia sit exercitationem nam ipsa, repellendus aut facilis quasi voluptas!
Ana Rodriguez
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint iure autem recusandae, veniam, illo dolor soluta assumenda minima quia velit officia sit exercitationem nam ipsa, repellendus aut facilis quasi voluptas!


Hawaii begins using new asphalt that could extend road life | Honolulu Star-Advertiser
The Hawaii Department of Transportation plans to use a new type of asphalt that could extend road life by years, officials said.
Stone matrix asphalt may reduce the need for filling potholes, fixing cracks and performing other types of regular road maintenance, KHON-TV reported.
The stronger and more flexible compound could last up to 25 years, officials said.
“Overall way better product that we’ve gotten for the public at a cost of about 1.6 to two times the cost of materials,” said Ed Sniffen, the state Deputy Director of Highways.
A repaving project on Oahu’s Pali Highway added a layer of stone matrix asphalt on top of standard asphalt to make the road smoother and more durable, officials said.
Transportation officials plan to expand use of the asphalt hybrid to various major road arteries.
“We’re already looking toward the next corridors we can do it on,” Sniffen said, noting that the Nimitz Highway, part of Route 92 on Oahu, is scheduled for reconstruction and resurfacing.
The department first experimented with the pavement on a 5-mile stretch of the Moanalua Freeway in 2004. It has held up very well, Sniffen said.
“That area is super smooth, doesn’t have any cracks in it, and we’ve not touched it or done anything on it for the last 15 years,” Sniffen said. “So we know it works, something that can give us life.”
Sniffen cautioned drivers that a smooth ride can lead to a false sense of security. “If things are smoother, you don’t notice the speeds that you’re driving,” he said.


‘Cats’ Movie Trailer Teases a Bizarre Feline Show
by Genevieve ScaranoA new trailer just dropped for the upcoming Cats film and it teases a strange, yet alluring storyline about a group of passionate felines.
The movie’s star-studded cast, including Idris Elba, Jennifer Hudson, and Taylor Swift, has received a “digital fur” makeover, thanks to some CGI tech. Even though the animation is a tad creepy, the movie looks like a lot of fun with dancing, singing, and glittery catnip.
“Tonight is a magical night…where I chose the cat that deserves a new life,” Judi Dench, who plays Old Deuteronomy, tells all her fellow kitties.
One cat will be “reborn” in the group, and of course, there is A LOT of competition.
Contenders include felines who like to eat, cause trouble, and hide in the shadows. And sadly, not all tabbies are welcome to the celebration: Grizabella (Hudson), who is slightly older than her other peers, is turned away multiple times, however, she’s still determined to win.
Who will be the king or queen of the Jellicles tribe?
Cats arrives in theaters on Dec. 20.
More on Geek.com:


{% extends "layout.html" %} {% load crispy_forms_tags %} {% block title %} Create Organization {% endblock %} {% block content %}
An organization allows you to group related projects together under one name.
To get started, just enter a name for your organization below - they have to follow the same rules as usernames, and they can't already be taken.
{% crispy form %}


Howto migrate a real-life batch pipeline from the DataSet API to the DataStream API
May 9, 2023 - Etienne Chauchot (@echauchot)Introduction #
The Flink community has been deprecating the DataSet API since version 1.12 as part of the work on FLIP-131: Consolidate the user-facing Dataflow SDKs/APIs (and deprecate the DataSet API) . This blog article illustrates the migration of a real-life batch DataSet pipeline to a batch DataStream pipeline. All the code presented in this article is available in the tpcds-benchmark-flink repo. The use case shown here is extracted from a broader work comparing Flink performances of different APIs by implementing TPCDS queries using these APIs.
What is TPCDS? #
TPC-DS is a decision support benchmark that models several generally applicable aspects of a decision support system. The purpose of TPCDS benchmarks is to provide relevant, objective performance data of Big Data engines to industry users.
Chosen TPCDS query #
The chosen query for this article is Query3 because it contains all the more common analytics operators (filter, join, aggregation, group by, order by, limit). It represents an analytic query on store sales. Its SQL code is presented here:
SELECT dt.d_year, item.i_brand_id brand_id, item.i_brand brand,SUM(ss_ext_sales_price) sum_agg FROM date_dim dt, store_sales, item WHERE dt.d_date_sk = store_sales.ss_sold_date_sk AND store_sales.ss_item_sk = item.i_item_sk AND item.i_manufact_id = 128 AND dt.d_moy=11 GROUP BY dt.d_year, item.i_brand, item.i_brand_id ORDER BY dt.d_year, sum_agg desc, brand_id LIMIT 100
The initial DataSet pipeline #
The pipeline we are migrating is this batch pipeline that implements the above query using the DataSet API and Row as dataset element type.
Migrating the DataSet pipeline to a DataStream pipeline #
Instead of going through all of the code which is available here we will rather focus on some key areas of the migration. The code is based on the latest release of Flink at the time this article was written: version 1.16.0.
DataStream is a unified API that allows to run pipelines in both batch and streaming modes. To execute a DataStream pipeline in batch mode, it is not enough to set the execution mode in the Flink execution environment, it is also needed to migrate some operations. Indeed, the DataStream API semantics are the ones of a streaming pipeline. The arriving data is thus considered infinite. So, compared to the DataSet API which operates on finite data, there are adaptations to be made on some operations.
Setting the execution environment #
We start by moving from ExecutionEnvironment to StreamExecutionEnvironment . Then, as the source in this pipeline is bounded, we can use either the default streaming execution mode or the batch mode. In batch mode the tasks of the job can be separated into stages that can be executed one after another. In streaming mode all tasks need to be running all the time and records are sent to downstream tasks as soon as they are available.
Here we keep the default streaming mode that gives good performance on this pipeline and that would allow to run the same pipeline with no change on an unbounded source.
Using the streaming sources and datasets #
Sources: DataSource
Datasets: DataSet
Migrating the join operation #
The DataStream join operator does not yet support aggregations in batch mode ( see FLINK-22587 for details). Basically, the problem is with the trigger of the default GlobalWindow which never fires so the records are never output. We will workaround this problem by applying a custom EndOfStream window. It is a window assigner that assigns all the records to a single TimeWindow . So, like for the GlobalWindow, all the records are assigned to the same window except that this window’s trigger is based on the end of the window (which is set to Long.MAX_VALUE). As we are on a bounded source, at some point the watermark will advance to +INFINITY (Long.MAX_VALUE) and will thus cross the end of the time window and consequently fire the trigger and output the records.
Now that we have a working triggering, we need to call a standard join with the Row::join function.
Migrating the group by and reduce (sum) operations #
DataStream API has no more groupBy() method, we now use the keyBy() method. An aggregation downstream will be applied on elements with the same key exactly as a GroupReduceFunction would have done on a DataSet except it will not need to materialize the collection of data. Indeed, the following operator is a reducer: the summing operation downstream is still done through a ReduceFunction but this time the operator reduces the elements incrementally instead of receiving the rows as a Collection. To make the sum we store in the reduced row the partially aggregated sum. Due to incremental reduce, we also need to distinguish if we received an already reduced row (in that case, we read the partially aggregated sum) or a fresh row (in that case we just read the corresponding price field). Also, please note that, as in the join case, we need to specify windowing for the aggregation.
Migrating the order by operation #
The sort of the datastream is done by applying a KeyedProcessFunction .
But, as said above, the DataStream semantics are the ones of a streaming pipeline. The arriving data is thus considered infinite. As such we need to “divide” the data to have output times. For that we need to set a timer to output the resulting data. We set a timer to fire at the end of the EndOfStream window meaning that the timer will fire at the end of the batch.
To sort the data, we store the incoming rows inside a ListState and sort them at output time, when the timer fires in the onTimer() callback.
Another thing: to be able to use Flink state, we need to key the datastream beforehand, even if there is no group by key because Flink state is designed per-key. Thus, we key by a fake static key so that there is a single state.
Migrating the limit operation #
As all the elements of the DataStream were keyed by the same “0” key, they are kept in the same " group". So we can implement the SQL LIMIT with a ProcessFunction with a counter that will output only the first 100 elements.
Migrating the sink operation #
As with sources, there were big changes in sinks with recent versions of Flink. We now use the Sink interface that requires an Encoder . But the resulting code is very similar to the one using the DataSet API. It’s only that Encoder#encode() method writes bytes when TextOutputFormat.TextFormatter#format() wrote Strings.
Conclusion #
As you saw for the migration of the join operation, the new unified DataStream API has some limitations left in batch mode. In addition, the order by and limit resulting code is quite manual and requires the help of the Flink state API for the migration. For all these reasons, the Flink community recommends to use Flink SQL for batch pipelines. It results in much simpler code, good performance and out-of-the-box analytics capabilities. You could find the equivalent Query3 code that uses the Flink SQL/Table API in the Query3ViaFlinkSQLCSV class .


<EMAIL_ADDRESS>Projects
Home
Vampire Sweeper
Maori Proverbs
JavaScript Calculator
Colorful Sound
Christmas Card
Have a look at some of the porjects I've been able to create They are surely to improve with time.


--- layout: post title: "Dynamic test oracles for rho problems" description: "A proof of concept of cross-branch testing for compiled languages." date: 2021-01-04 6:26 UTC tags: [Languages, F#, Unit Testing] --- {% include JB/setup %}
{{ page.description }}
Hillel Wayne recently published an article called Cross-Branch Testing. It outlines an approach to a class of problems that are hard to test. He mentions computer vision and simulations, among others. I can add that it's also difficult to write intuitive tests of convex hulls and Conway's game of life.
Hillel Wayne calls these rho problems, 'just because'. I'm totally going to run with that term.
In the article, he outlines an approach where you test an iteration of rho code against a 'last known good' snapshot. He uses git worktree
to set up a snapshot of the reference implementation. He then writes a property that compares the refactored code's behaviour against the reference.
The example code is in Python, which is a language that I don't know. As far as I can tell, it works because Python is 'lightweight' enough that you can load and execute source code directly. I found that the approach makes much sense, but I wondered how it would apply for statically typed, compiled languages. I decided to create a proof of concept in F#.
My first problem was to port Hillel Wayne's example rho problem to F#. The function f
doesn't have any immediate mathematical properties; nor is its behaviour intuitive. While I think that I understand what each line of code in f
means, I don't really know Python. Since one of the properties of rho problems is that bugs can be subtle, I didn't trust myself to be able to port the Python code to F# without some test cases.
To solve that problem, I first found an online Python interpreter and pasted the f
function into it. I then wrote code to print the output of a function call:
print(f'1, 2, 3, { f(1, 2, 3) }')
This line of code produces this output:
1, 2, 3, True
In other words, I could produce comma-separated values of input and actual output.
Hillel Wayne wrote properties using Hypothesis, which, it seems, by default runs each property 200 times.
In F# I'm going to use FsCheck, so I first used F# Interactive with FsCheck to produce 200 Python print
statements like the above:
> Arb.Default.Int32().Generator |> Gen.three |> Gen.map (fun (x, y, z) -> sprintf "print(f'%i, %i, %i, { f(%i, %i, %i) }')" x y z x y z) |> Gen.sample 100 200 |> List.iter (printfn "%s");; print(f'-77, 67, 84, { f(-77, 67, 84) }') print(f'58, -46, 3, { f(58, -46, 3) }') print(f'21, 13, 94, { f(21, 13, 94) }') ...
This is a throwaway data pipeline that starts with an FsCheck integer generator, creates a triple from it, turns that triple into a Python print
statement, and finally writes 200 of those to the console. The above code listing only shows the first three lines of output, while the rest are indicated by an ellipsis.
I copied those 200 print
statements over to the online Python interpreter and ran the code. That produced 200 comma-separated values like these:
-77, 67, 84, False 58, -46, 3, False 21, 13, 94, True ...
These can serve as test cases for porting the Python code to F#.
The next step is to write a parametrised test, using a provisional implementation of f
:
[<Theory; MemberData(nameof fTestCases)>]
let ``test f`` x y z expected = expected =! f x y z
This test uses xUnit.net 2.4.1 and Unquote 5.0.0. As you can tell, apart from the annotations, it's a true one-liner. It calls the f
function with the three supplied arguments x
, y
, and z
and compares the return value with the expected
value.
The code uses the new nameof feature of F# 5. fTestCases
is a function in the same module that holds the test:
// unit -> seq<obj []> let fTestCases () = use strm = typeof<Anchor>.Assembly.GetManifestResourceStream streamName use rdr = new StreamReader (strm) let s = rdr.ReadToEnd () s.Split Environment.NewLine |> Seq.map csvToTestCase
It reads an embedded resource stream of test cases, like the above comma-separated values. Even though the values are in a text file, it's easier to embed the file in the test assembly, because it nicely dispenses with the problem of copying a text file to the appropriate output directory when the code compiles. That would, however, be an valid alternative.
Anchor
is a dummy type to support typeof
, and streamName
is just a string constant that identifies the name of the stream.
The csvToTestCase
function converts each line of comma-separated values to test cases for the [<Theory>]
attribute:
// string -> obj [] let csvToTestCase (csv : string) = let values = csv.Split ',' [| values.[0] |> Convert.ToInt32 |> box values.[1] |> Convert.ToInt32 |> box values.[2] |> Convert.ToInt32 |> box values.[3] |> Convert.ToBoolean |> box |]
It's not the safest code I could write, but this is, after all, a proof of concept.
The most direct port of the Python code I could produce is this:
// f : int -> int -> int -> bool let f (x : int) (y : int) (z : int) = let mutable mx = bigint x let mutable my = bigint y let mutable mz = bigint z let mutable out = 0I for i in [0I..9I] do out <- out * mx + abs (my * mz - i * i) let x' = mx let y' = my let z' = mz mx <- y' + 1I my <- z' mz <- x' abs out % 100I < 10I
As F# code goes, it's disagreeable, but it passes all 200 test cases, so this will serve as an initial implementation. The out
variable can grow to values that overflow even 64-bit integers, so I had to convert to bigint to get all test cases to pass.
If I make the same mutation to the code that Hillel Wayne did (abs out % 100I < 9I
) two test cases fail. This gives me some confidence that I have a degree of problem coverage comparable to his.
Now that a reference implementation exists, we can use it as a test oracle for refactorings. You can, for example, add a little test-only utility to your program portfolio:
open Prod open FsCheck [<EntryPoint>] let main argv = Arb.Default.Int32().Generator |> Gen.three |> Gen.sample 100 200 |> List.iter (fun (x, y, z) -> printfn "%i, %i, %i, %b" x y z (f x y z)) 0 // return an integer exit code
Notice that the last step in the pipeline is to output the values of each x
, y
, and z
, as well as the result of calling f x y z
.
This is a command-line executable that uses FsCheck to produce new test cases by calling the f
function. It looks similar to the above one-off script that produced Python code, but this one instead just produces comma-separated values. You can run it from the command line to produce a new sample of test cases:
$ ./foracle 29, -48, -78, false -8, -25, 13, false -74, 34, -68, true ...
As above, I've used an ellipsis to indicate that in reality, 200 lines of comma-separated values scroll by.
When you use Bash, you can even pipe the output straight to a file:
$ ./foracle > csv.txt
You can now take the new comma-separated values and update the test values that the above test f
test uses.
In other words, you use version n of f
as a test oracle for version n + 1. When iteration n + 1 is a function of iteration n, you have a so-called dynamic system, so I think that we can call this technique dynamic test oracles.
The above foracle
program is just a proof of concept. You could make it more flexible by making it take command-line arguments that would let you control the sample size and FsCheck's size
parameter (the hard-coded 100
in the above code listing).
With the confidence instilled by the test cases, we can now refactor the f
function:
// f : int -> int -> int -> bool let f (x : int) (y : int) (z : int) = let imp (x, y, z, out) i = let out = out * x + abs (y * z - i * i) y + 1I, z, x, out let (_, _, _, out) = List.fold imp (bigint x, bigint y, bigint z, 0I) [0I..9I] abs out % 100I < 10I
Instead of all those mutable variables, the function is, after all, just a left fold. Phew, I feel better now.
This article demonstrated a proof of concept where you use a known good version (n) of the code as a test oracle for the next version (n + 1). In interpreted languages, you may be able to load two versions of the code base side by side, but that's rarely practical in a statically typed compiled language like F#. Instead, I used a utility program to generate test cases that can be used as a data source for a parametrised test.
The example rho problem takes only integers as input, and returns a simple Boolean value, so in this case it's trivial to encode each test case as a line of comma-separated values. For (real) problems that may involve more complex types, it'd be better to use another serialisation format, such as JSON or XML.
An outstanding issue is whether it's possible to implement shrinking behaviour when tests fail. Currently, the proof of concept just uses a set of serialised test cases. Normally, when a property-based testing framework like FsCheck detects a counter-example, it'll shrink the counter-example to values that are easier to understand than the original. This proof of concept doesn't do that. I'm not sure if a framework like FsCheck currently contains enough extensibility points to enable that sort of behaviour. I'll leave that question open for any reader interested in taking on that problem.
Comments
Hi Mark! Thanks for another thought provoking post.
I believe you and Hillel are writing characterization tests, which you've mentioned in the past. Namely, you're both using the behavior of existing code to verify the correctness of a refactor. The novel part to me is that Hillel is using code as the test oracle. Your solution serializes the oracle to a static file. The library I use for characterization tests (ApprovalTests) does this as well.
I believe shrinking is impossible when the oracle is a static file. However with Hillel's solution the oracle may be consulted at any time, making shrinking viable. If only there was a practical way to combine the two...
A thought provoking post indeed!
I think that is a fine choice given the use case laid out in this post. In general though, I think Hedgehog is a better property-based testing library. Its killer feature is integrated shrinking, which means that all generators can also shrink and this extra power is essentially free.
For the record (because this can be a point of confusion), Haskell has QuickCheck and (Haskell) Hedgehog while F# has ports from Haskell called FsCheck and (FSharp) Hedgehog.
Jacob Stanley gave this excellent talk at YOW! Lambda Jam 2017 that explains the key idea that allows Hedgehog to have integrated shrinking. (Spoiler: A generic type that is invariant in its only type parameter is replaced by a different generic type that is monadic in its only type parameter. API design guided by functional programming for the win!)
In my experience, property-based tests written with QuickCheck / FsCheck do not normally shrink. I think this is because of the extra work required to enable shrinking. For an anecdotal example, consider this post by Fraser Tweedale. He believed that it would be faster to add (Haskell) Hedgehog as a dependency and create a generator for it than to add shrinking to his existing generator in QuickCheck.
I am confused by this paragraph. I interpret your word "When" at the start of the second sentence as a common-language synonym for the mathematical word "If". Here is roughly how I understand that paragraph, where
A
stands for "version / iteration n off
" andB
stands for "version / iteration n + 1 off
". "A
depends onB
. IfB
depends onA
, then we have a dynamic system. Therefore, we have a dynamic system." I feel like the paragraph assumes (because it is obvious?) that version / iteration n + 1 off
depends on version / iteration n off
. In what sense is that the case?I am interested!
Quoting Mark and then Alex.
I want to start by elaborating on this to make sure we are all on the same page. I think of shrinking as involving two parts. On the one hand, we have the "shrink tree", which contains the values to test during the shrinking process. On the other hand, for each input tested, we need to know if the output should cause the test to pass or fail.
With Hedgehog, getting a shrink tree would not be too difficult. For a generator with type parameter
'a
, the current generator API returns a "random" shrink tree of type'a
in which the root is an instancea
of the type'a
and the tree completely depends ona
. It should be easy to expose an additional function that accepts inputs of type'a Gen
and'a
and returns the tree with the given'a
as its root.The difficult part is being able to query the test oracle. As Mark said, this seems easy to do in a dynamically-typed language like Python. In contrast, the fundamental issue with a statically-typed language like F# is that the compiled code exists in an assembly and only one assembly of a given name can be loaded in a given process at the same time.
This leads me to two ideas for workarounds. First, we could query the test oracle in a different process. I imagine an entry point could be generated that gives direct access to the test oracle. Then the test process could query the test oracle by executing this generated process. Second, we could generate a different assembly that exposes the test oracle. Then the test process could load this generated assembly to query the test oracle. The second approach seems like it would have a faster query time but be harder to implement. The first approach seems easier to implement but would probably have a slower query time. Maybe the query time would be fast enough though, especially if it was only queried when shrinking.
But given such a solution, who wants to restrict access to the test oracle only to shrinking? If the test oracle is always available, then there is no need to store input-output pairs. Instead of always checking that the system under test works correctly for a previously selected set of inputs, the property-based test can check that the system under test has the expected behavior for a unique set of inputs each time the property-based test is executed. In my experience, this is the default behavior of a property-based test.
One concern that some people might have is the idea of checking into the code repository the binary containing the test oracle. My first though is that the size of this is likely so small that it does not matter. My second thought is that the binary containing the test oracle does not have to be included in the repository. Instead, the workflow could be to (1) create the property-based test that uses the compiled test oracle, (2) refactor the system under test, (3) observe that the property-based test still passes, (4) commit the refactored code, and (5) discard the remaining changes, which will delete the property-based test and the compiled test oracle.
Instead of completely removing that property-based test, it might be better to leave it there with input-output pairs stored in a file. Then the conversion from that state of the property-based test to the one that uses the compiled test oracle will be much smaller.
Alex, thank you for writing. Yes, I think that calling this a Characterisation Test is correct. I wasn't aware of the ApprovalTests library; thank you for mentioning it.
When I originally wrote the article, I was under the impression that shrinking might still be possible. I admit, though, that I hadn't thought things through. I think that Tyson Williams argues convincingly that this isn't possible.
Tyson, thank you for writing. I'm well aware of Hedgehog, and I'm keen on the way it works. I rarely use it, however, as it so far doesn't quite seem to have the same degree of 'industrial strength' to it that FsCheck has. Additionally, I find that shrinking is less important in practice than it might seem in theory.
I'm not sure that I understand your confusion about the term dynamic. You write:
Why do you write that? I don't think, in the way you've labelled iterations, thatA
depends onB
.When it comes to shrinking, I think that you convincingly argues that it can't be done unless one is able to query the oracle. As long as all you have is a list of test cases, you can't do that... unless, perhaps, you were to also generate and run all the shrunk test cases when you capture the list of test cases... Again, I haven't thought this through, so there may be some obvious gotcha that I'm missing.
I would be wary of trying to host the previous iteration in a different process. This is technically possible, but, in .NET at least, quite cumbersome. You'll have to deal with data marshalling and lifetime management of the second process. It was difficult enough in .NET framework back when remoting was a thing; I'm not even sure how one would go about such a problem in .NET Core - particularly if you want it to work on both Windows, Linux, and Mac. HTTP?
That seems reasonable. I haven't used FsCheck, so I wouldn't know myself. Several of us are making many great improvements to F# Hedgehog right now.
That would be too many test cases. The shrinking process finds two values
n
andn+1
such that the test passes forn
and fails forn+1
. This can be viewed as a constraint. The objective is to minimize the value ofn
. The only way to ensure that some value is the minimum is to test all values smaller than it. However, doing so is not practical. Property-based tests uses randomness precisely because it is not practical to test every possible value.Instead, the shrinking process uses binary search as a heuristic to find a value satisfying the constraint that is rather small but not necessarily the smallest.
Ok. I will go slower and ask smaller questions.
Does this phrase have the same meaning if "When" is replaced by "If"?
I understand how version n of
f
is being used as a test oracle for version n + 1. In this blog post, in what sense is something of iteration n + 1 is a function of iteration n?Tyson, thank you for writing.
I'm not sure that there's a big difference, but then, I don't know how you parse that. As Kevlin Henney puts it, It seems to me that you're attempting to parse my prose as though it was an unambiguous description, which it can't be.A dynamic system is a system such that
xt+1 = f(xt)
, wherext
is the value ofx
at timet
, andxt+1
is the value ofx
at timet+1
. For simplicity, this is the definition of a dynamic system in discrete time. Mathematically, you can also express it in continuous time using calculus.Oh, yes. My mistake. I meant to phrase in slightly differently thereby changing it from essentially an impossible question to one that only you can answer. Here is what I meant to ask.
No matter though. I simply misunderstood your description / defintion of a dynamical system. I understand now. Thanks for your patience and willingness to explain it to me again.


--- layout: post title: The Sultans Elephant date: 2006-05-03 00:00:00 category: personal ---
I got handed a flier for this whilst in London today; it looks interesting:
"The Sultan’s Elephant is a spectacle you’ve only imagined... Created by theatrical magicians Royal de Luxe, it tells the story of a sultan from far-off lands and his magical, time-travelling mechanical elephant. Forty feet high and 42 tonnes in weight, this beautiful creature will capture the hearts and minds of everyone who sees it.
The Sultan’s Elephant is played out over four days in the streets, squares and public spaces of central London. Whether you dip into it for three hours or follow its progress for three days, this breathtaking show will live in your memory forever."


21A Bathurst ST,Toronto,
Toronto, ON M5V OP2
Canada
Order & Plant Support
<EMAIL_ADDRESS>Partnership & Collaboration
<EMAIL_ADDRESS>Monday - Friday:
10:00 am - 6:00 pm


Namespace Unity.Lifetime
Classes
ContainerControlledLifetimeManager
Unity returns the same instance each time the Resolve(...) method is called or when the dependency mechanism injects the instance into other classes.
ContainerControlledTransientManager
A special lifetime manager which works like TransientLifetimeManager, except container remembers all Disposable objects it created. Once container is disposed all these objects are disposed as well.
ExternallyControlledLifetimeManager
A LifetimeManager that holds a weak reference to it's managed instance.
HierarchicalLifetimeManager
A special lifetime manager which works like ContainerControlledLifetimeManager, except that in the presence of child containers, each child gets it's own instance of the object, instead of sharing one in the common parent.
LifetimeManager
Base class for all lifetime managers - classes that control how and when instances are created by the Unity container.
LifetimeManager.InvalidValue
PerResolveLifetimeManager
This is a custom lifetime manager that acts like TransientLifetimeManager, but also provides a signal to the default build plan, marking the type so that instances are reused across the build up object graph.
PerThreadLifetimeManager
A LifetimeManager that creates a new instance of the registered Type once per each thread.
SingletonLifetimeManager
Singleton lifetime creates globally unique singleton. Any Unity container tree (parent and all the children) is guaranteed to have only one global singleton for the registered type.
SynchronizedLifetimeManager
Base class for Lifetime managers which need to synchronize calls to GetValue(ILifetimeContainer).
TransientLifetimeManager
An LifetimeManager implementation that does nothing, thus ensuring that instances are created new every time.
Interfaces
IFactoryLifetimeManager
This interface marks all lifetime managers compatible with RegisterFactory(Type, String, Func<IUnityContainer, Type, String, Object>, IFactoryLifetimeManager) registration.
IInstanceLifetimeManager
This interface marks all lifetime managers compatible with RegisterInstance(Type, String, Object, IInstanceLifetimeManager) registration.
ILifetimeContainer
Represents a lifetime container.
ITypeLifetimeManager
This interface marks all lifetime managers compatible with RegisterType(Type, Type, String, ITypeLifetimeManager, InjectionMember[]) registration.


Order some Pizza
Items
Add and see your Total
Create Your Pizza
Small
Medium
Large
Pick your Toppings
None
Chicken
Pepperoni
Steak
How many?


#include <correlation_results.h>
Public Member Functions | |
| CorrelationResults () | |
| CorrelationResults (const GlobalVariables &kGlobalVariables, const PlateNeighbours &kPlateNeighbours) | |
| std::string | correlation_file_name () const |
| PlatesMapSimple < CorrelationPlate >::map | correlation_plates () const |
| CorrelationPlate | correlation_plates (int plate_num) const |
| CorrelationPlate | normalized_correlation () const |
| size_t | num_bins () const |
| size_t | num_pi_bins () const |
| size_t | num_sigma_bins () const |
| std::string | pairs_file_name () const |
| std::vector< int > | plates_list () const |
| int | plates_list (int index) const |
| std::string | results () const |
| void | ComputeCrossCorrelation (const AstroObjectDataset &object_list, const LyaSpectraDataset &spectra_list, const GlobalVariables &kGlobalVariables) |
| void | CreateBinFiles () |
correlation_results.h Purpose: This file defines the class CorrelationResults. This class contains the variables necessary to store the measurement of the cross-correlation
Definition at line 37 of file correlation_results.h.
| CorrelationResults::CorrelationResults | ( | ) | [inline] |
Definition at line 44 of file correlation_results.h.
{};
| CorrelationResults::CorrelationResults | ( | const GlobalVariables & | kGlobalVariables, |
| const PlateNeighbours & | kPlateNeighbours | ||
| ) |
correlation_results.cpp Purpose: This files contains the body for the functions defined in correlation_results.h
EXPLANATION: Cosntructs a CorrelationResults instance and initializes all its variables
INPUTS: kGlobalVarialbes - object of type GlobalVariables kPlateNeighbours - a PlateNeighbours instance
OUTPUTS: NONE
CLASSES USED: CorrelationPlate CorrelationResults GlobalVariables
FUNCITONS USED: NONE
Definition at line 12 of file correlation_results.cpp.
{ // setting the number of bins and plates from kGlobalVariables num_bins_ = kGlobalVariables.num_bins(); num_sigma_bins_ = kGlobalVariables.num_sigma_bins(); num_pi_bins_ = kGlobalVariables.num_pi_bins(); // setting the results directory and the pairs file name from kGlobalVariables results_ = kGlobalVariables.results() + "qso_spectrum_pairs_info_bin_"; pairs_file_name_ = kGlobalVariables.pairs_file_name(); correlation_file_name_ = kGlobalVariables.correlation_file_name(); // initialization of the plates map plates_list_ = kPlateNeighbours.GetPlatesList(); for (size_t i = 0; i < plates_list_.size(); i ++){ correlation_plates_[plates_list_[i]] = CorrelationPlate(plates_list_[i], num_bins_, results_, pairs_file_name_, kPlateNeighbours.GetNeighboursList(plates_list_[i])); } // initialization of the normalized cross-correlation variable normalized_correlation_ = CorrelationPlate(_NORM_, num_bins_, results_, kGlobalVariables.normalized_correlation(), kPlateNeighbours.GetNeighboursList(_NORM_)); // creating bin files CreateBinFiles(); }
| void CorrelationResults::ComputeCrossCorrelation | ( | const AstroObjectDataset & | object_list, |
| const LyaSpectraDataset & | spectra_list, | ||
| const GlobalVariables & | kGlobalVariables | ||
| ) |
EXPLANATION: Computes the cross-correlation for all plates
INPUTS: object_list - an AstroObjectDataset instance spectra_list - a LyaSpectraDataset instance kGlobalVariables - a GlobalVariables instance to load the bin settings
OUTPUTS: NONE
CLASSES USED: AstroObjectDataset CorrelationResults GlobalVariables LyaSpectraDataset
FUNCITONS USED: NONE
Definition at line 56 of file correlation_results.cpp.
{ for (size_t i = 0; i < plates_list_.size(); i++){ std::cout << i << " out of " << plates_list_.size() << " computed" << std::endl; (*correlation_plates_.find(plates_list_[i])).second.ComputeCrossCorrelation(object_list, spectra_list, kGlobalVariables); } NormalizeCrossCorrelation(); SaveCrossCorrelation(); }
| std::string CorrelationResults::correlation_file_name | ( | ) | const [inline] |
Definition at line 53 of file correlation_results.h.
{return correlation_file_name_;}
| PlatesMapSimple<CorrelationPlate>::map CorrelationResults::correlation_plates | ( | ) | const [inline] |
Definition at line 56 of file correlation_results.h.
{return correlation_plates_;}
| CorrelationPlate CorrelationResults::correlation_plates | ( | int | plate_num | ) | const [inline] |
Definition at line 57 of file correlation_results.h.
{return (*correlation_plates_.find(plate_num)).second;}
| void CorrelationResults::CreateBinFiles | ( | ) |
EXPLANATION: Creates the bin files in where the pair information will be stored. If files already exist, resets them
INPUTS: NONE
OUTPUTS: NONE
CLASSES USED: CorrelationResults
FUNCITONS USED: ToStr
Definition at line 89 of file correlation_results.cpp.
{ for (int bin = 0; bin < num_bins_; bin ++){ // creating directory for the bin std::string directory_name = results_ + ToStr(bin)+"/"; std::string command = "mkdir " + directory_name; system(command.c_str()); // creating bin files for each of the plates for (PlatesMapSimple<CorrelationPlate>::map::iterator it = correlation_plates_.begin(); it != correlation_plates_.end(); it ++){ std::string filename = directory_name + (*it).second.pairs_file_name(); // writing headers in file (open the file erasing the previous content) std::ofstream bin_file(filename.c_str(),std::ofstream::trunc); if (bin_file.is_open()){ bin_file << "# object_RA object_DEC object_Z spectrum_RA spectrum_DEC pixel_Z pixel_dist pixel_number pixel_delta pixel_w pi sigma\n"; bin_file.close(); } else{ std::cout << "Unable to open file:" << std::endl << filename << std::endl; } } } }
| CorrelationPlate CorrelationResults::normalized_correlation | ( | ) | const [inline] |
Definition at line 60 of file correlation_results.h.
{return normalized_correlation_;}
| size_t CorrelationResults::num_bins | ( | ) | const [inline] |
Definition at line 63 of file correlation_results.h.
{return num_bins_;}
| size_t CorrelationResults::num_pi_bins | ( | ) | const [inline] |
Definition at line 66 of file correlation_results.h.
{return num_pi_bins_;}
| size_t CorrelationResults::num_sigma_bins | ( | ) | const [inline] |
Definition at line 69 of file correlation_results.h.
{return num_sigma_bins_;}
| std::string CorrelationResults::pairs_file_name | ( | ) | const [inline] |
Definition at line 72 of file correlation_results.h.
{return pairs_file_name_;}
| std::vector<int> CorrelationResults::plates_list | ( | ) | const [inline] |
Definition at line 75 of file correlation_results.h.
{return plates_list_;}
| int CorrelationResults::plates_list | ( | int | index | ) | const [inline] |
Definition at line 76 of file correlation_results.h.
{return plates_list_[index];}
| std::string CorrelationResults::results | ( | ) | const [inline] |
Definition at line 79 of file correlation_results.h.
{return results_;}


Anual fee:
Years to pay:
Anual interest:
Basic compensation:
Interest for Illness:
Interest for death:
Start age:
Years
Age
Paid
Insurance Value
Comp Illness
Comp Death
0
23
4420.00
0.00
14420.00
14420.00


About
How It Works
FAQ
Blog
Contact
Cart
0
Our Menu
Shawarma
$5.00
Add to Cart
Big Shawarma
$6.00
Add to Cart
XL Shawarma
$7.00
Add to Cart
XXL Shawarma
$8.00
Add to Cart


Control Panel
Timed Duel
Single Vote
Poll Audience
Idle
Voting
Voted
Result
Timer
Switch to state:
Idle State
Round ID
Conclude last round
Submit
Switch to state:
Voting State
Candidate ID
Score
Reset
Submit
Switch to state:
Voted State
Switch to state:
Result State
Timer
Submit
Idle
Voting
Result
Rank
Switch to state:
Idle State
Candidate ID:
Concluded:
Set CID
Switch to state:
Voting State
Switch to state:
Result State
Candidate:
Add Score:
Reset
Add Score
Switch to state:
Rank State
Notification Delay
Notify Winner
Poll
Result


These are the results of searching for
stem cells in Open Science. There are several ways to further refine or reframe your search results. (
disable tutorial)
Open Science may also suggest alternate search terms in the same area of research to aid your discovery process.
You can narrow the search results within this page by clicking a facet value; you can also change which facets are available for narrowing your results by selecting from this list.
You can refine your search by typing in this box; result narrowing takes place as you type. You can try it now by typing product in and watching the result set change.
Search results can come from several different data sources, from related web search indices to Open Science journals. To select just one source, click it in the list. Individuals can add new data sources to expand their results in Preferences.
Sorting controls are provided, defaulting to sort by relevance.
You can prioritize results by clicking the up or down arrow icon. Your prioritization in each search context is recorded over time and affects the way search results are returned to you in the future. This is a kind of value add application that could be available in the Open Science application marketplace.
Note the difference in the amount of information presented between some results. The first result above links to a video, so a screenshot and icon are provided; the second is a journal article. Results are enhanced where the data exists and can be customized by additional applications in the marketplace.
You can change the way the result set is presented from a list view to a timeline-based view. Other media-related views (e.g. images, videos, etc.) may also be available, though not in this mockup. Maps, scatterplot, graph views, etc. are also examples of marketplace applications that offer new insights over result sets.
Applications, or "lenses," can be applied to augment a result set with additional, third-party information to better understand and sift through the results. The one here is from the Whatizit service, adding Protein Disease UMLS taxonomy terms to applicable results. Results can now be refined and navigated based on the results of the value added service.
You can hover over the current application to highlight those parts of the page that result from use of the active application. When activated, you should see the taxonomy cloud facet on the left and parts of certain results have been generated from the Whatizit application.
Additional facets from the selected application are given higher priority in the facet list.
You can also view the taxonomy in hierarchical form instead of the presently displayed cloud form. This has not been implemented in the mockup.
You can choose from applications you've purchased, or turn off the use of all applications.
Depending on your search, you may receive recommendations of related Open Science marketplace applications.
The tutorial continues when you click on any result.


This mode supports single-sign-on (SSO) and also allows you to use Crowd groups for authorization. For example, you can say "everyone in the 'developers' group will have the administrator access".
Crowd overview of SSO Crowd configuration documentation Adding an Application in Crowd.


American Freight Corporation
Toggle navigation
cloud_download
CDL Application
American Freight Corporation
Nationwide Services
Download Application


Photo Roster
All Students
Sample Name 1<EMAIL_ADDRESS>|
Sample Name 2<EMAIL_ADDRESS>|
Sample Name 3<EMAIL_ADDRESS>|
Sample Name 4<EMAIL_ADDRESS>|
Sample Name 5<EMAIL_ADDRESS>|
Sample Name 6<EMAIL_ADDRESS>|
SC01
Sample Name 1<EMAIL_ADDRESS>|
Sample Name 2<EMAIL_ADDRESS>|
SC01-T01
Sample Name 1<EMAIL_ADDRESS>|
SC01-T02
Sample Name 2<EMAIL_ADDRESS>|
SC01-T03
Sample Name X<EMAIL_ADDRESS>|
SC01-T04
Sample Name X<EMAIL_ADDRESS>|
SC01-T05
Sample Name X<EMAIL_ADDRESS>|
SC01-T06
Sample Name X<EMAIL_ADDRESS>|
SC01-T07
Sample Name X<EMAIL_ADDRESS>|
SC01-T08
Sample Name X<EMAIL_ADDRESS>|
SC01-T09
Sample Name X<EMAIL_ADDRESS>|
SC02
Sample Name 3<EMAIL_ADDRESS>|
Sample Name 4<EMAIL_ADDRESS>|
SC02-T01
Sample Name 3<EMAIL_ADDRESS>|
Sample Name 4<EMAIL_ADDRESS>|
SC02-T02
Sample Name X<EMAIL_ADDRESS>|
SC02-T03
Sample Name X<EMAIL_ADDRESS>|
SC02-T04
Sample Name X<EMAIL_ADDRESS>|
SC02-T05
Sample Name X<EMAIL_ADDRESS>|
SC02-T06
Sample Name X<EMAIL_ADDRESS>|
SC02-T07
Sample Name X<EMAIL_ADDRESS>|
SC02-T08
Sample Name X<EMAIL_ADDRESS>|
SC02-T09
Sample Name X<EMAIL_ADDRESS>|
SC02-T10
Sample Name X<EMAIL_ADDRESS>|
SC03
Sample Name 5<EMAIL_ADDRESS>|
SC03-T01
Sample Name 5<EMAIL_ADDRESS>|
SC03-T02
Sample Name X<EMAIL_ADDRESS>|
SC03-T03
Sample Name X<EMAIL_ADDRESS>|
SC03-T04
Sample Name X<EMAIL_ADDRESS>|
SC03-T05
Sample Name X<EMAIL_ADDRESS>|
SC03-T06
Sample Name X<EMAIL_ADDRESS>|
SC03-T07
Sample Name X<EMAIL_ADDRESS>|
SC03-T08
Sample Name X<EMAIL_ADDRESS>|
SC03-T09
Sample Name X<EMAIL_ADDRESS>|
SC03-T10
Sample Name X<EMAIL_ADDRESS>|
SC04
Sample Name 6<EMAIL_ADDRESS>|
SC04-T01
Sample Name 6<EMAIL_ADDRESS>|
SC04-T02
Sample Name X<EMAIL_ADDRESS>|
SC04-T03
Sample Name X<EMAIL_ADDRESS>|
SC04-T04
Sample Name X<EMAIL_ADDRESS>|
SC04-T05
Sample Name X<EMAIL_ADDRESS>|
SC04-T06
Sample Name X<EMAIL_ADDRESS>|
SC04-T07
Sample Name X<EMAIL_ADDRESS>|
SC04-T08
Sample Name X<EMAIL_ADDRESS>|
SC04-T09
Sample Name X<EMAIL_ADDRESS>|
SC04-T10
Sample Name X<EMAIL_ADDRESS>|
SC05
Sample Name X<EMAIL_ADDRESS>|
SC05-T01
Sample Name X<EMAIL_ADDRESS>|
SC05-T02
Sample Name X<EMAIL_ADDRESS>|
SC05-T03
Sample Name X<EMAIL_ADDRESS>|
SC05-T04
Sample Name X<EMAIL_ADDRESS>|
SC05-T05
Sample Name X<EMAIL_ADDRESS>|
SC05-T06
Sample Name X<EMAIL_ADDRESS>|
SC05-T07
Sample Name X<EMAIL_ADDRESS>|
SC05-T08
Sample Name X<EMAIL_ADDRESS>|
SC05-T09
Sample Name X<EMAIL_ADDRESS>|
SC05-T10
Sample Name X<EMAIL_ADDRESS>|
SC06
Sample Name X<EMAIL_ADDRESS>|
SC06-T01
Sample Name X<EMAIL_ADDRESS>|
SC06-T02
Sample Name X<EMAIL_ADDRESS>|
SC06-T03
Sample Name X<EMAIL_ADDRESS>|
SC06-T04
Sample Name X<EMAIL_ADDRESS>|
SC06-T05
Sample Name X<EMAIL_ADDRESS>|
SC06-T06
Sample Name X<EMAIL_ADDRESS>|
SC06-T07
Sample Name X<EMAIL_ADDRESS>|
SC06-T08
Sample Name X<EMAIL_ADDRESS>|
SC06-T09
Sample Name X<EMAIL_ADDRESS>|
SC06-T10
Sample Name X<EMAIL_ADDRESS>|
SC07
Sample Name X<EMAIL_ADDRESS>|
SC07-T01
Sample Name X<EMAIL_ADDRESS>|
SC07-T02
Sample Name X<EMAIL_ADDRESS>|
SC07-T03
Sample Name X<EMAIL_ADDRESS>|
SC07-T04
Sample Name X<EMAIL_ADDRESS>|
SC07-T05
Sample Name X<EMAIL_ADDRESS>|
SC07-T06
Sample Name X<EMAIL_ADDRESS>|
SC07-T07
Sample Name X<EMAIL_ADDRESS>|
SC07-T08
Sample Name X<EMAIL_ADDRESS>|
SC07-T09
Sample Name X<EMAIL_ADDRESS>|
SC08
Sample Name X<EMAIL_ADDRESS>|
SC08-T01
Sample Name X<EMAIL_ADDRESS>|
SC08-T02
Sample Name X<EMAIL_ADDRESS>|
SC08-T03
Sample Name X<EMAIL_ADDRESS>|
SC08-T04
Sample Name X<EMAIL_ADDRESS>|
SC08-T05
Sample Name X<EMAIL_ADDRESS>|
SC08-T06
Sample Name X<EMAIL_ADDRESS>|
SC08-T07
Sample Name X<EMAIL_ADDRESS>|
SC08-T08
Sample Name X<EMAIL_ADDRESS>|
SC08-T09
Sample Name X<EMAIL_ADDRESS>|
Others
Preview User<EMAIL_ADDRESS>|
Teaching Assistants
Sample Name X<EMAIL_ADDRESS>|
Instructors
Preview User<EMAIL_ADDRESS>|


--- layout: component-layout title: How to add tags to a ticket? link-title: Tags category: Productivity url: /uvdemo/productivity/tags.html tags: [Tag, Tags, Ticket, Tickets, Add Tag to Ticket, Adding Tags to Tickets] ---
UVdesk - How to add tags to a ticket?
What are tags & its usage?
Tags are set of words that are used to add more meaning to the ticket and to make the ticket search easy.
Tags Usage:
Tag helps to label any ticket with specific words making it easier to search any ticket from a chunk of ticket list as it has been tagged.
For example - If you want to tag all the support requests having a prime concern related to presale then you can tag those tickets as "Presale query" or "About presale". It will help a lot in ticket search.
Quicks steps for adding Tags:
The tags can be added manually to any ticket by the support staff or the administrator. Follow these simple steps to tag any ticket.


The Lively Kernel has a class browser that allows
the behavior of the system to be viewed and edited interactively.
The upper left panel of the browser contains the names of the
Lively Kernel (JavaScript) classes in the system.
When you select one of them, the upper right panel shows
all the methods (functions) of that class.
When you choose one of the methods, the lower panel shows the
source code of the method.
Notes:
To save changes after editing a method, use the "accept changes"
operation that is available in the popup menu of the method panel.
You can also use the keyboard shortcuts defined below.
There are various keyboard shortcuts available to edit the methods.
(NOTE: these shortcuts do not work on all browsers. In some browsers
you may have to use the "Alt Gr" key instead):
Alt-S ("Save-It"): Save (accept) the changes
Alt-A: Select All
Alt-X: Cut
Alt-C: Copy
Alt-V: Paste
Alt-Z: Undo
Some additional comments on text editing:
Typing replaces selection.
Double-clicking selects a word; triple-clicking selects the entire text.
Double-clicking near a bracket, parenthesis or a JavaScript comment (/* ... */)
selects text inside the brackets/parentheses/comment.
Try it yourself! Try viewing the methods of class RectShape.
Try editing some of the methods to make changes to the behavior of the system
itself.
For instance, if you modify the method RectShape.setFill as shown below,
you change the way menus and many other objects in the system are drawn.
You have to accept the changes by pressing Alt-S or by choosing
the "evaluate as JavaScript code"
popup menu item of the text that you just edited.


what might make a good turn model?
taking in just tokens, timestamps, and speakers (i.e. an AWS transcript), how can we quickly put together a good transcript? what are some things to think about (e.g. back-channels)? what’s a way to measure the accuracy of a model if we don’t have labeled data?
what sorts of biases are likely to show up bc of a turn model?


Into_the_Badlands
Into the Badlands is a genre-bending martial arts series very loosely based on the classic Chinese tale "Journey to the West". In a land controlled by feudal barons, Into the Badlands tells the story of a great warrior and a young boy who embark on a journey across a dangerous land to find enlightenment.