Riga also automatically collects and receives certain information from your computer or mobile device, including the activities you perform on our Website, the Platforms, and the Applications, the type of hardware and software you are using (for example, your operating system or browser), and information obtained from cookies. For example, each time you visit the Website or otherwise use the Services, we automatically collect your IP address, browser and device type, access times, the web page from which you came, the regions from which you navigate the web page, and the web page(s) you access (as applicable).
When you first register for a Riga account, and when you use the Services, we collect some Personal Information about you such as:
Under no circumstances shall Riga be liable for any direct, indirect, special, incidental or consequential damages, including, but not limited to, loss of data or profit, arising out of the use, or the inability to use, the materials on this site, even if Riga or an authorized representative has been advised of the possibility of such damages. If your use of materials from this site results in the need for servicing, repair or correction of equipment or data, you assume any costs thereof.
All our templates inherit the GNU general public license from HTML. All .PSD & CSS files are packaged separately and are not licensed under the GPL 2.0. Instead, these files inherit Riga Personal Use License. These files are given to all Clients on a personal use basis. You may not offer them, modified or unmodified, for redistribution or resale of any kind. You can’t use one of our themes on a HTML domain. More on HTML Vs CSS, you can read here. You can use our templates do develop sites for your clients.
Services help our customers promote their products and services, marketing and advertising; engaging audiences; scheduling and publishing messages; and analyze the results.
By using any of the Services, or submitting or collecting any Personal Information via the Services, you consent to the collection, transfer, storage disclosure, and use of your Personal Information in the manner set out in this Privacy Policy. If you do not consent to the use of your Personal Information in these ways, please stop using the Services.
Riga Landing Page uses tracking technology on the landing page, in the Applications, and in the Platforms, including mobile application identifiers and a unique Hootsuite user ID to help us recognize you across different Services, to monitor usage and web traffic routing for the Services, and to customize and improve the Services. By visiting Riga or using the Services you agree to the use of cookies in your browser and HTML-based emails. Cookies are small text files placed on your device when you visit a web site in order to track use of the site and to improve your user experience.
BackCopyright © Riga - Mobile App Landing Page Template by Inovatik


--- layout: project_detail title: Terminus meta_content: Terminus project detail description project_id: terminus project_title: Terminus project_tagline: tech, ed, and a bit of art ---
Terminus is a text-based adventure game that teaches users how to use terminal commands.
Play the current version! And please leave feedback as a Github issue.


Home Space
Is This A Good Home For You?
Aspect
Data
Address
fsdfdfss
Price
fdsfsdfd
Suburb
fdsfsdfd
Bedrooms
fdsfsdfd
City
fdsfsdfd
Sun
NA


Chocolate Pizza
Posted on 15 Dec 2013 / Desserts
For the fig-swirl: Melt melt butter over medium heat in a saucepan. Add brown sufar and stir to dissolve. Halve all of the figs and toss in the saucepan with water and lemon juice. Cook over medium heat, stirring frequently, until you have a chunky-jammy mixture. Add salt with one or two stirs, set aside and let cool completely.
Ice cream: In a small pot overmedium heat, combine milk, and granualted sugar until sugar is completely dissolved and the milk is just barely lukewarm. Whisk in the egg yolks. Set mixture in the fridge and wait until the fig mixture is cooled.
Using an ice cream machine, pour liquids into the frozen basin and process according to manufacturer instructions, i.e., let spin and thicken for 20 minutes before adding marscarpone, fig jam mixture, and the nuts. Continue to process for +/- 10 minutes. Pour semi-frozen mixture into a pyrex dish or glass tupperware. Freeze for at least two hours before serving.
- 1 1/2 cups milk
- 1/2 cup mascarpone
- 1/2 tsp pink salt
- 1 lb Black Mission Figs
- 1/2 cup brown sugar
- 2-4 tbsp water
- 1 1/2 cups heavy cream
- 1/3 granulated sugar
- 2 egg yolks
- 1 lemon, juiced
- 2 tbsp butter
- 1 cup honey roasted pecans, roughly chopped
Vanessa Stevenson
Food enthusiast, photography fan. Add a pinch of raw foodism and that's pretty much who I am.


This sample illustrates how to wire up a Slack WebHooks receiver which can be used for both Slack Outgoing WebHooks as well as Slash Commands. A sample WebHook URI is:
https://<host>/api/webhooks/incoming/slack/{id}
Note that for security reasons the URI MUST be https.
Set the MS_WebHookReceiverSecret_Slack application setting to the Slack 'token' parameter, optionally using IDs
to differentiate between multiple WebHooks, for example '
In this example we use id 'trigger' for an outgoing WebHook and id 'slash' for a slash command. This means that you should register the following URIs with Slack:
https://<host>/api/webhooks/incoming/slack/trigger https://<host>/api/webhooks/incoming/slack/slash
and then configure the application setting as follows
<add key="MS_WebHookReceiverSecret_Slack" value="trigger=<token>, slash=<token>" />
Please see Slack WebHooks for more information.


Swedish word of the day: dagis
by Catherine EdwardsEssential vocab if you or your friends or colleagues have small children in Sweden.
Dagis is how many people refer to 'daycare' in Sweden.
It's short for daghem (literally 'day home' or 'home for the day') but most people use the more colloquial term ending in -is, just like many other slang or informal words in Swedish.
The more formal term for daycare is förskola (literally 'preschool').
It refers to structured childcare offered for children aged between one and five, before their time at förskoleklassen (preschool class, a halfway stage between förskola and primary school) begins at age six.
In most larger Swedish towns and cities, it's possible to find international dagisar, and there are a few different types of dagisar so that parents can choose the one that best suits them in terms of location and activities.
Compared to other countries, in Sweden a very high proportion of youngsters attend dagis, partly because it's heavily subsidized and so is low-cost for parents.
Municipalities are legally responsible for providing care at dagis, and the system has existed in Sweden in some form since the early 1800s, when it had a religious link.
However, it was only in 1943 that parliament decided on the names daghem and lekskola (literally 'playschool' as alternatives to the older name barnträdgård (literally 'child garden'), which was influenced by the German Kindergarten. The name förskola came a few years later, and was intended to emphasize the educational aspect of the centres, and now lekskola is quite old-fashioned but you'll still hear dagis used a lot.
There are a few related words, such as dagisplats (a place at (a particular) preschool) and dagiskö (queue for a dagisplats).
And homeware shop Clas Ohlson is sometimes jokily referred to as gubbdagis (preschool for older men) because of the stereotype that women might drop their husbands off there before continuing with their own shopping. That's slightly outdated now, after the company's CEO committed to improving gender equality in the business, and the store's customers are around 50 percent female.
Finally, dog owners should be aware of hunddagis (doggy daycare), since Sweden has strict rules about how long it's possible to leave dogs home alone.
Examples
Jag måste hämta Emil på dagis
I need to fetch Emil from daycare
Hur trivs barnen på dagis?
How are the children finding preschool?
Do you have a favourite Swedish word you would like to nominate for our word of the day series? Get in touch by email or if you are a Member of The Local, log in to comment below.


This is Halcyonic, a free site template by AJ for HTML5 UP. It's responsive, built on HTML5 + CSS3, and includes 5 unique page layouts.
This is Halcyonic, a free site template by AJ for HTML5 UP. It's responsive, built on HTML5 + CSS3, and includes 5 unique page layouts.
This is Halcyonic, a free site template by AJ for HTML5 UP. It's responsive, built on HTML5 + CSS3, and includes 5 unique page layouts.
This is Halcyonic, a free site template by AJ for HTML5 UP. It's responsive, built on HTML5 + CSS3, and includes 5 unique page layouts.


URL Shortener
Paste the URL to be shortened
Short me!
List URLs
or upload a .CSV file to shorten multiple URLs!


{% extends "base_AdminLTE.html"%} {% block title %}Docklet | Settings{% endblock %} {% block panel_title %}Settings{% endblock %} {% block panel_list %}
when an activating request is sent, an e-mail will be sent to this address to remind the admin.
if this address is "", no email will be sent to admin.
the e-mail address to send activating e-mail to user
if this address is "", no email will be sent out.


This page will contain information about recent changes to my CIS155 project. By: Kenneth Gray Date: 01/22/21 Course: CIS 155 Web Development I Project v1 01/22/21 Project v2 02/02/21 Project v3 02/17/21 Changelog 01/22/21 Project v1 Changes Added index.html (The home page) ✓ Added about.html (The about page) ✓ Added styles.css ✓ Added background and text color to css sheet. ✓ Added text-align to center the text on the site. ✓ Added hyperlink to group of shibas photo, directs to home page. ✓ Added hyperlink to "about" and "home" in changelog to direct users to wanted page. ✓ 02/02/21 Project v2 Changes Added history.html ✓ Added health.html ✓ Added grid style layout for shiba coat colors. ✓ Added grid style layout for history.html page to display picture on the left and text on the right. ✓ Added float to navigation links to display the navigation links horizontally. ✓ Added an image map to the Doge Meme face to redirect to Wiki on the Doge Meme. ✓ Added a paw print as a background image to the bottom right of the body of each page. ✓ Added text shadowing to h1 to add depth. ✓ Added sources right below changelog. ✓ Added a figure and a figure caption to the home page. ✓ 02/17/21 Project v3 Changes Added a table to health.html. ✓ Added information to health.html. ✓ Added table styles in css stylesheet. ✓ Added @media queries to format phones and PC. ✓ Added pulldown menu for the cited sources in about.html. ✓ Added a style to remove underline in navigation links. ✓


Provides authentication information for HTTP RPC calls.
Represents an HTTP authentication scheme like Basic or Bearer
Interface to provide a Bearer token to HTTP RPC API calls
HttpRpcClient is meant to run outside of Corda Node JVM and provide connectivity to a node using the HTTP-RPC protocol.
Since Corda Node can expose multiple RPC interfaces through HTTP, it is required to specify which RPCOps interface should be used.
A sibling of net.corda.internal.base.stream.DurableStreamContext but for HTTP RPC Client module
Once Artemis RPC elimination is complete those two classes might be merged into one, destination module TBD.
Represents a logical connection to the HTTP RPC server which may go up and down.
The proxy object can be used to make remote calls using the interface methods.
Can be attached to HttpRpcClient to be informed about connection and disconnection events.
HttpRpcConnectionListenerDistributor is responsible for distributing connection and disconnection events to interested listeners (HttpRpcConnectionListener).
RemoteClient implementations are responsible for making remote calls to the server and returning the response,
after potentially deserializing.
Analog of Apache HTTP's HttpContext can be extended to support storing state for challenge response based schemes
(extensions in package net.corda.v5.httprpc.client.internal.processing)


|
Bullet Collision Detection & Physics Library
|
#include "LinearMath/btThreads.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "BulletDynamics/ConstraintSolver/btSolverBody.h"
#include "BulletDynamics/ConstraintSolver/btSolverConstraint.h"
Go to the source code of this file.
Classes | |
| struct | btBatchedConstraints |
| struct | btBatchedConstraints::Range |


Setup
- Authentication Guard
- Login Controller
- Using Usernames
- Eloquent Model Binding
- Pass-Through Authentication / SSO
- Displaying LDAP Error Messages (password expiry, account lockouts)
Authentication Guard
Once you have configured a new authentication provider, you will have to setup your authentication guard to use this new provider.
For this example, we will change our default web
guard to use our new ldap
provider:
// config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'ldap', // Changed from 'users'
],
// ...
],
Login Controller
Now that we have updated our default authentication guard to use our new ldap
provider, we will jump into
the default LoginController
that is included with the Laravel UI package.
For this example application, we will authenticate our LDAP users with their email address using the LDAP attribute mail
.
To have LdapRecord properly locate the user in your directory during login,
we will override the credentials
method in the LoginController
:
// app/Http/Controllers/Auth/LoginController.php
use Illuminate\Http\Request;
protected function credentials(Request $request)
{
return [
'mail' => $request->email,
'password' => $request->password,
];
}
As you can see above, we set the mail
key which is passed to the LdapRecord authentication provider.
A search query will be executed on your directory for a user that contains the mail
attribute equal
to the entered email
that the user has submitted on your login form. The password
key will not be used in the search.
If a user is not found in your directory, or they fail authentication, they will be redirected to the login page normally with the "Invalid credentials" error message.
You may also add extra key => value pairs in the
credentials
array to further scope the LDAP query. Thepassword
key is automatically ignored by LdapRecord.
Using Usernames
In corporate environments, users are often used to signing into their computers with their username. You can certainly keep this flow easy for them - we just need to change a couple things.
First, you will need to change the email
column in the database migration that creates your users
table to username
, as this represents what it will now contain:
Schema::create('users', function (Blueprint $table) {
// ...
// Before...
$table->string('email')->unique();
// After...
$table->string('username')->unique();
});
Make sure you run your migrations using
php artisan migrate
.
Once we've changed the name of the column, we'll jump into the config/auth.php
configuration and modify
our LDAP user providers sync_attributes
to synchronize this changed column.
In this example, we will use the users sAMAccountName
as their username
which is common in Active Directory environments:
// config/auth.php
'providers' => [
// ...
'ldap' => [
// ...
'database' => [
// ...
'sync_attributes' => [
'name' => 'cn',
'username' => 'samaccountname',
],
],
],
],
Now, since we have changed the way our users sign into our application from the default email
field,
we need to modify our HTML login form to reflect this. Let's jump into our auth/login.blade.php
:
<!-- resources/views/auth/login.blade.php -->
<!-- Before... -->
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
<!-- After... -->
<input id="username" type="text" class="form-control @error('username') is-invalid @enderror" name="username" value="{{ old('username') }}" required autocomplete="username" autofocus>
After changing the HTML input, we now must modify our LoginController
to use this new field.
We do this by overriding the username
method, and updating our credentials
method:
// app/Http/Controllers/Auth/LoginController.php
use Illuminate\Http\Request;
public function username()
{
return 'username';
}
protected function credentials(Request $request)
{
return [
'samaccountname' => $request->get('username'),
'password' => $request->get('password'),
];
}
You can now sign into your application using usernames instead of email addresses.
Eloquent Model Binding
If you are using database synchronization, model binding allows you to attach the users LdapRecord model to their Eloquent model so their LDAP data is available on every request automatically.
Using this feature will perform a single query on your LDAP server for a logged in user per request. This could lead to slightly longer load times depending on your LDAP server and network speed.
This also means persistent LDAP connectivity is required while LDAP authenticated users use your Laravel application.
To begin, insert the LdapRecord\Laravel\Auth\HasLdapUser
trait onto your User model:
namespace App;
use LdapRecord\Laravel\Auth\HasLdapUser;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasLdapUser;
Now, after an LDAP user logs into your application, their LdapRecord model will be available on
their model via the ldap
property:
// Instance of App\User
$user = Auth::user();
// Instance of App\Ldap\User
$user->ldap;
// Get LDAP user attributes
echo $user->ldap->getFirstAttribute('cn');
// Get LDAP user relationships:
$groups = $user->ldap->groups()->get();
Pass-through Authentication / SSO
Pass-through authentication allows your users to be automatically signed in when they access your application on a Windows domain joined computer. This feature is ideal for in-house corporate environments.
However, this feature assumes that you have enabled Windows Authentication in IIS, or have enabled it in some other means with Apache. LdapRecord does not set this up for you. To enable Windows Authentication, visit the IIS configuration guide.
When you have it enabled on your server and a user visits your application from a domain joined computer,
the users sAMAccountName
becomes available on a PHP server variable ($_SERVER['AUTH_USER']
).
LdapRecord provides a middleware that you apply to your stack which retrieves this username from the request, attempts to locate the user in your directory, then logs the user in.
To use the middleware, insert it on your middleware stack inside your app/Http/Kernel.php
file:
protected $middlewareGroups = [
'web' => [
// ...
\LdapRecord\Laravel\Middleware\WindowsAuthenticate::class,
],
];
The
WindowsAuthenticate
middleware uses the rules you have configured inside yourconfig/auth.php
file. A user may successfully authenticate against your LDAP server when visiting your site, but depending on your rules, may not be imported or logged in.
SSO Domain Verification
To prevent security issues using multiple-domain authentication using the WindowsAuthenticate
middleware,
domain verification is performed on the authenticating user by checking if their domain name is contained
inside of the users distinguished name that is retrieved from each of your configured LDAP guards.
Only 'Domain Components' are checked in the users distinguished name. More on this below.
To describe this issue in further detail -- the WindowsAuthenticate
middleware retrieves all of your configured
authentication guards inside of your config/auth.php
file, determines which one is using the ldap
driver, and then attempts to locate the authenticating users from each connection.
Since there is the possibility of users having the same sAMAccountName
on two separate domains,
LdapRecord must verify that the user retrieved from your domain is in-fact the user who
is connecting to your Laravel application via Single-Sign-On.
For example, if a user visits your Laravel application with the username of:
ACME\sbauman
And LdapRecord locates a user with the distinguished name of:
cn=sbauman,ou=users,dc=local,dc=com
They will be denied authentication. This is because the authenticating user has a domain of
ACME
, but it is not contained inside of their distinguished name domain components (dc).
Using the same example, if the located users distinguished name is:
cn=sbauman,ou=users,dc=acme,dc=com
Then they will be allowed to authenticate, as their ACME
domain is contained inside of
their distinguished name domain components (dc=acme
).
Comparison against each domain component is done in a case-insensitive manor.
If you would like to disable this check, you must call the static method bypassDomainVerification
on the WindowsAuthenticate
middleware inside of your AuthServiceProvider
:
Important: If you only connect to one domain inside your application, this is not a security issue. However, if you use multi-domain authentication and disable this check, users who have the same
sAMAccountName
could login as eachother. This is a security issue. You have been warned.
// app/Providers/AuthServiceProvider.php
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
WindowsAuthenticate::bypassDomainVerification();
}
Changing the Server Key
By default, the WindowsAuthenticate
middleware uses the AUTH_USER
key inside of PHP's $_SERVER
array ($_SERVER['AUTH_USER']
). If you would like to change this, call the serverKey
method on
the WindowsAuthenticate
middleware inside of your AuthServiceProvider
:
// app/Providers/AuthServiceProvider.php
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
WindowsAuthenticate::serverKey('PHP_AUTH_USER');
}
Selective / Bypassing Single-Sign-On
Occasionally you may need to allow users who are not apart of the domain to login to your application, as well as allowing domain users to automatically sign in via Single-Sign-On.
Unfortunately, NTLM / Windows authentication is all-or-nothing on your entire web application. This means, you cannot enable a single HTTP endpoint in your application to use Single-Sign-On or exempt a portion of your application. However, there is a workaround that is used frequently in the industry.
The goal is to have two URL's that point to the same Laravel application. One that
has Windows authentication enabled, and another that does not. This is typically idendified by an sso
sub-domain:
<!-- Standard URL -->
my-app.com
<!-- Single-Sign-On URL -->
sso.my-app.com
To do this, you must create a new IIS instance and point to the same Laravel application. Then, you simply have Windows authentication enabled on one instance, and left disabled on another.
Nothing needs to be done in your Laravel application. The WindowsAuthenticate
middleware
will only attempt to authenticate users when the AUTH_USER
server key is present,
so it can remain in the global middleware stack.
Displaying LDAP Error Messages
When a user fails LDAP authentication due to their password / account expiring, account lockout or their password requiring to be changed, specific error codes are sent back from your server. LdapRecord can interpret these for you and display helpful error messages to users upon failing authentication.
To add this functionality, you must add the following trait to your LoginController
:
LdapRecord\Laravel\Auth\ListensForLdapBindFailure
Example:
// app/Http/Controllers/Auth/LoginController.php
// ...
use LdapRecord\Laravel\Auth\ListensForLdapBindFailure;
class LoginController extends Controller
{
use AuthenticatesUsers, ListensForLdapBindFailure;
// ...
However, this feature will only work automatically if your LoginController
resides in the default
App\Http\Controllers\Auth
namespace. If you have changed the location of your LoginController
,
you must modify the constructor and add the following method call to register the LDAP listener:
// app/Http/Controllers/Auth/LoginController.php
// ...
use LdapRecord\Laravel\Auth\ListensForLdapBindFailure;
class LoginController extends Controller
{
use AuthenticatesUsers, ListensForLdapBindFailure;
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->listenForLdapBindFailure();
}
Altering the response
By default, when an LDAP bind failure occurs, a ValidationException
will be thrown which will
redirect users to your login page and display the error. If you would like to modify this
behaviour, you will need to override the method handleLdapBindError
.
This method will include the error message as the first parameter and the error code as the second.
This is useful for checking for specific Active Directory response codes and returning a response:
// app/Http/Controllers/Auth/LoginController.php
// ...
class LoginController extends Controller
{
// ...
use ListensForLdapBindFailure {
handleLdapBindError as baseHandleLdapBindError;
}
protected function handleLdapBindError($message, $code = null)
{
if ($code == '773') {
// The users password has expired. Redirect them.
abort(redirect('/password-reset'));
}
$this->baseHandleLdapBindError($message, $code);
}
}
Refer to the Password Policy Errors documentation to see what each code means.


--- layout: doc title: Documentation ---
This appendix contains some tentative plans and ideas for improving Proof General.
This appendix is no longer extended: instead we keep a list of Proof General projects on the web, and forthcoming plans and ideas in the ‘TODO’ and ‘todo’ files included in the ordinary and developers PG distributions, respectively. Once the items mentioned below are implemented, they will be removed from here.
Please send us contributions to our wish lists, or better still, an offer to implement something from them!
| A.1 Proof by pointing and similar features | ||
| A.2 Granularity of atomic command sequences | ||
| A.3 Browser mode for script files and theories |
This is a note by David Aspinall about proof by pointing and similar features.
Proof General already supports proof by pointing, and experimental support was provided in LEGO. We would like to extend this support to other proof assistants. Unfortunately, proof by pointing requires rather heavy support from the proof assistant. There are two aspects to the support:
Term structure mark-up is useful in itself: it allows the user to explore the structure of a term using the mouse (the smallest subexpression that the mouse is over is highlighted), and easily copy subterms from the output to a proof script.
Command generation for proof by pointing is usually specific to a particular logic in use, if we hope to generate a good proof command unambiguously for any particular click. However, Proof General could easily be generalised to offer the user a context-sensitive choice of next commands to apply, which may be more useful in practice, and a worthy addition to Proof General.
Implementors of new proof assistants should be encouraged to consider supporting term-structure mark up from the start. Command generation should be something that the logic-implementor can specify in some way.
Of the supported provers, we can certainly hope for proof-by-pointing support from Coq, since the CtCoq proof-by-pointing code has been moved into the Coq kernel lately. I hope the Coq community can encourage somebody to do this.
This is a proposal by Thomas Kleymann for generalising the way Proof General handles sequences of proof commands (see Goal-save sequences in the user manual), particularly to make retraction more flexible.
The blue region of a script buffer contains the initial segment of the proof script which has been processed successfully. It consists of atomic sequences of commands (ACS). Retraction is supported to the beginning of every ACS. By default, every command is an ACS. But the granularity of atomicity should be able to be adjusted.
This is essential when arbitrary retraction is not supported. Usually, after a theorem has been proved, one may only retract to the start of the goal. One needs to mark the proof of the theorem as an ACS. At present, support for goal-save sequences (see Goal-save sequences in the user manual), has been hard wired. No other ACS are currently supported. We propose the following to overcome this deficiency:
proof-atomic-sequents-list
is a list of instructions for setting up ACSs. Each instruction is a
list of the form (end start &optional
forget-command)
. end is a regular expression to recognise
the last command in an ACS. start is a function. Its input is the
last command of an ACS.  It is evaluated once and, starting with the
command matched by end, the output is
successively matched against previously processed commands until a match
occurs (or the beginning of the current buffer is reached). The region
determined by (start,end) is locked as an ACS. Optionally,
the ACS is annotated with the actual command to retract the ACS. This is
computed by applying forget-command to the first and last command
of the ACS.
For convenience one might also want to allow start to be the
symbol ‘t’ as a convenient short-hand for '(lambda (str)
".")
which always matches.
This is a proposal by David Aspinall for a browser window.
A browser window should provide support for browsing script files and theories. We should be able to inspect data in varying levels of detail, perhaps using outlining mechanisms. For theories, it would be nice to query the running proof assistant. This may require support from the assistant in the form of output which has been specially marked-up with an SGML like syntax, for example.
A browser would be useful to:
The last point is the most important. We should be able to integrate a search mechanism for proofs of similar theorems, theorems containing particular constants, etc.
This document was generated on April 14, 2023 using texi2html 1.82.


I love to travel all around the world. I love to travel because both of my parents work for United Airlines, so I get to travel all around the world. I have been to
My other biggest interest must be sports. I have loved sports since I was a young kid, I have always had a interest in playing even though
I wasn't very good. I have always loved to watch them as well as play them with my friends or on a minor league team. My favorite sport is baseball,
I have played since I could remember. My favorite position was catcher because I got to be in every play. I also enjoy watching my favorite baseball team the
Chicago Cubs. My other favorite sport is Football that is American football. I was never good at playing football, so I mainly just watched it with
my dad. My Favorite team is the Chicago Bears, I am hoping for a Superbowl win this year.


--- layout: post title: Monotouch Examples date: '2010-01-03T02:54:00.001Z' author: solrevdev tags: modified_time: '2010-01-03T02:54:21.666Z' blogger_id: tag:blogger.com,1999:blog-31446756.post-1045190491650359161 blogger_orig_url: http://www.solrevdev.com/2010/01/monotouch-examples.html ---
Monotouch Examples
I really really have to get myself a mac so I can start developing apps for the iPhone rather than just reading about it.
Until that happens I will have to make do with looking at sites like this that have some code snippets in C# with the MonoTouch environment.


Acceptance Testing .NET Applications using IronPython
The following was originally published in the excellent Python Magazine. Thier contractual exclusivity period has now long expired, so here it comes again. Many thanks to my technical reviewer Michael Foord, and to the editors Brandon Craig Rhodes and Doug Hellmann, who patiently gave excellent and much needed guidance through its protracted gestation, and especially to all my co-workers at Resolver Systems, from whom I've learned so much.
Acceptance Testing .NET Applications using IronPython
Unit tests demonstrate to developers that individual functions and classes work as expected. Acceptance tests are an orthogonal complement to this. They verify to everybody, including managers and clients, that features they understand and care about are completed and working correctly. They also prove that the system as a whole is correctly integrated and that no regressions have occurred.
Resolver Systems is developing a .NET desktop spreadsheet application, Resolver One, for which we have accumulated an acceptance testing framework. This framework uses Python's standard unittest module, and is executed using IronPython.
While Resolver One is written in IronPython, this technique allows IronPython tests to interact with product code written in any .NET language.
This article describes the principles of this IronPython acceptance testing framework, and demonstrates them by creating an acceptance test for a small sample C# GUI application.
Caveats
When testing products written in static .NET languages such as C#, some common testing practices like monkey-patching will be unavailable. Static language classes are not modifiable at runtime, not even from tests written in IronPython. Fortunately, this is less of a concern for acceptance testing than it is for unit testing - we want the tests to operate on the unmodified whole end-to-end system.
Resolver One is currently 40k lines of IronPython. I would guess this is maybe equivalent to 60-80k lines of C#, demonstrating the viability of this approach for desktop applications of this size.
Our approach requires source code modifications to the system under test (SUT.) In particular, the SUT must provide methods for the test to start and stop the application, and must provide public access to its forms and other GUI objects. This means that this methodology cannot be used to black-box test arbitrary compiled programs - it requires the SUT to be written with testing in mind.
Why Acceptance Test?
Unit tests call individual methods and functions of the SUT, and have a close correspondence with the internal design of the product. Acceptance tests, in contrast, invoke the program as a whole, just like a user would, and have a close correspondence with the product specification.
Acceptance testing automates the expensive, time consuming, error-prone and soul-destroying process of using a team of human testers to fire up the application under test, and exhaustively interact with the user interface to verify the program behaves correctly. Traditionally, a single iteration of this process can take days or weeks for substantial applications. Automating the process can yield the same feedback - or better - in minutes or hours. This reduces costs and provides valuable, rapid feedback to both developers and project stakeholders.
This is useful for assessing whether user-visible features are correctly implemented, for doing quick smoke tests to make sure recent changes haven't accidentally broken other features, or for systematic checking that new functionality works under various conditions, such as on different operating systems, or in various browsers. Acceptance tests can include stress testing, and continually running acceptance tests on an integration server can detect infrequent, intermittent bugs.
Best of all, acceptance tests that are derived directly from the specification can prove to clients that the system does what the requirements ask. This can be invaluable when it comes to client sign-off on deliverables, especially if the client trusts this process due to having participated in the creation of the user-stories or acceptance tests themselves.
Acceptance tests do not yield the same incidental benefits in terms of good code design as unit tests do. However, creating acceptance tests before the product code is implemented does allow developers to focus exclusively on the requirements from a user's point of view. In practice, this turns out to help immeasurably in defining the specifications, and in giving developers a solid understanding of them.
Acceptance Tests Should Derive From User Stories
User Stories are a human-readable specification document that describes a short scenario, using the SUT to perform some actions that a real user cares about. User stories usually form the entire specification. Such documents should be informal yet precise, succinct and easy to understand. In ideal circumstances, your customer would collaborate with you in creating these documents.
An example user story might look like this:
- Alice starts WizBang. The window appears.
- She sees the three default list entries: 'one', 'two', 'three'. Nothing is selected.
- She clicks the 'AddButton'
- The 'Add Item' dialog appears
- She types an item name into the dialog and clicks OK
- The new item is at the end of the list, selected.
- She clicks the 'CloseButton'
- The application closes
An acceptance test is an executable script that performs the actions
described in the user story, and verifies the application responds as
expected. To create an acceptance test, at Resolver Systems we paste the
entire user story, as comments, into a new test method, on a class
derived from Python's unittest.TestCase
.
from unittest import main as run_test, TestCase class AT001_AddItems(TestCase): def test_additems(self): # 1. Alice starts WizBang. The window appears. # 2. She sees the three default list entries: # 'one', 'two', 'three'. Nothing is selected. # 3. She clicks the 'AddButton' # 4. The 'Add Item' dialog appears # 5. She types an item name into the dialog and clicks OK # 6. The new item is at the end of the list, selected. # 7. She clicks the 'CloseButton' # 8. The application closes self.fail("test not finished") if __name__ == '__main__': run_test()
The call to fail()
at the end of this test is a good habit to develop.
It stops unfinished tests like this one from passing, making them easy
to accidentally overlook and be forgotten, invisible amongst a large
collection of passing tests. When the test is complete, this fail can be
removed.
Setting up IronPython
In order for IronPython to be able to import from unittest
like this,
a copy of the CPython standard library must be on sys.path
. If you
installed version 2+ of IronPython from the MSI installer, this is all
taken care of automatically, using a copy of the standard library that
is included with the install. Otherwise, you need to set this up
manually, either by setting an environment variable:
set IRONPYTHONPATH=C:\Python25\Lib
or by appending this directory to sys.path
inside your IronPython
install's Lib\site.py
file:
import sys sys.path.append(r'C:\Python25\Lib')
Note that different versions of IronPython require different versions of the CPython standard library:
- IronPython 1.1: Python 2.4
- IronPython 2.0: Python 2.5
- IronPython 2.6: Python 2.6
Once this is done, test it out by starting ipy.exe
, and typing:
> import unittest
If this works without complaint, exit ipy.exe, and run the nascent acceptance test above, using the DOS command-line:
> ipy.exe AT001_AddItems.py F ====================================================================== FAIL: test_add_address (__main__.AT001_AddItems) ---------------------------------------------------------------------- Traceback (most recent call last): File "AT001_AddItems.py", line 11, in test_add_address self.fail("test not finished") AssertionError: test not finished ---------------------------------------------------------------------- Ran 1 test in 0.141s FAILED (failures=1)
About IronPython
IronPython is a .NET based reimplementation of the Python language. It combines the strength and elegance of Python as a language with the ability to directly call and interoperate with other .NET code. In daily use, I am continually surprised by how well this works. IronPython faithfully mimics CPython - there are almost no surprising differences between the two. Native Python types are mapped seamlessly and intuitively to equivalent .NET data types with an absolute minimum of fuss. For example, IronPython code can generally pass native Python types, like lists or dictionaries, to .NET functions or methods, instead of having to instantiate and populate .NET collection classes.
To use a .NET library, your IronPython code first has to add a reference
to the containing .NET assembly. An assembly is a physical chunk of
code, usually contained in a DLL file. To add a reference, use the clr
module, which is built-in to IronPython:
import clr clr.AddReference('System.Windows.Forms')
This AddReference()
function behaves just the same regardless of
whether you are referencing assemblies from the .NET standard library
(as shown here), 3rd party DLLs, or your own .NET projects.
Code within an assembly is contained within namespaces. For the .NET standard library, the assemblies are usually given the same name as the namespace they implement. This is the case here, so once the above assembly is referenced, we can import code from the System.Windows.Forms namespace just as if it was a Python module:
from System.Windows.Forms import Form form = Form() form.Show()
This will display an instance of the .NET form class on screen. Note
that the form does not yet respond to events. For that, we will add a
call to Application.Run()
, discussed below.
Note that our IronPython projects always contain an automatic reference
to the System
assembly, so anything implemented in there, such as the
System.Threading
namespace, can always be imported without having to
explicitly add any references.
Ostensibly, using .NET and IronPython limits the operations described in this whole article to Windows only. The Mono project should allow this acceptance testing technique to be used directly on other operating systems, but that has not been tried.
Implementing the Test
To implement the comments pasted into our acceptance test, three things must be done:
Firstly, the test must invoke the SUT, once for every test method, in such a way that the test and the SUT then both run simultaneously.
Secondly, while the test runs, it must be able to make assertions about the behaviour of the SUT. On the GUI, for example, the test must be able to read the state of the form and its controls, in order to assert that the correct text is displayed.
Thirdly, the test must provide simulated input on each of the SUT's external interfaces, to stimulate the program into action. For example, then the test must drive the SUT by providing simulated button clicks or keyboard input.
The method chosen to fulfil all three of these requirements is for the test to invoke the SUT in the same process, but on a new thread. Since IronPython is a .NET language, it can directly access the SUT's form and control objects, making assertions about the state of the controls that are visible to the user. It can also simulate user actions by calling methods and firing events on the SUT's GUI controls.
For this acceptance testing technique to work, the start-up of the SUT must be structured so as to expose a few public members and objects that are monitored and manipulated by the test. For example, elements of the GUI must be public. This obviously makes the tests fairly invasive.
We've justified this to ourselves at Resolver Systems by taking a pragmatic philosophy: These are the smallest set of changes to our application that we could find in order to make it testable. This technique has allowed us to create a set of working acceptance tests that wouldn't otherwise have existed.
The System Under Test
The public methods and objects required from our SUT are shown in the following minimal C# GUI application, called WizBang. This was created using the free Visual Studio Express Edition, but could easily be created using your own development tools of choice. At Resolver Systems, we prefer to create form layouts using Visual Studio's excellent GUI designing tool, and then inherit from these generated classes in other editors, such as Wing, Emacs or Vi.
WizBang defines a couple of simple forms, MainForm
and AddItemForm
:
WizBang has a public class called Program
, which provides public
access to the application's forms, and handles the startup and shutdown
of the application. During startup, it creates and shows an instance of
the main form.
// C# scaffolding for the WizBang application. // Exposes public functions and GUI forms, for use by tests. using System; using System.Threading; using System.Windows.Forms; namespace WizBang { public class AllForms { public static MainForm mainForm; public static AddItemForm addItemForm; } public class Program { public ManualResetEvent eventloopReady = new ManualResetEvent(false); public void Start() { AllForms.mainForm = new MainForm(); AllForms.mainForm.Show(); eventloopReady.Set(); Application.Run(); } public static void Stop() { Application.Exit(); } } }
Program.cs and its respective forms can be compiled to a .NET
assembly, WizBang.dll. When the application is run normally by users,
Program.Start()
is called by a second Visual Studio project,
RunWizBang, which exists simply to create a minimal Windows
executable.
To run WizBang during testing, the test code references the
WizBang.dll assembly, and calls Program.Start()
itself.
Importantly, a new instance of the main form is created every time
Program.Start()
is called. This allows many successive tests to run,
each with their own instance of the main form, so that state changes in
one test do not affect subsequent tests. This is important - the
application's state should be completely reset before the start of each
test. Take particular care to do this right if your application has
global state, such as class-level variables, singletons, or relies on
external systems such as the file system, the registry or databases.
After the main form is created and shown, Application.Run()
is called.
This is a .NET method which starts the main form's event loop, making
the form responsive to events such as form moves and resizes, control
clicks and keyboard presses.
When the test is completed, it can call the public Program.Stop()
method, which safely disposes of resources and unconditionally closes
the application by calling Application.Exit()
. This is a .NET method
which closes all our forms and ends their event loops.
Program.Stop()
should be the same method that your application calls
when quitting, after any user confirmations have happened. The following
handler on the main form's Closed event ensures this:
// C# event hander for the main form of the WizBang application private void MainForm_Closed(object sender, EventArgs e) { Program.Stop(); }
Invoking the SUT on a New Thread
If the test calls Program.Start()
directly, as described above, then
the program will run, and the main form will be displayed and
responsive, but the test will not work. The reason is that the call to
Application.Run()
is synchronous - it does not return until the
program exits. The test will be blocked, waiting for the application's
event loop to end.
The test must invoke the SUT in such a way that the program and the test can run together in parallel. Invoking the SUT in a new process would be nice for the sake of decoupling one test from the next. For our approach, however, the SUT has to run in the same process, to give the test access to the SUT's public methods and objects.
Program.Start()
therefore needs to be called on a new thread, created
by the test. The program's event loop can proceed on the new thread,
handling events to let the application run normally. Meanwhile, our test
can proceed on the original thread, stimulating the GUI and watching the
application's behaviour.
This threading is the reason for the ManualResetEvent
instance in
Program.cs. Manual reset events are a .NET construct to facilitate
synchronisation between threads. In this case, the SUT calls Set()
in
Program.Start()
, to tell the test thread that the main form has been
created and shown. The test can then start to make assertions about the
state of the main form's controls, and trigger events to manipulate
those controls.
For many activities in IronPython, there is a choice of using the familiar Python libraries, or the .NET equivalents. Threads are no exception to this - we may use the Python thread or threading modules, or we may use .NET's Threading library.
Incidentally, these threads differ from those in CPython in one important respect - there is no Global Interpreter Lock (GIL). The GIL is an implementation detail of the CPython interpreter. The threads created by .NET will run concurrently on multiple cores, no matter which library we use.
We implement this in a new class AcceptanceTest
, which sits between
AT001_AddItems
and unittest.TestCase
in the inheritance hierarchy:
On a real project, many ATxxx
test classes would inherit from
AcceptanceTest
, which looks like this:
# Python acceptance test base class # References .NET assemblies - requires IronPython import clr clr.AddReference('WizBang') # import from .NET namespaces - requires IronPython from System.Threading import ApartmentState, Thread, ThreadStart # import from the Python standard library from unittest import TestCase # import from the .NET namespace of the system under test from WizBang import Program class AcceptanceTest(TestCase): """ Starts up the program under test (PUT) on a new thread at the start of each test, and shut it down again after each test has run """ def __init__(self, *args): TestCase.__init__(self, *args) self.program = None self.eventloop = None def setUp(self): TestCase.setUp(self) self.program = Program() self.eventloop = Thread(ThreadStart(self.program.Start)) self.eventloop.Name = "eventloop" self.eventloop.SetApartmentState(ApartmentState.STA) self.eventloop.Start() self.program.eventloopReady.WaitOne() def tearDown(self): self.program.Stop() self.eventloop.Join() TestCase.tearDown(self)
Python's unittest module will call AcceptanceTest's setUp()
method
before each test method is run, so this is an ideal place to create a
new thread and invoke Program.Start()
on it. The new thread is given a
name, for ease of hypothetical future debugging. It must be set to a
single threaded apartment state to prevent possible errors if your code
calls any COM components, even indirectly.
Once the new thread has been started, starting the WizBang application,
setUp()
waits for a signal from the application on the
ManualResetEvent eventloopReady
. This is used by the application to
signal to the test that the main form is shown and its event loop is
started. This prevents over-eager tests from attempting to access the
main form before it is visible and responding to events.
Similarly, tearDown()
will be called by unittest after every test has
completed. In this method, Program.Stop()
is called to exit this
instance of WizBang. tearDown()
then waits for the SUT's event loop
thread to end, by joining it. This is to ensure the next test is not
affected in some way, by allowing it to start before this test has
ended.
This can all be tried out, by modifying AT001_AddItems
to inherit from
AcceptanceTest
instead of TestCase
, and adding a sleep in the body
of the test method, before the fail:
from System.Threading import Thread from unittest import main as run_test from AcceptanceTest import AcceptanceTest class AT001_AddItems(AcceptanceTest): def test_add_address(self): # 1. Alice starts WizBang. The window appears. # etc (not yet implimented) Thread.Sleep(5000) self.fail("test not finished") if __name__ == '__main__': run_test()
Running this test now displays the SUT's form for the duration of the sleep, and during that time it is responsive to move and resize events. Unlike the last version, this test proceeds to execute while the form is visible, so at the end of the sleep, the test fails, with 'test not finished', and the SUT is ended, closing its form.
Note that the sleep triggers a runtime warning from ipy.exe on stdout,
about sleeping threads not pumping GUI events. This makes no difference
here, but from now on, we'll do as this warning suggests and replace
sleeps with calls to Thread.CurrentThread.Join()
, which behaves the
same as sleep, but continues to process any events that arrive while
sleeping.
Now that our acceptance test is properly starting and stopping the SUT, we are in a position to start making assertions about the state and behaviour of the main form.
Asserting Correct Behaviour
We can now start coding the requirements that have been pasted into our acceptance test as comments. We might be tempted to implement the first requirement of the acceptance test as follows:
import clr clr.AddReference('WizBang') from WizBang import AllForms # 1. Alice starts WizBang. The window appears. mainform = AllForms.mainform self.assertEquals(mainform.Visible, 'form should be visible')
On first glance, this appears to work - you can run this and this assert
will pass. However, there is an insidious problem here, because it
accesses properties of a .NET control from a thread other than the one
it was created on. Such access can sometimes result in an
InvalidOperationException
, with a message along the lines of
"Cross-thread operation not valid: Control 'mainform' accessed from a
thread other than the thread it was created on." Worse, depending on
circumstances, sometimes no exception is raised, but values are returned
which may not be correctly synced to the current value of
mainform.Visible
.
The proper way to access properties like this is to invoke such code on
the control's own thread. All .NET controls, of which forms are a
subclass, have an Invoke()
method for just this purpose.
Conceptually, Invoke()
takes a callable, which is executed
synchronously by passing it as an event to the control's event loop (or
the event loop of its parent form). When the event loop processes this
event, the passed callable is invoked on the event loop's thread - which
can safely access the properties of its own controls. The return value
from the callable is passed back by the event-handler, and then safely
marshalled back to the invoking thread as the return value from
Invoke()
.
In practice, the callable passed to Invoke needs to be wrapped in a
delegate. Delegates are .NET's type-safe function pointers. An
appropriate delegate can be constructed using the IronPython construct
CallTarget0
, which denotes a delegate taking zero arguments.
The above sounds like quite a mouthful, and the code is correspondingly verbose:
import clr clr.AddReference('IronPython') from IronPython.Runtime.Calls import CallTarget0 # 1. Alice starts WizBang. The window appears. getVisible = CallTarget0(lambda: mainform.Visible) self.assertTrue(mainform.Invoke(getVisible), 'form not visible')
Note that the location of CallTarget0
was changed between IronPython
versions 1 and 2. The location of the import will need to change for the
above code to work on IronPython 1.
Invoking on the control's own thread like this means that our callable
(the lambda: mainform.Visible
) can safely access any of mainform's
properties and methods.
More Concise Test Code
The cross-thread invoking described above will be used frequently
throughout our acceptance tests, whenever the properties or methods of a
control are accessed. Such code can be abbreviated slightly, by defining
a method on AcceptanceTest
, to help us invoke on the main form's
thread:
def on_gui(self, target): return self.program.mainform.Invoke(CallTarget0(target))
Which can be used to reduce the length of our assertion to:
# 1. Alice starts WizBang. The window appears. self.assertTrue(self.on_gui(lambda: mainform.Visible), 'form not visible')
Even so, wrapping access to each attribute individually like is still a little fiddly, especially if it is happening many times. To improve this, there is nothing to stop us wrapping larger callables instead. For example, consider the second user story requirement:
# 2. She sees the three default list entries: # 'one', 'two', 'three'. Nothing is selected. self.on_gui(self.assert_list_at_startup)
The function assert_list_at_startup()
, shown below, can now have
access to properties on all controls without using Invoke()
, since it
runs entirely on the GUI thread:
def assert_list_at_startup(self): wizList = self.program.mainform.Controls['WizList'] self.assertEquals(wizList.SelectedIndex, -1, 'should be nothing selected') self.assertEquals(wizList.Items[0], 'one', 'list[0] wrong') self.assertEquals(wizList.Items[1], 'two', 'list[1] wrong') self.assertEquals(wizList.Items[2], 'three', 'list[2] wrong')
If any of these assertions should fail, raised exceptions are correctly
propagated back to our test thread. The only problem is that the stack
trace displayed in the test output ends at on_gui()
's cross-thread
invoke - i.e. it does not display the line within
assert_list_at_startup()
which failed. However such stack traces are
accompanied by the error message from the failing assertion, so this is
not usually a problem. If this turns out to be critical for your
situation, it is possible to create your own cross-thread exception
handler which fixes this, reconstituting the entire stack trace even
across thread boundaries.
Wrapping callables, as on_gui()
does, is often usefully implemented as
a decorator. This can be provided by our AcceptanceTest module:
def guithread(target): def wrapper(*args, **kwargs): test = args[0] return test.on_gui(lambda: target(*args, **kwargs)) return wrapper
This decorator expects to be applied to methods on AcceptanceTest
, so
that it can call .on_gui()
on this method's first parameter. if the
decorated function is not a method on AcceptanceTest, the decorator will
not work.
Functions like assert_list_at_startup()
, above, which make frequent
access to properties of controls, can now be decorated:
@guithread def assert_list_at_startup(self): wizList = self.program.mainform.Controls['WizList'] self.assertEquals(wizList.SelectedIndex, -1, # etc
Such a decorated method can then be conveniently called by the acceptance test:
# 2. She sees the three default list entries: # 'one', 'two', 'three'. Nothing is selected. self.assert_list_at_startup()
It is tempting at this point to simply decorate our entire test method
with @guithread
, so that the whole thing can execute on the GUI thread
and have unfettered access to the form's attributes and controls.
However, this would not work since the test needs to surrender its use
of the GUI thread from time to time, to allow the form to process all
the events on its event loop. Without this, the form would be blocked,
waiting for the test to finish, and would be unable to handle button
clicks and other input. Amongst other things, this would prevent the
form from reacting to the simulated user input that our test is about to
provide.
Simulating User Button Clicks
The next part of our acceptance test requires that the test provides some input to the SUT, simulating the actions of a user:
# 3. She clicks the 'AddButton'
Buttons provide a method specifically to simulate being clicked, which
our test can use. A small utility method on AcceptanceTest
calls this
on the GUI thread:
@guithread def click_button(self, form, buttonName): form.Controls[buttonName].PerformClick()
This can be used in our acceptance test:
# 3. She clicks the 'AddButton' self.click_button(mainform, 'addButton')
Running the test will now correctly click the add item button. However, the Wizbang application does not yet have any button click handlers, so the button has no effect.
Up until this point, all the assertions in AT001_AddItems
have passed
without us having to modify WizBang the application. This is because the
conditions being tested were already set up correctly by the design-time
properties of the main form, or by the application's scaffolding code in
WizBang.Program
.
When using test-driven development (TDD), this is generally not the case, and in fact, this is not true for our next requirement, which tests that the add item button click caused the add item form to appear. Since this is not yet implemented, when the test is run, this assertion will fail:
# 4. The 'Add Item' dialog appears addItemForm = AllForms.addItemForm self.assertTrue(self.on_gui(lambda: addItemForm.Visible), 'additem form should be visible')
To make this requirement pass, the following click handler is attached to the Add Item button on WizBang's main form. We're going to skip unit tests for this article, but on a real project, this is the perfect time to create them - after the acceptance test, but before the implimentation. Once they are done, the handler to make them and the acceptance test both pass looks like this:
// C# click handler for the AddItem button on WizBang's main form private void AddButton_Click(object sender, EventArgs e) { if (AllForms.addItemForm == null) AllForms.addItemForm = new AddItemForm(); AllForms.addItemForm.Show(); }
In a real application, this handler would need to be a little more robust, able to handle multiple clicks of the button, and forms which are disposed or already visible. However, this behaviour is not yet tested by our acceptance test, and therefore TDD conveniently suggests that for the moment, it should remain unimplemented.
Simulating User Keyboard Input
The next requirement asks that our test simulate the user typing into a TextBox control on the add item form. This can be trivially implemented using the techniques discussed thus far:
# 5. She types an item name into the dialog and clicks OK self.set_text(addItemForm.addItem, 'hello') self.click_button(addItemForm, 'okButton') self.assertFalse( self.on_gui(lambda: addItemForm.Visible), "additem form should close")
Where set_text()
is a small helper function provided by
AcceptanceTest
:
@guithread def set_text(self, textbox, text): textbox.Text = text
Running this test will successfully populate the TextBox with the word
"hello". However, this is a fairly poor acceptance test. If the TextBox
control did not have focus, then a real user would have to perform extra
steps before being able to type into it. If the TextBox was not visible
or enabled, then a user would not be able to type into it at all. Our
test implementation, by simply setting the Text
attribute, performs an
end-run around many of the restrictions that real users would face, and
hence is not a good test of the application's behaviour as a user would
actually experience it.
The simplest way to improve on this for the moment is to explicitly test for these conditions:
@guithread def set_text(self, textbox, text): self.assertTrue(textbox.Visible, 'textbox should be visible') self.assertTrue(textbox.Focused, 'textbox should have focus') self.assertTrue(textbox.Enabled, 'textbox should be enabled') textbox.Text = text
Running this test does actually reveal a genuine error - the add item
form's textbox does not have focus. A real user, on running WizBang,
would have to click or use the tab key to give the textbox focus, a step
which our test has previously been able to obliviously skip. We would
prefer that our user didn't have to do this either, so we add an
Activated
handler on the AddItemForm
:
// C# handler for the add item form's Activated event private void AddItemForm_Activated(object sender, EventArgs e) { addItem.Focus(); }
This makes the acceptance test pass. Implementing the next test requirement is straightforward:
# 6. The new item is at the end of the list, selected. self.assert_list_after_add()
where:
@guithread def assert_list_after_add(self): self.assertEquals(self.item_count(), 4, 'should be 4 items') wizList = AllForms.mainForm.Controls['WizList'] self.assertEquals(wizList.Items[3], 'hello', 'list[3] wrong') self.assertEquals(wizList.SelectedIndex, 3, '4th should be selected')
This is asserting that the text we typed into the add item form ("hello") is added to the end of the main form's list, and is selected. In order to make this pass, we need a click handler for the OK button on the add item form:
// C# handler for add item form's ok button private void okButton_Click(object sender, EventArgs e) { ListBox wizList = AllForms.mainForm.WizList; wizList.Items.Add(addItem.Text); wizList.SelectedIndex = wizList.Items.Count - 1; this.Close(); }
Finally, the test closes down the application and ends:
# 7. She clicks the 'CloseButton' self.click_button(mainForm, 'closeButton') # 8. The application closes self.assertTrue(mainForm.IsDisposed, 'mainform should close')
Notice how access to mainForm.IsDisposed
is not invoked on the GUI
thread. By this point in the test, all being well, the main form has
been closed, and its thread will be ended. Attempting to invoke on it
will fail. Instead, we read this property directly.
To make this pass, we add a simple button click hander to the main form's Close button:
// C# handler for click event on main form's close button private void CloseButton_Click(object sender, EventArgs e) { this.Close(); }
Simulating Mouse and Keyboard Events
Directly calling controls' methods and setting their properties, as described above, can be problematic, since the controls will not behave precisely as they would when in use by a real user. Our assertions above that controls being manipulated are currently visible, enabled and focussed are a partial solution to this problem.
However, there are many other possible ways in which our tests could
unintentionally get the SUT to behave in ways that are different from
the behaviour a real user would see. For example, a textbox could have a
custom keypress handler, which performs input validation of some kind.
Such a handler would not be invoked when our test simply sets the
.Text
property of the control, as we do above.
In a worst case scenario, acceptance tests could pass even though the application was completely unusable by a real user.
To combat this, the approach taken at Resolver Systems is to stimulate controls by generating fake Win32 mouse and keyboard events. This drives the application by, for example, actually moving the mouse cursor over a button, then issuing a mouse click event. Windows itself then fires the button click event, which ends up calling the click event handlers.
This approach guarantees that our acceptance tests are only able to perform the same actions that a human user would be able to, and is more of a true 'end-to-end' test - which seems like a good principle for acceptance tests to aim for in general.
Simulating user input in this way, however, is not without drawbacks.
The acceptance test framework sends low level mouse events, using the
win32 function SendInput()
, from the Windows user32.dll. Calling win32
functions from IronPython like this requires creating a C# assembly, in
which we expose SendInput()
, and more than a dozen similar functions,
by declaring them as follows:
using System.Runtime.InteropServices; namespace UnmanagedCode { // extensive type declarations for type 'Input' go here public class User32 { [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int SendInput( int nInputs, ref Input pInputs, int cbSize); } }
It turns out that populating the large Input
data structure to be
passed to this function takes another 50 lines of code. Similar
scaffolding is required to support keyboard events. This is a
substantial extra layer of complexity - albeit one that has proven
reliable and stable since it was created.
Having said that, the acceptance tests written this way are not completely reliable in operation - developers (or office cleaners) moving the mouse or leaning on the keyboard can interfere with the running tests. Sometimes, due simply to race conditions, the GUI does not respond as quickly as the test script expects, causing spurious failures. While issues such as these can be accounted for, for example by waiting for events or for conditions before allowing tests to proceed, this still causes a significant level of false positives in our test failures, as new tests 'bed down' and we gradually discover and compensate for their intermittent failure modes.
Finally, it is probable that our tests run more slowly than they would if they invoked event handlers directly. To some extent this is mitigated by a distributed test runner, which splits any given test suite across all idle desktop machines in the office. However, there are many tests, some of which are stress tests, and running our full acceptance test suite still takes at least a couple of hours. Having it run faster would always be beneficial.
Because both speed and reliability might be improved to some extent by reducing our use of keyboard and mouse events, it would be advisable to at least consider trying the simpler techniques described earlier in this article, before attempting to generate mouse and keyboard events like this.
Conclusion
We've seen how to construct an IronPython acceptance test for an application written in C#.
Despite the pitfalls described in the last section, we're very happy with acceptance testing of our .NET desktop application at Resolver Systems. It has proven to be eminently feasible, and of great value to us. In addition to the well-known benefits of unit-testing, acceptance testing provides an orthogonal layer of information about the system-under-test.
Most directly, it gives concrete, rapid feedback on the completion and robustness of features at a level that managers care about and users understand. Also, it provides thorough smoke tests to check that recent changes have not broken existing functionality. Perhaps most important of all, however, acceptance tests provide a method to precisely specify detailed requirements which can be easily created by users, are intimately understood by developers, are provably met, and are trivially traceable through to the final phases of the project.
Given acceptance tests such as those described in this article, test-driven development then provides developers with the ability to navigate from requirements through to working code that provably fulfils the specification, using a series of small, discrete and well-understood steps. This gives projects practical tools with which to make rapid progress, to avoid major risks, and to meaningfully measure the project's current status and velocity.
Readers who are interested in using IronPython, for testing or for other purposes, should check out IronPython in Action, a pragmatic and densely informative new book by Michael Foord, which caters to both Python and .NET developers.


I have done codeine a good bit through my life, and it is probably my favorite 'mellow' drug other than weed. I was first introduced to it by a high school friend, and I used to trade weed or speed or coke or whatever for it. At first, I would only have a pill or two, but I started taking it more and more. It was cheap so I did it several times a day, which didn't help.
After a while the pills were too much of a chore to choke down, so I busted them up and dissolved them in (as I recall) ringer's lactate to inject. For several months I shot up increasingly more and more until I was usually a stupefied zombie. What I remember best about this was the way just after I shot up everything white seemed green, desks, walls, paper, etc. Not a dark green, a sort of day-glo, brighter-at-the-edges green, kind of hard to look at directly. Not suprisingly I did very poorly in school that year.
Other codeine highlights: Passing out during choir recital on codeine, Liquid Ketocet and Xylezine(sp?) I shot up, and nearly living on the stuff working under the table shoveling gravel last summer. No more green (Or shooting it up) It just made me feel stoned-happy and a couple made it so I could get drunk off a couple beers. A sidenote: A friend almost died that summer from taking Codiene and Vetrinary Epilepsy medicine and driving. be careful mixing with other downers.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Midnight city goes platinum
Posted in Photos at October 14th, 2013.
Midnight city went platinum!
Thank you guys for making this happen…
Much love
A
Posted in Photos at October 14th, 2013.
Midnight city went platinum!
Thank you guys for making this happen…
Much love
A
Posted in Film at April 4th, 2013.
You can now listen to the Oblivion Soundtrack, Anthony’s collaboration with composer Joseph Trapanese, in full on Mashable here. The CD is available to pre-order in the M83 store here, and on iTunes here.
Posted in Music at March 6th, 2013.
Anthony has been working on the official score for Oblivion with Tron composer Joseph Trapanese.
Head over to Rolling Stone here to listen to ‘StarWaves’, taken from the soundtrack released on April 9th on Back Lot Records.


Input modules are generic components that let one map a key to one or more values. In concept and API, input modules are closest to the java.util.Properties class. An input module has a number of named attributes, each of which has an associated value or values, which will be computed or looked up when requested.
| InputModule | |----------------------------| | PropName | PropValue(s) | |----------------------------| | prop1 | value1 | | prop2 | value2 | | ... | ... | | propn | valuen | +----------------------------+
Three operations are defined by the InputModule interface:
getAttribute(prop1)
would return value1
Input modules are used in various places in Cocoon, notably from within the sitemap, XSPs, and matchers.
In the sitemap, input modules are made available
through a {modulename:attributename} syntax. For instance, if a RequestParameterModule named
request-param
is defined in cocoon.xconf, then
{request-param:user}
will in effect be replaced by the value of
the user
request parameter (e.g. index.html?user=joe). Similarly,
a SystemPropertyModule named
system-property
would allow
{system-property:user.home}
to represent user's home directory
path.
Input modules are declared in cocoon.xconf. There is a section dedicated to input modules:
<input-modules> <component-instance name="global" class="org.apache.cocoon.components.modules.input.GlobalInputModule" logger="core.modules.input"/> <component-instance name="request" class="org.apache.cocoon.components.modules.input.RequestModule" logger="core.modules.input"/> <component-instance name="session" class="org.apache.cocoon.components.modules.input.SessionModule" logger="core.modules.input"/> <component-instance name="request-param" class="org.apache.cocoon.components.modules.input.RequestParameterModule" logger="core.modules.input"/> ... <component-instance name="defaults" class="org.apache.cocoon.components.modules.input.DefaultsModule" logger="core.modules.input"> <values> <skin>defaultSkin</skin> <base-url>http://localhost:8080/cocoon</base-url> </values> </component-instance> <input-modules>
In cocoon.xconf, each input module can take a static configuration.
This is made available to the class via the configure()
method,
called once on startup. In the example above, an Avalon
Configuration
object representing the <values> node will be
passed to the DefaultsModule.
In addition, every time an input module is used, a dynamic configuration is passed to it, as well as the current "object model". You can see these in the InputModule interface definition for all three methods. This dynamic, per-request configuration will usually override the static configuration. This dual static/dynamic configuration makes input modules useful in a wide variety of circumstances.
So-called "meta" modules are modules that act on other modules. The simplest example of a meta module is the SimpleMappingMetaModule, which will query another module with a modified version of an attribute name. For instance, if configured with:
<component-instance name="mappingmodule" class="org.apache.cocoon.components.modules.input.SimpleMappingMetaModule" logger="core.modules.mapper"> <input-module name="xmlmodule"/> <prefix>/site/</prefix> <suffix>/@href</suffix> </component-instance>
Then a key foo
will cause xmlmodule
to be queried for
attribute /site/foo/@href
, and that value will be returned.
Another useful example is ChainMetaModule, which will query a set of input modules until one returns a non-null value for an attribute, providing "fall-back" behaviour.
The machinery for meta modules is provided in AbstractMetaModule.
Many input modules make use of the JXPath library, which lets one traverse Java object structures with an XPath-like syntax. Support for this is mostly located in the JXPathMetaModule and AbstractJXPathModule superclasses, which should be kept synchronised.
The best way to learn what can be done with input modules is by examining the samples that come with the Cocoon application. The main Cocoon documentation and Cocoon Wiki should have further information.


Discus
The discus throw is sport in athletics, of the track and field type, in which a disk-shaped object, known as a discus, is thrown for distance in an attempt to mark a farther distance than his or her competitors. The discus throw is a routine part of most modern track and field meets at all levels and is a sport which is particularly iconic of the Olympic Games. In modern competition the discus must be thrown from a circle 2.5 metres (8.2 feet) in diameter and fall within a 40° sector marked on the ground from the centre of the circle.
Javelin
The javelin throw is a track and field athletics event where the javelin, a spear about 2.5 m (8 ft 2 in) in length, is thrown. Javelin throwing is an event of both the men's decathlon and the women's heptathlon. The javelin thrower gains momentum by running within a predetermined area.
Shot Put
The shot put is a track and field event involving "throwing"/"putting" (throwing in a pushing motion) a heavy spherical object —the shot—as far as possible. The shot put competition for men has been a part of the modern Olympics since their revival in 1896, women's competition began in 1948.
Hammer Throw
The hammer throw is a sport in athletics, of the track and field type, in which a hammer is hurled for distance, using two hands within a throwing circle. In the modern hammer throw technique, a thrower makes three full, quick turns of the body before flinging the weight. Strength, balance, and proper timing are essential. The throw is a failure if the athlete steps on or outside the circle, or if the hammer lands outside a 40° sector marked on the field from the centre of the circle.
Road Running
Road running is the sport of running on a measured course over an established road, as opposed to track and cross country running. These events would be classified as long distance according to athletics terminology, with distances typically ranging from 5 kilometers to 42.2 kilometers in the marathon. They may involve large numbers of runners or wheelchair entrants. Road running is part of a group of road events known as "road races". Road running may offer those involved a range of challenges and interests such as dealing with hills, sharp bends, varied surfaces, inclement weather, and involvement in a large group. Aerobic fitness, or the ability of the body to use oxygen, is the biggest factor contributing to success. The impact of running on roads puts more stress on the feet, knees and lower back than running on dirt or grass. It can compensate by providing a consistent, level surface. It may put less strain on the Achilles tendon.


Bringing to you the best home made cakes for all functions
want to surprise loved ones, flossy cakes are the right cakes to buy!
Flossy cakes has a month end cake and platter promotion..5% discount for any cake and design
Categories of our different products
Wedding Cakes
BirthDay Cakes
Cookies
Muffins


This is a very short story.
There once was a person who signed up for web development classes.
He was very excited to share knowledge with his classmates and instructors.
This was his first attempt at writing HTML.
This will certainly not be his last crack at HTML.
I look forward to learning more with you all.
With warm regards,
Shure Joe


Let's talk product
StaySafe is an platform for Shops, Malls, Showrooms, Parlars, Salons which gives real time updates about number of COVID19 positive cases founded within 14 days on their respecrtive permises. So they can take safaty measure on time, and abate it to further spread.
image_search
Quick scanner
Quickly scans your customer's any government-approved ID so that, you can securly and uniquely indentify your customers.
developer_board
Simple Dashboard
The user-friendly dashboard, keeps data of your customer's all previous arrivals, So you can easily track your regular customers.
how_to_reg
Reduces Fake Identity Description
As the data directly get fetched from IDs, Now no need to ask your customer about there details and filled it mannually. So chances of fake indenty description will decreases.
pan_tool
Promote Social Distancing
Promotes social distancing by keeping a track of how frequently a customer visits a your place. And helps to take measures which will profitable to you.Here is our team
Namodith
Founder and CEO of StaySafe.
A very creative and optimistic person with good management skills and also a pro-active communicator.
Somyranjan Rout
Developer and Co-founder of StaySafe
Creative and People-Oriented Developer with decent Web development, UX/UI and project management experience. Cloud Computing, Deep learning and Cyber Security Enthusiast.
Tejash Butani
App Developer and Co-founder of StaySafe.
Proficient in mobile app development. Persistent towards his goals and action-oriented person.


{% extends "layout.html" %} {% block title %}Not found | {% endblock %} {% block body %}
This page doesn't exist


NoClick Help File
Settings may end with "_units". The units are
- ms = milliseconds
- pix = screen pixels
- deg = degrees
Colours are specified as #RRGGBB, with 6 hexidecimal digits.
Mouse
timeInterval_ms [integer]
This is the sampling rate at which the mouse is querried for its position. The variable, stationaryDuration_, is incremented to indicate how many milliseconds the mouse has been stationary for. It is reset to 0 when the mouse has not been stationary.
stationaryThreshold_ms [integer]
This is how long the mouse must be stationary before it can activate a button.
HotCursor
semiWidth_pix [integer]
The cursor is square. The side length is 1 + 2 * semiWidth.
color [string]
The colour of the two cross-hairs of the cursor.
inset_pix [integer]
The cursor is a cross-hair. The inset is how far each of the 4 arms keeps from the centre. An inset of 0 is a full cross.
show [boolean]
Set to, false, to hide the cross-hair. It can interfere with screen work.
HotKey
The hot key toggles between Hide and Show i.e an active and inactive system.
modifiers
The modifier mask for the hot key. Shift=1, Ctl=2, Alt=4. A mask of value -1 indicates that there is no hot key.
key
The platform-specific key code for the hot key.
Label
timeInterval_ms [integer]
This is how often the variable, stationaryDuration_, is checked to see if the mouse is stationary. The labels/buttons in the GUI are activated by the mouse coming to stop in the label.
allowHover
When set, hovering will switch Show to Hide.
Panes
movingTimeCutoff_ms
How long for the mouse and star to disappear when the mouse starts moving.
sideLength_pix [integer]
Each of the 4 "click" panes is a square of this side length.
lineOffset_pix [integer]
How many pixels the left-most and right-most panes are displaced vertically in the Line configuration type of the click panes.
type [string]
Either LinePanesTypoe or SquarePanesType, for the confguration type of the click panes.
hotPointOffset_pix [integer]
This indicates how far the outside corner of the LeftClick pane is from the mouse: The line segment joinging the outside corner and the mouse is the hypotenuse of an isoscelese right triangle, with each leg having length hotPointOffset.
opacity
A real number between 0 and 1.
borderWidth_pix
Width of pane border with Linear panes arrangement.
borderColor
This color is used with Linear panes when the borderWidth_pix < 0.
borderOpacity
The opacity of the pane borders with the Linear pane configuration.
leftClickColor [string]
rightClickColor [string]
dClickColor [string]
dragColor [string]
The colour for the corresponding pane.
Drag
stopDelay_ms [integer]
During a 1-Stage drag, this is how long the mouse can be statinary for, before the drag is ended.
stopDelay2_ms [integer]
During a 2-stage drag, this is how long the mouse can be statinary for, before the second stage of the drag is ended.
type [integer]
This is the type of drag that the Drag pane actives -- either 1 or 2, corresponding, respectively to a 1-stage Drag or a 2-stage Drag.
stageColor [string]
The colour of the drag radio buttons when that stage of a drag is active.
Star
"Star" refers to the red box that appears on the screen (originaly planned it to be a star).
color
Color of the star.
opacity
Opacity of the star.
hotPointOffset_pix
Distance of star from the hot point.
sideLength_pix
Side length of the star
axisAngle_deg [float]
In order for the Click Panes to appear, the mouse must move into the cone having its vertex at the mouse, its centre line (axis) joing with the Star, and the cone sides make an angle of, axisAngle, with the axis.
stationaryTimeAppear_ms [int]
How long it takes the red box to appear, once the mouse has become stationary. If this is too small, it causes flickering of the red box.
stationaryTimeCutoff_ms [int]
How long the red box stays visible once the mouse has become stationary.
Action
The actions are intiated from the four click panes.
timeInterval_ms [integer]
How often the action, if any, is attended to. This setting sets a timer.
System
lowestLoggingLevel [integer]
The logging levels are
- 0 = Debug
- 1 = Info
- 2 = Warn
- 3 = Critical
- 4 = Fatal
These values are NOT the values of the QMsgType enumeration, as Info was added later, and its value is not in sequence of severity. For example, if lowestLoggingLevel is set to 2, the only log messages recorded are those of severity Warning and hgher.
writeIniFileNameToScreen [boolean]
This is a convenience, as the ini file name contains the full path to where NoClick also keeps this help file and the log file.


z
-plane
Please enable JavaScript for this application to work!
f
(
z
) =
ok
Equation Parsed: ✔
Clear Graphs
Toggle Axes On/Off
Zoom Square
Zoom
z
:
-
+
Zoom
w
:
-
+
Color:
Free Draw
Line
Circle
Pointer
z
-plane range:
w
-plane range:
w
-plane
Please enable JavaScript for this application to work!


Flag of The Republic of Indiaभारतीय ध्वज (तिरंगा)
Saffron signifies Sacrifice, white signifies Peace and green signifies Prosparity.
The blue wheel is the Ashoka Chakra, having 24
spokes, which inspires to work tirelessly.
Developed By: Vani Kulkarni,
Graphics Design: Mayuresh Kulkarni


Fabian Caba Heilbron
I am a Research Scientist at Adobe Research. I recieved my Ph.D. from KAUST under the supervision of Professor Bernard Ghanem. I was fortunate to work with Juan Carlos Niebles during my master studies at Universidad del Norte.
My research interests span computer vision and machine learning. Specifically, my research focuses in the developments of models to recognize and detect human activities from videos. Some of my previous efforts include:
- gathering large-scale video datasets
- developing efficient scanning methods for video analysis
- training models for temporal activity localization
If you want to reach out, please contact me at: fabian.caba [at] kaust.edu.sa
Professional Experience
ActivityNet Challenge [2016-Present]: I am one of the leading forces behind organizing the ActivityNet Challenge. I built the infrastructure that allows multiple researchers to test-bed their methods. The challenge has attracted a large number of researchers, and it has been sponsored by several companies including DeepMind, Facebook, and Google AI.
Mantis AI [2017-Present]: I am a co-founder of Mantis AI. Mantis crafts ground-breaking research in deep-learning to perform activity detection and video summarization for content-aware ad placement.
IVUL [2015-2019]: I was a Research Assistant at IVUL. My work aimed to develop models for human activity understanding. Some of my efforts were published at top-tier computer vision conferences (see Publications).
Adobe Research [Summer 2017, Summer 2018]: I was an intern for two consecutive summers at Adobe Research. During these periods I developed: (i) an active learning method for action detection; (ii) a navigation system for video editing purposes.
Publications
Active Speakers in Context
Juan Carlos Leon, Fabian Caba Heilbron, Long Mai, Federico Perazzi, Joon-Young Lee, Pablo Arbelaez, Bernard Ghanem Seattle, CVPR 2020. - [Paper (Coming Soon)]
TDNet: A Temporally Distributed Network for Fast Video Segmentation
Ping Hu, Fabian Caba Heilbron, Oliver Wang, Zhe Lin, Stan Sclaroff, Federico Perazzi Seattle, CVPR 2020. - [Paper (Coming Soon)]
RefineLoc: Iterative Refinement for Weakly-Supervised Action Localization
Humam Alwassel, Alejandro Pardo, Fabian Caba Heilbron, Ali Thabet, Bernard Ghanem Preprint, 2019. - [arXiv]
Rethinking Online Action Detection in Untrimmed Videos: A Novel Online Evaluation Protocol
Marcos Baptista-Ríos, Roberto J. López-Sastre, Fabian Caba Heilbron, Jan C. Van Germert, F. Javer Acevedo-Rodríguez, Saturnino Maldonado-Bascón IEEE Access 2019. - [Paper]
Logistic Regression is Still Alive and Effective.
Merey Ramazanova, Chen Zhao, Mengmeng Xu, Humam Alwassel, Sara Rojas, Fabian Caba Heilbron, Bernard Ghanem Seoul, ICCVW 2019. - [Paper]
Clothing Recognition in the Wild using the Amazon Catalog
Fabian Caba Heilbron, Bojan Pepik, Zohar Barzelay, Michael Donoser Seoul, ICCVW 2019. - [Paper]
What do I Annotate Next? An Empirical Study of
Active Learning for Action Localization
Fabian Caba Heilbron, Joon-Young Lee, Hailin Jin, Bernard Ghanem Munich, ECCV 2018. - [Paper]
Temporal Action Localization
Humam Alwassel*, Fabian Caba Heilbron*, Bernard Ghanem; * := equal contribution Munich, ECCV 2018. - [Paper] [Project page] [Video]
Humam Alwassel*, Fabian Caba Heilbron*, Victor Escorcia*, Bernard Ghanem
* := equal contribution Munich, ECCV 2018. - [Paper] [Project page] [Code (Github)] [Video]
SCC: Semantic Context Cascade for Efficient Action Detection
Fabian Caba Heilbron, Wayner Barrios, Victor Escorcia, Bernard Ghanem
Hawaii, CVPR 2017. - [Paper] [Poster]
DAPs: Deep Action Proposals for Action Understanding
Victor Escorcia, Fabian Caba Heilbron, Juan Carlos Niebles, Bernard Ghanem
Amsterdam, ECCV 2016. - [Paper] [Code (Github)] [Poster]
Efficient Detection of Human Actions in Untrimmed Videos
Fabian Caba Heilbron, Juan Carlos Niebles, Bernard Ghanem
Las Vegas, CVPR 2016. - [Paper] [Project page] [Code (Github)] [Demo]
Fabian Caba Heilbron, Victor Escorcia, Bernard Ghanem, Juan Carlos Niebles
Boston, CVPR 2015. - [Paper] [Project page] [Code (Github)] [Demo]
Bernard Ghanem, Ali Thabet, Juan Carlos Niebles, Fabian Caba Heilbron
Boston, CVPR 2015. - [Paper] [Project page] [Code] [Data]
Fabian Caba Heilbron, Ali Thabet, Juan Carlos Niebles, Bernard Ghanem
Singapore, ACCV 2014. - [Paper] [Project page]
Fabian Caba Heilbron, Juan Carlos Niebles
Glasgow, ICMR 2014. - [Paper] [Code (Github)]
In God we trust. All others must bring data.
— W. Edwards Deming


“It looks really cool! I use GCSE Bitesize but it doesn’t always explain things that well.”
Blessing, GCSE Student, Brixton
“This looks like it would be very helpful. Right now I use Gojimo, but it just uses lots of questions”
Joseph, A-Level Biology Student, Camberwell


What is an SIP?
*Monthly Investment value must be between ₹ 500 to ₹ 2,00,000
*Investment preiod should be between 1 to 30 years
*Rate Of Return must be between 1% to 15%


Before Change
c1 = np.linalg.norm(B, np.inf)
for j in range(m_star):
B = t * np.dot(A, B) / float(s*(j+1))
c2 = np.linalg.norm(B, np.inf)
F = F + B
if c1 + c2 <= tol * np.linalg.norm(F, np.inf):
break
c1 = c2
After Change
raise ValueError("expected A to be like a square matrix")
if A.shape[1] != B.shape[0]:
raise ValueError("the matrices A and B have incompatible shapes")
if B.ndim not in (1, 2):
raise ValueError("expected B to be like a matrix or a vector")
n = A.shape[0]
n0 = B.shape[-1]
u_d = 2**-53
tol = u_d
mu = _trace(A) / float(n)
A = A - mu * np.identity(n)
A_1_norm = _exact_1_norm(A)
if t*A_1_norm == 0:
m_star, s = 0, 1
else:
ell = 2
norm_info = LazyOperatorNormInfo(t*A, A_1_norm=t*A_1_norm, ell=ell)
m_star, s = _fragment_3_1(norm_info, n0, tol, ell=ell)
F = B
eta = math.exp(t*mu / float(s))
for i in range(s):
c1 = _exact_inf_norm(B)
for j in range(m_star):
print(type(t))
print(type(s))
print(type(j))
print(type(A), type(B))
print()
coeff = t / float(s*(j+1))
B = coeff * np.dot(A, B)
c2 = _exact_inf_norm(B)
F = F + B
if c1 + c2 <= tol * _exact_inf_norm(F):
break


Named entity disambiguation (NED) is the process of mapping “strings” to “things” in a knowledge base. You have likely already used a system that requires NED multiple times today. Every time you ask a question to your personal assistant or issue a search query on your favorite browser, these systems use NED to understand what people, places, and things (entities) are being talked about.
Take the example shown above. You ask your personal assistant “What is the average gas mileage of a Lincoln?”. The assistant would need NED to know that “Lincoln” refers to Lincoln Motors (the car company)—not the former president or city in Nebraska. The ambiguity of mentions in text is what makes NED so challenging as it requires the use of subtle cues.
NED gets more interesting when we examine the full spectrum of entities shown above, specifically the more rare tail and unseen entities. These are entities that occur infrequently or not at all in data. Performance over the tail is critical because the majority of entities are rare. In Wikidata, only 13% of entities even have Wikipedia pages as a source of textual information.
Prior approaches to NED use BERT-based systems to memorize textual patterns associated with an entity (e.g., Abraham Lincoln is associated with “president”). As shown above, the SotA BERT-based baseline from Févry does a great job at memorizing patterns over popular entities (it achieves 86 F1 points over all entities). For the rare entities, it does much worse (58 F1 points lower on the tail). One possible solution to better tail performance is to simply train over more data, but this would likely require training over data 1,500x the size of Wikipedia for the model to achieve 60 F1 points over all entities!
In this blog post, we present Bootleg, a self-supervised approach to NED that is better able to handle rare entities.
Tail Disambiguation through NED Reasoning Patterns
The question we are left with is how to disambiguate these rare entities? Our insight is that humans disambiguate entities, including rare entities, by using signals from text as well as from entity relations and types. For example, the sentence “What is the gas mileage of a Lincoln?” requires reasoning that cars have a gas mileage, not people or locations. This can be used to reason that the mention of “Bluebird” in “What is the average gas mileage of a Bluebird?” refers to the car, a Nissan Bluebird, not the animal. Our goal in Bootleg is to train a model to reason over entity types and relations and better identify these tail entities.
Through empirical analysis, we found four reasoning patterns for NED, shown and defined in the figure below.
These patterns rely on signals from entities, types, and relations. Luckily, tail entities do not have equally rare types and relations. This means we should be able to learn type and relation patterns from our data that can apply to tail entities.
Bootleg: A Model for Tail NED
Bootleg takes as input a sentence, determines the possible entity candidates that could be mentioned in the sentence, and outputs the most likely candidates. The core insight that enables Bootleg to better identify rare entities is in how it internally represents entities.
Similar to how words are often represented by continuous word embeddings (e.g., BERT or ELMo), Bootleg represents entity candidates as a combination of a unique entity embedding, a type embedding, and a relation embedding, as shown above. For example, each car entity will get the same car type embedding (likewise for relations) which will encode patterns learned over all cars in the training data. A rare car can then use this global “car type” knowledge for disambiguation, as it will have the car embedding as part of its representation.
To output the correct entities, Bootleg uses these representations in a stacked Transformer module to allow the model to naturally learn the useful patterns for disambiguation without hard-coded rules. Bootleg then scores the output candidate representations and returns the most likely candidates.
There are other exciting techniques we present in our paper regarding regularization and weak labeling to improve tail performance.
Bootleg Improves Tail Performance and Allows for Knowledge Transfer
Our simple insight of training a model to reason over types and relations provides state-of-the-art performance on three standard NED benchmarks – matching or exceeding SotA by up to 5.6 F1 points – and outperforms a BERT-based NED baseline by 5.4 F1 points over all entities and 40 F1 points over tail entities (see F1 versus entity occurrence plot above).
Benchmark
System
Precision
Recall
F1
KORE50
Hu et al., 2019
80.0
79.8
79.9
Bootleg
86.0
85.4
85.7
RSS500
Phan et al., 2019
82.3
82.3
82.3
Bootleg
82.5
82.5
82.5
AIDA CoNLL YAGO
Févry et al., 2020
-
96.7
-
Bootleg
96.9
96.7
96.8
We’ll now show how the entity knowledge encoded in Bootleg’s entity representations can transfer to non-NED tasks. We extract our entity representations and use them in both a production task at a major technology company and relation extraction task. We find that the use of Bootleg embeddings in the production task provides a 8% lift in performance and even improves quality over Spanish, French, and German languages. We repeat this experiment by adding Bootleg representations to a SotA model for the TACRED relation extraction task (see tutorial). We find this Bootleg-enhanced model sets a new SotA by 1 F1 point.
These results suggest that Bootleg entity representations can transfer entity knowledge to other language tasks!
Recap
To recap, we described the problem of the tail of NED and showed that existing NED systems fall short at disambiguating these rare, yet important entities. We then introduced four reasoning patterns for NED and described how we trained Bootleg to learn these patterns through the use of embeddings and Transformer modules. We finally showed that Bootleg is a SotA NED system that better disambiguates rare entities than prior methods. Further, Bootleg learns representations that can transfer entity knowledge to non-NED tasks.
We are actively developing Bootleg and would love to hear your thoughts. See our website, source code, and paper.


{% extends "base.html" %} {% block title %}Profile{% endblock %} {% block content_header %}
In this profile you will be able to see all the content created by you.