--- layout: default sidebar: false sharing: true ---
As is obvious from the content of Sold Everywhere But Borders, the employees and customers of Ramsey Borders gave it an identity. The book is a tribute to the company, yes, but more so to the people who made up the company. Of the 11,000+ individuals who were ever employed by Borders Group, I only had the pleasure of meeting a few of them, but I wouldn't trade these relationships for the world.


React admin framework done by and for backenders
ALPHA VERSION – NOT FOR PRODUCTION USE
$ yarn add @bestdoctor/ke
This is an example of the future API
To use ke
you should implement several base classes.
First of all you should extend BaseProvider
class.
It implements the basic methods for HTTP interaction using an axios instance.
Thus, you should have an axios instance with the required headers and pass
it to the provider class.
// client.ts
import axios from 'axios'
const httpClient = axios.create({
baseURL: process.env.API_URL,
})
export { httpClient }
// provider.ts
import { BaseProvider } from '@bestdoctor/ke'
import { httpClient } from 'client'
class Provider extends BaseProvider {
constructor() {
super(httpClient)
}
}
export { Provider }
After that you should extend BaseAdmin class. Here you can declaratively describe your component.
In admin class you can describe:
getResource(lookupField?: string | undefined): string
- method to get resource
url string for backend requests.As a result, your admin class will look like this:
// admin.tsx
import {
BaseAdmin,
BaseFilter,
LinkWidget,
ReadOnlyWidget,
SelectWidget,
ForeignKeySelectWidget,
} from '@bestdoctor/ke';
import { PatientProvider } from './providers';
class PatientAdmin extends BaseAdmin {
list_filters = {
name: 'id',
label: 'ID',
Filter: BaseFilter,
}
list_fields = [
{
id: 'id',
Header: 'ID',
toDetailRoute: '/patients',
accessor: (row: any) => row.id,
},
]
detail_fields = [
{
name: 'full_name',
widget: LinkWidget,
helpText: 'Full name',
href: (object: any) => object.admin.url,
layout: { x: 2, y: 1, w: 2, h: 1, static: true },
},
{
name: 'user.email',
widget: ReadOnlyWidget,
helpText: 'User email',
layout: {x: 0, y: 0, w: 1, h: 2, static: true},
},
{
name: 'status',
widget: SelectWidget,
helpText: 'Status',
dataSource: `${process.env.API_URL}appeal_results/`,
layout: {x: 3, y: 3, w: 1, h: 2, static: true},
},
{
name: 'user',
widget: ForeignKeySelectWidget,
helpText: 'User select',
dataSource: `${process.env.API_URL}users/`,
targetPayload: (object: any) => ({ user: object.email }),
optionLabel: (object: any) => object.full_name,
optionValue: (object: any) => object.email,
layout: { x: 9, y: 13.5, w: 2, h: 1, static: true },
}
]
getResource(lookupField?: string | undefined): string {
const baseUrl = `${process.env.API_URL}patients/`
return getAdminResource(baseUrl, lookupField)
}
}
To get more info about fields description, check here
After that you can use ResourceComposer
, AdminResource
and Resource
components,
which makes all magic under the hood and get your user component.
AdminResource
component takes the following arguments:
admin
– instance of your admin classprovider
– instance of your provider implementationuser
– user object from your backend. Used for permissions and analytics systemanalytcs
– analytics object instance. See below for more details.import { ResourceComposer } from '@bestdoctor/ke';
import { Provider } from 'provider';
const provider = new Provider()
const App = () => (
<ResourceComposer>
<AdminResource
name="patients"
admin={new PatientAdmin()}
provider={provider}
user={{ name: 'name', permissions: ['admin_user'] }}
analytics={analyticsInstnace}
/>
</ResourceComposer>
)
App
will have routes for the list and detail view with the
settings and widgets you set.
Resource
component can be used in case you want to mount custom widget to
ke
routing and use it features under the hood. For example, login page:
<Resource name="login">
<Login />
</Resource>
If you want ke to generate a side bar with all sections of your spa, use
withSideBar
setting:
<ResourceComposer withSideBar>
...
</ResourceComposer>
You can restrict access to different sections of your system, as well as to individual widgets.
To restrict access to an entire section, define permissions list in your admin class:
import { BaseAdmin } from '@bestdoctor/ke'
class MyAdmin extends BaseAdmin {
baseUrl = 'https://test.com'
permissions = ['my_admin_access_permission']
list_fields = ...
}
and pass current user permissions list to ResourceComposer
element:
<ResourceComposer permissions={currentUser.permissions}>
...
</ResourceComposer>
To render a specific widget based on user permissions, use hasPermission
util in detail fields settings:
import { hasPermission } from '@bestdoctor/ke'
...
{
name: 'status.text',
helpText: 'Status',
widget: (user: { permissions: string[] }) => (
hasPermission(user.permissions, 'admin_permission') ? SelectWidget : ReadOnlyWidget
),
displayValue: (object: any) => object.status,
targetPayload: (value: any) => ({ status: value }),
layout: { x: 9, y: 9, w: 2, h: 1, static: true },
},
Out of the box we support error monitoring via Sentry
To include it in your application, use the component EnableSentry
at the root of your application.
// App.tsx
import { EnableSentry } from '@bestdoctor/ke'
const App = (): JSX.Element => (
<>
<EnableSentry sentryDSN={sentryDSN} />

Hello, world

</>
)
For application perfomance monitoring we support ELK APM You can use it via EnableELK component
import { EnableELK } from '@bestdoctor/ke'
const App = (): JSX.Element => (
<>
<EnableELK
serviceName={ELK_SERVICE_NAME}
serverUrl={ELK_SERVER_URL}
serviceVersion={ELK_SERVICE_VERSION}
/>

Hello, world

</>
)
ke
has default integration with google analytics through firebase.
You can use it or connect the service you need. To use build-in analytics
create instance:
import { FirebaseAnalytics } from '@bestdoctor/ke'
const firebaseConfig = {
apiKey: 'secret',
authDomain: 'auth.domain',
databaseURL: 'database.url',
projectId: 'projectID',
storageBucket: '',
messagingSenderId: '',
appId: '',
measurementId: '',
userId: '',
}
const analytics = new FirebaseAnalytics(firebaseConfig)
and pass it to your AdminResource
:
<AdminResource
name="test"
admin={new TestAdmin()}
provider={provider}
user={currentUser}
analytics={analytics}
/>
If you want to use another analytics service, you must define on your side a client that will implement the base interface, by analogy with firebase
Analytics hanlder here is object, that will handle events submit (in case you use SDK).
ke
has default analytics payload format:
You can override it with widgetAnalytics
setting
in your admin class settings
(place where you describe your widgets layout).
This setting can be declared as an arrow function that takes all of the above parameters. The return value of this function will be used as the body of the request when sent to the analytics:
{
name: 'test_widget',
widget: SelectWidget,
widgetAnalytics: ({ eventName, viewType, value, widgetName }) => (
{ customEventKey: { eventName, ... }}
),
...
}
To disable analytics for a specific widget, you can declare a widgetAnalytics
setting as false
:
{
name: 'test_widget',
widget: SelectWidget,
widgetAnalytics: false,
...
}
If you want to use analytics in your custom component-based widget,
you can use pushAnalytics
handler
It encapsulates the logic for unpacking and sending the event to the analytics.
Among other arguments described above, it takes widgetAnalytics
parameter.
pushAnalytics({
eventName: EventNameEnum.BUTTON_CLICK,
widgetType: WidgetTypeEnum.ACTION,
value: 'some value',
widgetAnalytics: true,
widgetName,
viewType: 'some_action',
resource: 'some_resource',
...props,
})
props
here is the properties,
that ke
injects in your custom widget when renders them from admin settings.
import type { WidgetProps } from '@bestdoctor/ke'
const CustomWidget = (props: WidgetProps): JSX.Element => {
const handleUserAction = (): void => {
pushAnalytics({
eventName: EventNameEnum.BUTTON_CLICK,
widgetType: WidgetTypeEnum.ACTION,
value: 'some value',
widgetAnalytics: true,
widgetName,
viewType: 'some_action',
resource: 'some_resource',
...props,
})
...
}
return (
<Button onClick={handleUserAction}>TEST</Button>
)
}
We would love you to contribute to our project. It's simple:
After cloning this repo if you'd like to use it in another project using React
(placed at e.g. /path/to/your/awesome/project/
) you should follow these steps:
yarn install
@bestdoctor/ke
: yarn link
npm link /path/to/your/awesome/project/node_modules/react
@bestdoctor/ke
to your project:
yarn link "@bestdoctor/ke"
(must be run in your project's folder)Here are useful tips:
yarn makecheck
.
Please do it before TravisCI does.Generated using TypeDoc


A simple web application that locates vaccine availability across Delhi (India). It uses Government of India's public API to fetch vaccines and is accurate upto 5 minutes of live status. Full project on my Github.


Gets an ECU-TEST installation instance by name which must be present in Jenkins global tool configuration.
ET.installation(String toolName) : ETInstance
ET.installation(Map<String, Object> installArgs) : ETInstance
ET.installation('ECU-TEST')
ET.installation toolName: 'ECU-TEST'


IndRel19
Set Warnings "-notation-overridden,-parsing".
From Coq Require Import ssreflect ssrbool ssrfun.
Require Import PeanoNat. (* for basic properties of nat functions! *)
Import Nat.
From Coq Require Import ssreflect ssrbool ssrfun.
Require Import PeanoNat. (* for basic properties of nat functions! *)
Import Nat.
Inductive Relations
One useful example is the "less than or equal to"
relation on numbers.
The following definition should be fairly intuitive. It
says that there are two ways to give evidence that one number is
less than or equal to another: either observe that they are the
same number, or give evidence that the first is less than or equal
to the predecessor of the second.
(* Inductive le : nat -> nat -> Prop := *)
(* | le_n : forall n, le n n *)
(* | le_S : forall n m, (le n m) -> (le n (S m)). *)
Inductive le (n: nat) : nat → Prop :=
| le_n : le n n
| le_S : ∀m, (le n m) → (le n (S m)).
(* Locate "<=". *)
Notation "m ≤ n" := (le m n).
(* | le_n : forall n, le n n *)
(* | le_S : forall n m, (le n m) -> (le n (S m)). *)
Inductive le (n: nat) : nat → Prop :=
| le_n : le n n
| le_S : ∀m, (le n m) → (le n (S m)).
(* Locate "<=". *)
Notation "m ≤ n" := (le m n).
Proofs of facts about ≤ using the constructors le_n and
le_S follow the same patterns as proofs about properties, like
ev above. We can apply the constructors to prove ≤
goals (e.g., to show that 3≤3 or 3≤6), and we can use
tactics like inversion to extract information from ≤
hypotheses in the context (e.g., to prove that (2 ≤ 1) → 2+2=5.)
Here are some sanity checks on the definition. (Notice that,
although these are the same kind of simple "unit tests" as we gave
for the testing functions we wrote in the first few lectures, we
must construct their proofs explicitly — simpl and
reflexivity don't do the job, because the proofs aren't just a
matter of simplifying computations.)
Theorem test_le1 :
3 ≤ 3.
Proof.
(* WORKED IN CLASS *)
apply le_n. Qed.
Theorem test_le2 :
3 ≤ 6.
Proof.
(* WORKED IN CLASS *)
do 3!(apply le_S). apply le_n. Qed.
Theorem test_le3 :
(2 ≤ 1) → 2 + 2 = 5.
Proof.
(* WORKED IN CLASS *)
case E : _ / ⇒ [| n H] //.
case F : _ / H; by rewrite F in E.
Qed.
3 ≤ 3.
Proof.
(* WORKED IN CLASS *)
apply le_n. Qed.
Theorem test_le2 :
3 ≤ 6.
Proof.
(* WORKED IN CLASS *)
do 3!(apply le_S). apply le_n. Qed.
Theorem test_le3 :
(2 ≤ 1) → 2 + 2 = 5.
Proof.
(* WORKED IN CLASS *)
case E : _ / ⇒ [| n H] //.
case F : _ / H; by rewrite F in E.
Qed.
Note it would be possible to define our relation in an almost identical way:
Inductive le' : nat → nat → Prop :=
| le'_n : ∀n, le' n n
| le'_S : ∀n m, (le' n m) → (le' n (S m)).
| le'_n : ∀n, le' n n
| le'_S : ∀n m, (le' n m) → (le' n (S m)).
But proving lemmas like the one one above using the ssreflect strategy would get somewhat more difficult. You can try it and see what would get problematic...
Theorem test_le'3 :
(le' 2 1) → 2 + 2 = 5.
Proof.
case E : _ _ / ⇒ [n | n m H] //.
(le' 2 1) → 2 + 2 = 5.
Proof.
case E : _ _ / ⇒ [n | n m H] //.
Here we can still handle the first case...
by rewrite -E.
But what now? The goal you are seeing now is simply nonsensical, even though there is nothing obviously inconsistent in the premises. If it is not obvious yet, try:
rewrite !add_succ_l !add_succ_r.
Not looking good, is it?
Abort.
We see here one of advantages of reasons why chosing one of arguments to be a parameter might be a good design choice. More will be seen when we discuss the shape of automatically generated induction principles later in this lecture. Let us also mention that similar problems may occur in the context of, e.g., formalizations of homotopy type theory in Coq.
The "strictly less than" relation n < m can be defined
in terms of le.
Definition lt (n m:nat) := le (S n) m.
Notation "m < n" := (lt m n).
Notation "m < n" := (lt m n).
In fact, this relation is already defined:
Print le.
Print Peano.le.
(* => Inductive le (n : nat) : nat -> Prop :=
le_n : n <= n | le_S : forall m : nat, n <= m -> n <= S m *)
Print Peano.le.
(* => Inductive le (n : nat) : nat -> Prop :=
le_n : n <= n | le_S : forall m : nat, n <= m -> n <= S m *)
Similarly, lt is also already there:
Print lt.
Print Peano.lt.
(* => lt = fun n : nat => eta le Peano.le (S n)
: nat -> nat -> Prop *)
Print Peano.lt.
(* => lt = fun n : nat => eta le Peano.le (S n)
: nat -> nat -> Prop *)
Obviously, le has its own reflection view:
Check leb_spec0.
(* => leb_spec0
: forall x y : nat, reflect (x <= y) (x <=? y) *)
Some other simple relations on numbers:
Inductive square_of (n : nat) : nat → Prop :=
sq : square_of n (n * n).
Inductive next_nat : nat → nat → Prop :=
| nn : ∀n:nat, next_nat n (S n).
sq : square_of n (n * n).
Inductive next_nat : nat → nat → Prop :=
| nn : ∀n:nat, next_nat n (S n).
Exercises
(* FILL IN HERE *)
Now for a change define an inductive binary relation empty_relation (on numbers)
that never holds.
Define then the corresponding (trivial) fuction empty on booleans and provide (trivial) reflection view emptyP.
(* FILL IN HERE *)
Recall what we said last time: Prop and bool are complementary: Prop allows robust natural
deduction, bool allows brute-force evaluation.
As you may guess, overusing inductively defined relations/propositions is not entirely in the spirit of ssreflect. Its design principle is to reflect such relations and propositions as recursive functions into booleans wherever possible. But it is not always possible, and one of the reasons has to do with differences between classical and constructive logic. Besides, while such functions are better suited for direct computations in Gallina, inductively defined propositions can often be better candidates for inductive proofs.
In fact, speaking of induction: with the Curry-Howard correspondence and its realization in Coq in
mind, we can now take a deeper look at induction principles.
Induction Principles
- Every time we declare a new Inductive datatype, Coq automatically generates an induction principle for this type.
- This induction principle is a theorem like any other: If t is defined inductively, the corresponding induction principle is called t_ind.
- Here is the one for natural numbers:
Check nat_ind.
(* ===> nat_ind :
forall P : nat -> Prop,
P 0 ->
(forall n : nat, P n -> P (S n)) ->
forall n : nat, P n *)
(* ===> nat_ind :
forall P : nat -> Prop,
P 0 ->
(forall n : nat, P n -> P (S n)) ->
forall n : nat, P n *)
- The induction tactic of plain Ltac is a straightforward wrapper that, at its core, simply performs apply t_ind. elim does more, but it does use t_ind.
- To see this more clearly, let's experiment with directly using apply nat_ind, instead of the induction tactic, to carry out some proofs.
- Here, for example, is an alternate proof of a theorem that we saw earlier.
Theorem mult_0_r' : ∀n:nat,
n * 0 = 0.
Proof.
by apply: nat_ind.
Qed.
n * 0 = 0.
Proof.
by apply: nat_ind.
Qed.
t_ind : ∀P : t → Prop,
... case for c1 ... →
... case for c2 ... → ...
... case for cn ... →
∀n : t, P n
... case for c1 ... →
... case for c2 ... → ...
... case for cn ... →
∀n : t, P n
Inductive yesno : Type :=
| yes : yesno
| no : yesno.
Check yesno_ind.
(* ===> yesno_ind : forall P : yesno -> Prop,
P yes ->
P no ->
forall y : yesno, P y *)
| yes : yesno
| no : yesno.
Check yesno_ind.
(* ===> yesno_ind : forall P : yesno -> Prop,
P yes ->
P no ->
forall y : yesno, P y *)
Exercise: 1 star, standard, optional (rgb)
Write out the induction principle that Coq will generate for the following datatype. Write down your answer on paper or type it into a comment, and then compare it with what Coq prints.
Inductive rgb : Type :=
| red : rgb
| green : rgb
| blue : rgb.
Check rgb_ind.
☐
| red : rgb
| green : rgb
| blue : rgb.
Check rgb_ind.
Inductive natlist : Type :=
| nnil : natlist
| ncons : nat → natlist → natlist.
Check natlist_ind.
(* ===> (Modulo a little variable renaming)
natlist_ind :
forall P : natlist -> Prop,
P nnil ->
(forall (n : nat) (l : natlist),
P l -> P (ncons n l)) ->
forall n : natlist, P n *)
| nnil : natlist
| ncons : nat → natlist → natlist.
Check natlist_ind.
(* ===> (Modulo a little variable renaming)
natlist_ind :
forall P : natlist -> Prop,
P nnil ->
(forall (n : nat) (l : natlist),
P l -> P (ncons n l)) ->
forall n : natlist, P n *)
Exercise: 1 star, standard, optional (natlist1)
Suppose we had written the above definition a little differently:
Inductive natlist1 : Type :=
| nnil1 : natlist1
| nsnoc1 : natlist1 → nat → natlist1.
| nnil1 : natlist1
| nsnoc1 : natlist1 → nat → natlist1.
Now what will the induction principle look like? ☐
From these examples, we can extract this general rule:
- The type declaration gives several constructors; each corresponds to one clause of the induction principle.
- Each constructor c takes argument types a1 ... an.
- Each ai can be either t (the datatype we are defining) or some other type s.
- The corresponding case of the induction principle says:
- "For all values x1...xn of types a1...an, if P holds for each of the inductive arguments (each xi of type t), then P holds for c x1 ... xn".
Exercise: 1 star, standard, optional (byntree_ind)
Write out the induction principle that Coq will generate for the following datatype. (Again, write down your answer on paper or type it into a comment, and then compare it with what Coq prints.)
Inductive byntree : Type :=
| bempty : byntree
| bleaf : yesno → byntree
| nbranch : yesno → byntree → byntree → byntree.
☐
| bempty : byntree
| bleaf : yesno → byntree
| nbranch : yesno → byntree → byntree → byntree.
Exercise: 1 star, standard, optional (ex_set)
Here is an induction principle for an inductively defined set.
ExSet_ind :
∀P : ExSet → Prop,
(∀b : bool, P (con1 b)) →
(∀(n : nat) (e : ExSet), P e → P (con2 n e)) →
∀e : ExSet, P e
Give an Inductive definition of ExSet:
∀P : ExSet → Prop,
(∀b : bool, P (con1 b)) →
(∀(n : nat) (e : ExSet), P e → P (con2 n e)) →
∀e : ExSet, P e
Inductive ExSet : Type :=
(* FILL IN HERE *)
.
☐
(* FILL IN HERE *)
.
Polymorphism
Inductive list (X:Type) : Type :=
| nil : list X
| cons : X → list X → list X.
is very similar to that of natlist. The main difference is
that, here, the whole definition is parameterized on a set X:
that is, we are defining a family of inductive types list X,
one for each X. (Note that, wherever list appears in the body
of the declaration, it is always applied to the parameter X.)
| nil : list X
| cons : X → list X → list X.
list_ind :
∀(X : Type) (P : list X → Prop),
P [] →
(∀(x : X) (l : list X), P l → P (x :: l)) →
∀l : list X, P l
Note that the whole induction principle is parameterized on
X. That is, list_ind can be thought of as a polymorphic
function that, when applied to a type X, gives us back an
induction principle specialized to the type list X.
∀(X : Type) (P : list X → Prop),
P [] →
(∀(x : X) (l : list X), P l → P (x :: l)) →
∀l : list X, P l
Exercise: 1 star, standard, optional (tree)
Write out the induction principle that Coq will generate for the following datatype. Compare your answer with what Coq prints.
Inductive tree (X:Type) : Type :=
| leaf : X → tree X
| node : tree X → tree X → tree X.
Check tree_ind.
☐
| leaf : X → tree X
| node : tree X → tree X → tree X.
Check tree_ind.
Exercises
Exercise: 1 star, standard, optional (mytype)
Find an inductive definition that gives rise to the following induction principle:
mytype_ind :
∀(X : Type) (P : mytype X → Prop),
(∀x : X, P (constr1 X x)) →
(∀n : nat, P (constr2 X n)) →
(∀m : mytype X, P m →
∀n : nat, P (constr3 X m n)) →
∀m : mytype X, P m
☐
∀(X : Type) (P : mytype X → Prop),
(∀x : X, P (constr1 X x)) →
(∀n : nat, P (constr2 X n)) →
(∀m : mytype X, P m →
∀n : nat, P (constr3 X m n)) →
∀m : mytype X, P m
Exercise: 1 star, standard, optional (foo)
Find an inductive definition that gives rise to the following induction principle:
foo_ind :
∀(X Y : Type) (P : foo X Y → Prop),
(∀x : X, P (bar X Y x)) →
(∀y : Y, P (baz X Y y)) →
(∀f1 : nat → foo X Y,
(∀n : nat, P (f1 n)) → P (quux X Y f1)) →
∀f2 : foo X Y, P f2
☐
∀(X Y : Type) (P : foo X Y → Prop),
(∀x : X, P (bar X Y x)) →
(∀y : Y, P (baz X Y y)) →
(∀f1 : nat → foo X Y,
(∀n : nat, P (f1 n)) → P (quux X Y f1)) →
∀f2 : foo X Y, P f2
Exercise: 1 star, standard, optional (foo')
Consider the following inductive definition:
Inductive foo' (X:Type) : Type :=
| C1 : list X → foo' X → foo' X
| C2 : foo' X.
| C1 : list X → foo' X → foo' X
| C2 : foo' X.
What induction principle will Coq generate for foo'? Fill
in the blanks, then check your answer with Coq.)
☐
foo'_ind :
∀(X : Type) (P : foo' X → Prop),
(∀(l : list X) (f : foo' X),
_______________________ →
_______________________ ) →
___________________________________________ →
∀f : foo' X, ________________________
∀(X : Type) (P : foo' X → Prop),
(∀(l : list X) (f : foo' X),
_______________________ →
_______________________ ) →
___________________________________________ →
∀f : foo' X, ________________________
- Interestingly, we can get induction to work with our self-written induction principles—provided we prove first these new induction principles do the job, of course!
- Some theorems can be proved slightly more conveniently this way...
Explicit Proof Objects for Induction
Check nat_ind.
(* ===>
nat_ind : forall P : nat -> Prop,
P 0 ->
(forall n : nat, P n -> P (S n)) ->
forall n : nat, P n *)
(* ===>
nat_ind : forall P : nat -> Prop,
P 0 ->
(forall n : nat, P n -> P (S n)) ->
forall n : nat, P n *)
There's nothing magic about this induction lemma: it's just
another Coq lemma that requires a proof. Coq generates the proof
automatically too...
Print nat_ind.
Print nat_rect.
(* ===> (after some manual inlining and tidying)
nat_ind =
fun (P : nat -> Prop)
(f : P 0)
(f0 : forall n : nat, P n -> P (S n)) =>
fix F (n : nat) : P n :=
match n with
| 0 => f
| S n0 => f0 n0 (F n0)
end.
*)
Print nat_rect.
(* ===> (after some manual inlining and tidying)
nat_ind =
fun (P : nat -> Prop)
(f : P 0)
(f0 : forall n : nat, P n -> P (S n)) =>
fix F (n : nat) : P n :=
match n with
| 0 => f
| S n0 => f0 n0 (F n0)
end.
*)
Note the use of inlined fix here.
We can read this as follows:
Suppose we have evidence f that P holds on 0, and
evidence f0 that ∀ n:nat, P n → P (S n).
Then we can prove that P holds of an arbitrary nat n via
a recursive function F. F pattern matches on n:
We can adapt this approach to proving nat_ind to help prove
non-standard induction principles too. Recall our definition of ev:
- If it finds 0, F uses f to show that P n holds.
- If it finds S n0, F applies itself recursively on n0 to obtain evidence that P n0 holds; then it applies f0 on that evidence to show that P (S n) holds.
Inductive ev : nat → Prop :=
| ev_0 : ev 0
| ev_SS : ∀n : nat, ev n → ev (S (S n)).
Recall also our desire to
prove that
∀ n : nat, even n → ev n.
Attempts to do this by standard induction on n fail, because the
induction principle only lets us proceed when we can prove that
even n → even (S n) — which is of course never provable. We could prove it by induction on evidence, we could also do a bit of a hack:
Theorem even__ev : ∀ n : nat,
(even n → ev n) ∧ (even (S n) → ev (S n)).
But we can make a much better proof by defining and proving a
non-standard induction principle that goes "by twos":
Definition nat_ind2 :
∀(P : nat → Prop),
P 0 →
P 1 →
(∀n : nat, P n → P (S(S n))) →
∀n : nat , P n :=
fun P ⇒ fun P0 ⇒ fun P1 ⇒ fun PSS ⇒
fix f (n:nat) := match n with
0 ⇒ P0
| 1 ⇒ P1
| S (S n') ⇒ PSS n' (f n')
end.
∀(P : nat → Prop),
P 0 →
P 1 →
(∀n : nat, P n → P (S(S n))) →
∀n : nat , P n :=
fun P ⇒ fun P0 ⇒ fun P1 ⇒ fun PSS ⇒
fix f (n:nat) := match n with
0 ⇒ P0
| 1 ⇒ P1
| S (S n') ⇒ PSS n' (f n')
end.
Again, note the use of inlined fix here.
Lemma even__ev' : ∀n, even n → ev n.
Proof.
move ⇒ n.
elim n using nat_ind2 ⇒ /= [Hev | |n' IHn' Hev].
<- da liegt der Hund begraben!
- apply ev_0.
- by case H': _ /.
- (* do you understand why Hev looks the way it does? *)
by apply ev_SS, IHn'.
Qed.
- by case H': _ /.
- (* do you understand why Hev looks the way it does? *)
by apply ev_SS, IHn'.
Qed.
Setoid Rewriting
- Finally, something which is quite orthogonal to ssreflect way of doing things, and contents of today's lecture ...
- Some of Coq's tactics treat iff statements specially, avoiding the need for some low-level proof-state manipulation.
- In particular, rewrite and some of its relatives can be used with iff statements, not just equalities. To enable this behavior, we need to import a Coq library that supports it:
Require Import Coq.Setoids.Setoid.
Here is a simple example demonstrating how these tactics work with
iff. First, let's use a couple of basic iff equivalences...
Check eq_mul_0.
(* => eq_mul_0
: forall n m : nat, n * m = 0 <-> n = 0 \/ m = 0 *)
Check or_assoc.
(* => eq_mul_0
: forall n m : nat, n * m = 0 <-> n = 0 \/ m = 0 *)
Check or_assoc.
We can now use these facts with rewrite and reflexivity to
give smooth proofs of statements involving equivalences. Here is
a ternary version of the previous mult_0 result:
Theorem mult_0_3 :
∀n m p, n * m * p = 0 ↔ n = 0 ∨ m = 0 ∨ p = 0.
Proof.
move ⇒ n m p.
rewrite !eq_mul_0. (* see what happened? And we finish the same way: *)
by rewrite or_assoc.
Qed.
∀n m p, n * m * p = 0 ↔ n = 0 ∨ m = 0 ∨ p = 0.
Proof.
move ⇒ n m p.
rewrite !eq_mul_0. (* see what happened? And we finish the same way: *)
by rewrite or_assoc.
Qed.
- "Setoid" is a set equipped with (well-behaved) equivalence relation.
- Uses of setoid rewriting go beyond equivalence in Prop.
- Esp. in ssreflect style, you often want to transform Prop equivalence to bool equivalence ...
Lemma apply_iff_example :
∀n m : nat, n * m = 0 → n = 0 ∨ m = 0.
Proof.
intros n m H. apply eq_mul_0. apply H.
Qed.
(* Sun Jul 14 22:07:54 MSK 2019 *)
∀n m : nat, n * m = 0 → n = 0 ∨ m = 0.
Proof.
intros n m H. apply eq_mul_0. apply H.
Qed.
(* Sun Jul 14 22:07:54 MSK 2019 *)


Experienced Software Test Engineer with a demonstrated history of working in the outsourcing/offshoring industry.
Skilled in Java, Selenium WebDriver, Maven, Git and SQL.
Strong quality assurance professional with a Master of Technology (M.Tech) focused in Information Systems and
Management from International School Of Information Management, Mysore.
| Operating Systems: | Windows 7/8/8.1/10, Linux Mint, Ubuntu |
| Programming: | Core JAVA |
| Database: | Oracle SQL |
| Web Development: | HTML, XML, CSS |
| Development Tools: | Eclipse IDE, JetBrains IntelliJ IDEA, Oracle SQL Developer |
| Testing Tools: |
Selenium WebDriver, Selenide, Cucumber,JMeter(Performance Testing)
Postman, SoapUI, Rest Assured, Serenity
|
| Testing Framework: | TestNG, JUnit |
| Bug Tracking: | JIRA |
| CI: | Jenkins, JetBrains Teamcity |
| Dependency Management: | Maven |
| Version Control: | Git |
| Others: | SDLC, STLC, AGILE Methodology, Atlassian Confluence |


Featured
Hot Deal
From $140
Rutherglen
Bed and Breakfasts
Rutherglen
Bed and Breakfasts
Rutherglen
Bed and Breakfasts
Featured
Hot Deal
From $140
Rutherglen
Bed and Breakfasts
Rutherglen
Bed and Breakfasts
Rutherglen
Bed and Breakfasts
Featured
Hot Deal
From $140
Rutherglen
Bed and Breakfasts
Rutherglen
Bed and Breakfasts
Rutherglen
Bed and Breakfasts
Featured
Hot Deal
From $140
Rutherglen
Bed and Breakfasts
Rutherglen
Bed and Breakfasts
Rutherglen
Bed and Breakfasts


As members we hold meetings to discuss our current and future projects, also to touch bases with other members and provide feedback about things going on in the district.
Once a month we meet with the KSD ITL (IT Leaders) to provide feedback about projects that are going on and discuss future initiatives.
Kent School District students use technology to learn new skills to prepare for their future every day. Our classrooms are places where students are able to try new ways to learn important concepts and, more importantly, college and career skills. Students in the One-to-One Laptop Program have access to 21st Century learning anytime, from anywhere.
Kent School District’s annual Technology Expo showcases how students gain college and career skills through classroom projects using technology tools. At the event, students and teachers will demonstrate technology in use, speak about what they have learned, and ask attendees to get involved by solving a problem, completing a task, building a device, and much more. Members of the STEP Team assist with the organization and assembly of the event. Members also host a booth for the STEP Team and VisFest showcasing what we do.
This event also highlights local businesses and organizations who support and use technology. These business sponsors and exhibitors help demonstrate the connection between classrooms and careers.
Find out more at: www.kenttechexpo.org
Since 2002, the Kent School District together with the STEP Team has hosted the VisFest Annual Visual Literacy Arts Festival. Through the years, VisFest has provided thousands of Kent area students an outlet to display their creative and artistic visual literacy talents to a wide audience of fellow students, teachers, and members of the community.
We play several roles in this event ranging from judging and scoring the entries to managing and hosting the Awards Ceremony. Currently, VisFest includes a Film Festival and a Video Game Expo.
Find out more at: www.visfest.org
There are four components to the STAR Initiative: Student, Technology, Access, and Resources. In order to achieve the Kent School District mission of preparing each and every student for a successful future, students must have technology, they must have online access, and they must have a variety of digital resources that support instruction and learning. Leveling the playing field by providing technology, access, and resources for all students is a critical component for increasing student achievement.
The STEP Team is involved in most of the STAR program but most directly in managing the Technology component. In an effort to bridge the “digital divide” among Kent School District students, STAR Laptop Grant Program, formerly known as Bridging the Gap, grants refurbished laptops to qualified families among our student population.
Find out more at: www.ksdstar.org
STEP Leaders present, participate, support, and volunteer at major conferences and events such as:
STEP Leaders go out to KSD schools to assist teachers and students with media projects. We help teach software such as:


Opening: April 18, 1988
Architectural design: Teotónio Pereira and Pedro Botelho
Art work: António Dacosta and Pedro Morais
Platform length: 105 m
Code: CS
Wikipedia page


HOME
ABOUT US
MEETINGS
CONTACT
NOTEBOOK SWAP
Fridays 3-4PM @ Murray Hall Room 111
What kind of
art and design?
Drawing
Ink and Graphite
Visual Art
Painting and Photography
Graphic Design
Photoshop and Illustrator
Web Design
HTML/CSS and Bootstrap
Visit Us
Fridays 3-4PM
Murray Hall Room 112
<
Follow us
@radrut


Beats Studio3 Wireless
Experience your music like never before.
$299.95
$60 Apple Music gift card with purchase of select Beats products.*
Portable Wireless Speaker
Beats Pill+
Available Colors
Find your Color
$299.95
$60 Apple Music gift card with purchase of select Beats products.*
Totally wireless high-performance earphones
POWERBEATS PRO
Up to 9 hours of listening time
Apple H1 Chip & Class 1 Wireless Bluetooth®
Sweat & water resistant
Adjustable, secure-fit earhooks
$199.95
$60 Apple Music gift card with purchase of select Beats products.*
Talk. Listen. Beats.
Beatsˣ
Up to 8 hours of battery life With Fast Fuel, a 5-minute charge = 2 hours of playback Sweat & water resistant Apple W1 Chip & Class 1 Wireless Bluetooth®
$299.95


--- layout: post title: "设计了一个Mysql数据库" date: 2017-03-20 14:42:35 image: '/assets/img/' description: "" tags: - categories: - SQL ---


[gecode-users] Question: stop during a search
Chuong
chuongdk at gmail.com
Mon Mar 26 16:14:54 CEST 2012
Hi all,
I have a question about stop during a search.
Is is possible to stop during a search before fixing all variables?
For example:
I have 4 variables a, b, c, d with domain of [0,1].
After fixing a=0, b=0, I can detect that I have solutions of every combinations
of c and d.
So it is not effective to branch in c and d (the propagation take more time
than counting combinations).
Is it possible to stop the search at this point and change to a=0, b=1
(not a=0, b=0, c=0).
Thank you in advance.
Best regards,
Chuong
More information about the users
mailing list


Propertylistmap name is required.
property Address is required.
City required.
property unit is required.
Number of bedrooms is required.
Price required.


Chloe Lewis shows off incredible post-baby body transformation in scanty crop top
New mum Chloe took a night off her parenting duties when she flaunted her enviably-toned figure on the town
by Lily Waddell, https://www.mirror.co.uk/authors/lily-waddell/Chloe Lewis stunned fans with her post-baby body transformation.
Her Instagram post almost marks a month since she welcomed her son into the world on October 13, yet Chloe has already snapped back into shape.
The new mum, who credited pilates training for her weight loss, proudly flaunted her astonishing figure for all to see on the gram.
In her latest snap, the reality star exhibited her enviably-toned physique in a lace crop top with a scalloped edge drawing attention to her bare stomach.

The mum-of-one had done up her caramel-coloured tresses in springy curls and pulled on her heels.

Chloe added the applause emoji to her caption.

She is yet to reveal her son's name.
Previously, Chloe shared her weight loss secrets as she praised her pilates class.

"(Big thank you to @zerogravitypilates for helping my bod bounce back with all the training I did before & while pregnant)."


The vet and his awesome team
Dr Neralla Sridhar
M.V.Sc(Surgery), MISVS, MIAEP
Chief Veterinary Surgeon
Dr Sridhar has 15 years of experience as Veterinary Surgeon and has worked with different organizations all over the world.
His career started as a teaching associate for postgraduate students in the city of Bangalore. He then relocated to Bahrain, where he was providing expert consultation for the large stud farms with horses and other livestock. After a four year stint, he eventually went on to work at Saudi Arabia where he was actively involved in the treatment and surgeries for the small animals.
He returned to India to work for the Royal Turf Club in Kolkatta offering treatments and surgeries for the race horses stationed in the club.
Despite all this experience, his true calling came when he set up his own pet clinic in the city of destiny. He has been instrumental in bringing Pawsandtails the glory it has earned today.
He says “ My mission in life is not merely to survive, but to thrive; and to do so with some passion, some compassion, some humor, and some style. …”. Thats Doctor Sridhar who lives with his beautiful wife and lovely daughter in the coastal city of Visakhapatnam.


Pilot Garden Clothing Company
Products
New Releases
Essentials
Customs
Archived
FaQ
Contact
Pilot Garden Clothing Company
Shop


Input an IPv6 address and the subnet size in slash notation:
| Compressed Address: | |
| Expanded Address: | |
| Prefix: | |
| Range: | |
| Number of /64s: |
Select a number of subnets or a subnet size to divide the above into:
subnets or
This calculator can be used for IPv6 in the same way VLSM is used to plan an IPv4 network.
Remember, the size of IPv6 can be huge. This calculator can crash your browser if you attempt to have it calculate billions of subnets!
Because of this, only the first 999 subnets are displayed.
Use the above calculator to plan your IPv6 networks. Because of the huge size of IPv6, we do not care about the number of hosts in a network. Remember, that the smallest recommended subnet is a /64.


Indian Institute of Technology Palakkad
UNNAT BHARAT ABHIYAN
Home
About Us
Activities
As Regional Co-ordinating Institute
As Participating Institute
Important Links
Regional Participating Institutes
Gallery
Contact Us
Gallery
Plastic Free Village Campaign
Student Solar Ambassador Workshop
Pale Blue Dot I- IIT Palakkad Public Lecture Series
Pale Blue Dot III- IIT Palakkad Public Lecture Series
Smart Farm Project
World Environment Day 2020 - Sapling Plantation


Choose an icon for the rating scale
Average user rating
Show average rating to user:
Yes
No
Number of users who rated the app
Show number of ratings to user:
Yes
No


{{ goal?.name }}
will be added to your goals
-
By accepting this, you are granting permission to
{{ goal?.sharedBy?.name }}
to track your progress for this goal.
-
You have already added this goal earlier. Your earlier goal will be
deleted to prevent duplicates.
- You will not be able to edit or delete this goal.
-
Target completion date :
{{ goal?.duration}}
day(s) from now.
Do you want to continue?
Accepting goal
{{ goal?.name }}


{% extends "dashboard/main.html" %} {% block content %} {% comment %} Should turn this into a FormWizard or something... {% endcomment %}
Initializing {{ dashboard }}
(Models with more objects than others are pre-selected)


Stray Kids Reveal Their Lightstick
by greenbaypackersStray Kidshas unveiled their official light stick!
On November 16, Stray Kids’s official Twitter account revealed the design of the beautiful light stick. It features a “compass without direction” and the words “You make Stray Kids stay” as a sweet message to Stray Kids’s fans Stays.
The hashtags that were included with the official light stick include “District 9 Unlock,” “You make Stray Kids stay,” and “No matter what the direction, I will find my dream, believe, and walk Going.”
According to the announcement, the light stick will become available on November 23.


THE CIDER HOUSE RULES A film review by Christopher Null Copyright 1999 filmcritic.com filmcritic.com
I went into THE CIDER HOUSE RULES with a blank slate, knowing nothing about the movie at all.
I didn't even know how to pronounce the title. It could've been "The cider house-rules," meaning "This is the cider house, and these are the rules." Or it could've been "The cider house *rules*!"
Wiser readers have probably already figured out that the former is correct, and while this isn't a movie about a bunch of rules, it comes awfully close. Based on John Irving's novel (he also wrote the script), CIDER HOUSE has that "adapted from the book" feeling -- like the writer didn't want to edit out any of the chaff because it was all too precious.
Well, CIDER HOUSE is a sloppy mess because of it. We start with the 1930/1940's childhood of main character Homer (Maguire), his adolescence in a remote Maine orphanage, his apprenticeship to the orphanage's OB/GYN and abortionist Doctor Larch (Caine), his infatuation with a patient who comes in for services (Theron), his decision to become an apple picker, and... okay, are you bored yet?
Try as I might, I can't even make it sound interesting, much less exciting. How this book became a film is beyond me. Obviously searching to recreate the magic of introspective period dramas like THE ICE STORM and DEAD POETS SOCIETY, THE CIDER HOUSE RULES is an exceedingly poor imitation that just doesn't work, mainly because nothing happens in its two-plus hours.
To enjoy the film at all, you'll need to take pleasure in the details. Maguire is typically excellent as the brooding Homer. Caine, doing his first American accent, is surprisingly effective as Homer's counterpoint. The supporting cast is uniformly good, excepting the inexplicably cast musician Erykah Badu. As a character study, CIDER HOUSE is mild entertainment, but it's not enough to merit recommending the film.
THE CIDER HOUSE RULES, you'll be interested to know, represents a 13 year struggle to make it to the big screen. Oh, how you feel that.
RATING: **1/2
|------------------------------| \ ***** Perfection \ \ **** Good, memorable film \ \ *** Average, hits and misses \ \ ** Sub-par on many levels \ \ * Unquestionably awful \ |------------------------------|
MPAA Rating: PG-13
Director: Lasse Hallstrom Producer: Richard N. Gladstein Writer: John Irving Starring: Tobey Maguire, Charlize Theron, Delroy Lindo, Paul Rudd, Michael Caine
http://www.miramax.com/mm_front/owa/mp.entryPoint?action=0&midStr=1312
--- Christopher Null -<EMAIL_ADDRESS>- http://www.filmcritic.com
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Aborts a job after the writes fail.
Aborts a job after the writes fail. Must be called on the driver.
Calling this function is a best-effort attempt, because it is possible that the driver just crashes (or killed) before it can call abort.
Aborts a task after the writes have failed.
Aborts a task after the writes have failed. Must be called on the executors when running tasks.
Calling this function is a best-effort attempt, because it is possible that the executor just crashes (or killed) before it can call abort.
Commits a job after the writes succeed.
Commits a job after the writes succeed. Must be called on the driver.
Commits a task after the writes succeed.
Commits a task after the writes succeed. Must be called on the executors when running tasks.
Specifies that a file should be deleted with the commit of this job.
Specifies that a file should be deleted with the commit of this job. The default implementation deletes the file immediately.
Notifies the commit protocol to add a new file, and gets back the full path that should be used.
Notifies the commit protocol to add a new file, and gets back the full path that should be used. Must be called on the executors when running tasks.
Note that the returned temp file may have an arbitrary path. The commit protocol only promises that the file will be at the location specified by the arguments after job commit.
A full file path consists of the following parts:
The "dir" parameter specifies 2, and "ext" parameter specifies both 4 and 5, and the rest are left to the commit protocol implementation to decide.
Important: it is the caller's responsibility to add uniquely identifying content to "ext" if a task is going to write out multiple files to the same dir. The file commit protocol only guarantees that files written by different tasks will not conflict.
Similar to newTaskTempFile(), but allows files to committed to an absolute output location.
Similar to newTaskTempFile(), but allows files to committed to an absolute output location. Depending on the implementation, there may be weaker guarantees around adding files this way.
Important: it is the caller's responsibility to add uniquely identifying content to "ext" if a task is going to write out multiple files to the same dir. The file commit protocol only guarantees that files written by different tasks will not conflict.
Called on the driver after a task commits.
Called on the driver after a task commits. This can be used to access task commit messages before the job has finished. These same task commit messages will be passed to commitJob() if the entire job succeeds.
Setups up a job.
Setups up a job. Must be called on the driver before any other methods can be invoked.
Sets up a task within a job.
Sets up a task within a job. Must be called before any other task related methods can be invoked.
An FileCommitProtocol implementation backed by an underlying Hadoop OutputCommitter (from the old mapred API).
Unlike Hadoop's OutputCommitter, this implementation is serializable.


--- project-id: 5 title: Global iodine levels set to reach record high by 2050, threaten ozone layer type: data journalism tag: journalism date: 1000-01-09 img: grid-image.png alt: area chart showing iodine levels rising over time description: The amount of iodine in the atmosphere has tripled between 1950 and 2010. ---
{% include head.html %} {% include js.html %} {% include stylesheets.html %} {% include nav.html dark_mode='med-dark-mode' light_shadow_style='color: #c5c5c5;' %}Iodine, a major contributor to ozone depletion, has tripled in the atmosphere between 1950 and 2010, according to studies by the National Center for Atmospheric Research.
Iodine is well-documented in its ability to destroy ozone. Until recently, it was regarded as a useful tool to weaken the ozone closest to the earth's surface (tropospheric ozone), which is a key component of smog. The problem is that what goes on in the troposphere doesn't stay in the troposphere, which means some of this iodine escapes up to the 'good' ozone (stratospheric ozone, which forms the ozone layer). A 2020 experiment at the University of Colorado Boulder showed that iodine processes could account for over 30% of the ozone loss in the lower stratosphere. Iodine also increases the lifetime of greenhouse gases like methane by gobbling up the free radicals that would have otherwise absorbed them.
Even as the ozone layer shows signs of recovery in the upper stratosphere, ozone in the lower stratosphere continues to decline. This is despite the success of the 2016 Montreal Protocol – iodine levels were so low at the time that they were not considered for regulation. Scientists at the Spanish National Research Council (CSIC) now believe that iodine emissions are one of the largest contributors to atmospheric ozone depletion.
The main sources of iodine are marine life and human emissions. NASA has found that Arctic sea ice extent has been shrinking by 12.6% every ten years since 1979. With this increased sea surface area, the number of underwater plankton and algae that emit organic iodine had been increasing as well. And when large waves break on the shore? Sea sprays are hotbeds for this iodine to be released into the atmosphere.
A 2022 study at CSIC identified two key measurements that preceded the highest-ever iodine levels 130,000 years ago:
On top of that, non-oceanic (inorganic) iodine levels were negligible 130,000 years ago. Inorganic iodine now accounts for approximately 75% of the total iodine in the atmosphere due to the significant rise in human emissions. Left unmitigated, the planet's iodine levels could soon surpass all recorded measurements.
Methodology
Data is from the supplementary sections of these two papers: Rapid increase in atmospheric iodine levels in the North Atlantic since the mid-20th century and The influence of iodine on the Antarctic stratospheric ozone hole. Validated and examined in Jupyter notebook. Plotted the heatmaps using plotly-calplot in Python. Plotted the area chart using Rawgraphs and polished it in Figma.
Data journalism project for the Lede Program at Columbia.
Project Type: {{ page.type }}
Role: data collection, data analysis, data visualization
Tools: Python(Jupyter) for scraping and analysis. Plotly, Rawgraphs, and Figma for graphics
Date: July 2023
Sources: Rapid increase in atmospheric iodine levels in the North Atlantic since the mid-20th century, The influence of iodine on the Antarctic stratospheric ozone hole
Code: GitHub


When clicked, your display ads will direct users to a landing page created
by
us. This landing page is designed to be fully optimised and will include information
about
your business, promotion or offer and include contact details.
We are able to track all activity on this page, which will be included in your
report.


Personal academic website
I am Senior Lecturer of Digital Marketing in the School of Business & Management, RMIT University (Saigon South Campus, Vietnam).
Prior to joining the School of Business & Management, I have been Lecturer of Information Technology in the School of Science & Technology for three years, where I taught courses in computer science areas such as data science & machine learning, data structures & algorithms, user-centered design, and technology leadership.
During this time, I was also Senior Program Manager for two undergraduate programs, Bachelor of Engineering (Software Engineering) (Honours) and Bachelor of Information Technology.
I completed my Ph.D. (Business Information Systems) degree at RMIT University (Australia) in May 2018, under the co-supervision by Dr. Siddhi Pittayachawan, Dr. Vince Bruno, and Professor Karlheinz Kautz.
My teaching and research interests focus on the following areas:
- cybersecurity management & behaviors
- digital business & digital transformation
- data analytics for business and education
- human-centered artificial intelligence
My research projects employed both quantitative and qualitative methods, and I am especially interested in social network analysis methods, and action research and design science approaches.
In 2016, I was awarded the RMIT Prize for Research Impact (Enterprise category), which recognized my active engagement with the industry through conducting research. Since 2018, I have received various research and teaching awards at RMIT University.
I always seek strong Ph.D. candidates who would like to do research in the areas listed above. Please find information about the Ph.D. programs and relevant contacts for further enquiries on this webpage.
I am a member of the following associations:


Ombudsman Exposition - Jeff Sonstein
Ombudsman Candidates
a brief bio follows, and more info may be found at:
http://ariadne.newcollege.edu/Personal/resume.html
----------
I have been involved in the VRML effort since before there were browsers
I wrote chapter 20 ("What Is VRML") in Matsuba and Roehl's book "Special
Edition Using VRML" (Que)
I began working with a computer in the early-1970s. It was an IBM 360, and
used punched-cards (%$#^% pieces of cardboard)
I bought my first "personal computer" in the mid-1970s. It was an 8080-based
CP/M (v1.4) machine with 48k of memory, a 300-baud *direct-connect* [gasp]
modem, and had a couple of single-sided floppies
I have mostly programmed in Pascal, C [ugh], Modula-2, and Oberon-2
My favorite renderer is PoV-Ray
My favorite text editor is PFE
Some examples of my work in and about VRML may be found at (and "below"):
http://www.newcollege.edu/vrmLab/
I am, by training, a psychotherapist


Fraud Detection Demo
Set Refresh
Every second
Every 5 seconds
Every 10 seconds
Pause
on Github
Powered By VoltDB
Fraud Accounts
Account
Transactions


Portfolio: bryan.nonni.io | Email<EMAIL_ADDRESS>| Twitter: @nonni_io
LinkedIn: linkedin.com/in/bryanwnonni | Telegram: t.me/nonni_io
GH: github.com/bnonni | NCR GH: github.com/bn185068
|
SKILLS |
Languages/Frameworks: Bash • JavaScript
• TypeScript • NodeJS • Python •
ReactJS • React-Native • Angular
Decentralized
Tech: Bitcoin Core •
LND •
CLN • Polar • DID/SSI • Web5
Cloud, DevOps & DB: SQL • Postgres • Mongo • Docker • Git • DigitalOcean • GCP • AWS • Nginx
|
EXPERIENCE |
LibertyPay, NCR | Atlanta, GA | Feb 2022 – Present | Software Engineer II
• Sister company to LibertyX – acquired by NCR in 2022
• Maintaining and evolving features for the LibertyPay production web app
• Developing API integrations between LibertyPay app and multiple major currency exchanges (dlocal, nium, banco popular)
• Enabling remittances for the LibertyPay application from the US to 3 new countries (portugal, guatemala, dominican republic)
• Leading integration of Pax debit terminals
(JetPay) with the LibertyPay app to accept debit payments in stores for remittances
• Leading build out of react-native mobile app to integrate
with NCR pay360 & sell direct to consumer (B2C)
• Completing backlog tickets to fix bugs, create new features and evolve the platform to help customer support team
NCR, Innovation Lab | Atlanta, GA | Feb 2020 – Feb 2022 | Software Engineer I, Tech Lead (DLT)
• Research: Bitcoin, Lightning Network, Ethereum, NFTs, DeFi protocols, Decentralized Identity, SSI, Web5
• Development: SSI Services API, Decentralized Buy
Now Pay Later, NCR Coin, Lightning PoS
• Led
intern team building SSI credential issuer API & credential wallet system – went to
pre-production
• Led Strike API integration to NCR Point-of-Sale demoing lightning payments internally (Global HQ Store)
• Won 2021 Hackathon with idea for a decentralized buy now, pay later system Point-of-Sale integration
• Winning hackathon idea provides NCR customers with access to $25MM Buy Now, Pay Later market
• Led development of NCR Coin (eth testnet) for hackathon gamification – custodial wallet service, token, NFTs
• Produced several patent-pending ideas in DLT (Blockchain, Cryptocurrency, Decentralized Identity)
• Led DLT in: research & dev, recruiting interns & FTEs and NCR Crypto Meetups for internal education
|
INTELLECTUAL PROPERTY |
1. Self-Sovereign Identity Verifiable Credentials for Consent Processing. No. 17/162,663, January 29, 2021.
2. Interfaces and Techniques for Secure Transaction Funding. No. 17/488,828, September 29, 2021.
3. Personal Identifiable Information Verification for Decentralized Network Services. No. 17/725,682, April, 21, 2022.
4. Self-Sovereign Identity Structured Messaging for Cross Channel Authentication. No. 17/162,663, April 28, 2022
|
COMMUNITY INVOLVEMENT / OPEN SOURCE / HACKATHONS |
Terminus Electric Money Laboratory (Terminus Labs) | Co-Founder | Atlanta, GA |
July 2022 – Present | terminus.money
• Atlanta Bitcoin Coworking space focused on community education and proliferation of
Bitcoin & the Lightning Network
• Open source software project – Lightning App Template: create-ln-app.dev
Atlanta BitDevs | Assistant Co-Organizer | Atlanta,
GA | July 2022 – Present | atlantabitdevs.org
• Assisting with content, planning
& hosting for monthly Socratic Seminars & leading bi-weekly technical reading groups
The Atlanta Bitcoin (TAB) Conference | Co-Organizer | Atlanta, GA |
July 2022 – October 2022
• Assisting with web development & social media content for TAB Conference
Bryan W Nonni, LLC | Owner | Atlanta, GA | February 2017 – July 2022
• Front
End Web Dev & server admin • bnhlegal.com, coastalhydrationtherapy.com, coastalhealthandvitality.com
BOLT.FUN Shock The Web Hackathon |
bolt.fun/hackathons/shock-the-web
• Online
hackathon • 1st
Place • Project: Arion
Parking, github.com/atlantabitdevs/park-lightning
PlebFi Miami 2022 Hackathon |
pleb.fi/miami2022
• Satellite event to BTC 2022 • 2nd Place •
Project: TreePay UX, github.com/atlantabitdevs/treepay-ux
MIT Bitcoin Expo 2022 | Remote | mitbitcoin.devpost.com
• Did not place • Project: Cete, helps families manage their finances on bitcoin: https://github.com/atlantabitdevs/family-btc
BTC++ Conference Hackathon | Austin, TX | btcplusplus.dev
• Best Use
of Core LN • Project: Terminus Pay, github.com/atlantabitdevs/terminus-pay-server
|
EDUCATION & CERTIFICATIONS |
B.S. Computer Science | GEORGIA STATE UNIVERSITY | December 2019 | 4.0 GPA Summa Cum Laude
B.A. Communications | UNIVERSITY OF GEORGIA | August 2014 | 3.0 GPA
GENERAL ASSEMBLY | JavaScript Development | Fall 2016 | 11 Week, Part Time Course
GENERAL ASSEMBLY | Front End Development | Summer 2016 | 11 Week, Part Time Course
|
OTHER PAST EXPERIENCE |
Trilogy Education & Georgia Tech | Atlanta, GA | January 2019 – May
2019 | Tutor
& Teaching Assistant
CloudTags | Atlanta, GA | January 2018 – January 2019 | Software Engineering
Intern
360i | Atlanta, GA | March 2016 – January 2019 | Media Manager – Tech Lead – Web Developer (A/B Testing)
mRelevance | Cartersville, GA | January 2015 – 2016 | Account Associate – Social Media Manager
360 Media | Atlanta, GA | September – December 2014 | PR Intern


|
Who's
Got My Back
(Tremonti/Stapp) |
|
Run
hide
All that was sacred to us Sacred to us See the signs The covenant has been broken By mankind Leaving us with no shoulder with no shoulder To rest our head on To rest our head on To rest our head on Whos got my back now? When all we have left is deceptive So disconnected So what is the truth now? Theres still time All that has been devastated Can be recreated Realize We pick up the broken pieces Of our lives Giving ourselves to each other ourselves to each other To rest our head on To rest our head on To rest our head on Whos got my back now? When all we have left is deceptive So disconnected So what is the truth now? Tell me the truth now Tell us the truth now Whos got my back now? When all we have left is deceptive So disconnected So what is the truth now? |
|
|


fun clear(): AsciiPanelView
Clear the entire screen to whatever the default background color is.
Return
this for convenient chaining of method calls
fun clear(character: Char): AsciiPanelView
Clear the entire screen with the specified character and whatever the default foreground and background colors are.
character
- the character to write
Return
this for convenient chaining of method calls
fun clear(character: Char, charColor: Int, bgColor: Int): AsciiPanelView
Clear the entire screen with the specified character and whatever the specified foreground and background colors are.
character
- the character to write
charColor
- the foreground color or null to use the default
bgColor
- the background color or null to use the default
Return
this for convenient chaining of method calls


|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.newdawn.slick.tiled.Layer
public class Layer
A layer of tiles on the map
| Field Summary | |
|---|---|
int[][][] |
data
The tile data representing this data, index 0 = tileset, index 1 = tile id |
int |
height
The height of this layer |
int |
index
The index of this layer |
java.lang.String |
name
The name of this layer - read from the XML |
float |
opacity
The opacity of this layer (range 0 to 1) |
java.util.Properties |
props
the properties of this layer |
boolean |
visible
The visibility of this layer |
int |
width
The width of this layer |
| Constructor Summary | |
|---|---|
Layer(TiledMap map,
org.w3c.dom.Element element)
Create a new layer based on the XML definition |
| Method Summary | |
|---|---|
int |
getTileID(int x,
int y)
Get the gloal ID of the tile at the specified location in this layer |
java.util.ArrayList<Tile> |
getTiles()
Gets all Tiles from this layer, formatted into Tile objects Can only be used if the layer was loaded using TiledMapPlus |
java.util.ArrayList<Tile> |
getTilesOfTileset(java.lang.String tilesetName)
Get all tiles from this layer that are part of a tileset Can only be used if the layer was loaded using TiledMapPlus |
boolean |
isTileOfTileset(int x,
int y,
java.lang.String tilesetName)
Returns true if this tile is part of that tileset Can only be used if the layer was loaded using TiledMapPlus |
protected void |
readData(java.io.InputStream is)
For reading decompressed, decoded Layer data into this layer |
void |
removeTile(int x,
int y)
Removes a tile |
void |
render(int x,
int y,
int sx,
int sy,
int width,
int ty,
boolean lineByLine,
int mapTileWidth,
int mapTileHeight)
Render a section of this layer |
void |
setTile(int x,
int y,
int tileOffset,
java.lang.String tilesetName)
Sets a tile's tileSet Can only be used if the layer was loaded using TiledMapPlus |
void |
setTileID(int x,
int y,
int tile)
Set the global tile ID at a specified location |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
public int index
public java.lang.String name
public int[][][] data
public int width
public int height
public float opacity
public boolean visible
public java.util.Properties props
| Constructor Detail |
|---|
public Layer(TiledMap map, org.w3c.dom.Element element) throws SlickException
element
- The XML element describing the layermap
- The map this layer is part of
SlickException
- Indicates a failure to parse the XML layer| Method Detail |
|---|
protected void readData(java.io.InputStream is)
is
- public int getTileID(int x, int y)
x
- The x coorindate of the tiley
- The y coorindate of the tile
public void setTileID(int x, int y, int tile)
x
- The x location to sety
- The y location to settile
- The tile value to setpublic void render(int x, int y, int sx, int sy, int width, int ty, boolean lineByLine, int mapTileWidth, int mapTileHeight)
x
- The x location to render aty
- The y location to render atsx
- The x tile location to start renderingsy
- The y tile location to start renderingwidth
- The number of tiles across to renderty
- The line of tiles to renderlineByLine
- True if we should render line by line, i.e. giving us a chance
to render something else between linesmapTileWidth
- the tile width specified in the map filemapTileHeight
- the tile height specified in the map filepublic java.util.ArrayList<Tile> getTiles() throws SlickException
SlickException
public java.util.ArrayList<Tile> getTilesOfTileset(java.lang.String tilesetName) throws SlickException
tilesetName
- The name of the tileset that the tiles are part of
SlickException
public void removeTile(int x, int y)
x
- Tile Xy
- Tile Ypublic void setTile(int x, int y, int tileOffset, java.lang.String tilesetName) throws SlickException
x
- Tile Xy
- Tile YtileOffset
- The offset of the tile, within the tileSet to set this tile
to, ordered in rowstilesetName
- The name of the tileset to set the tile to
SlickException
public boolean isTileOfTileset(int x, int y, java.lang.String tilesetName) throws SlickException
x
- The x co-ordinate of the tiley
- The y co-ordinate of the tiletilesetName
- The name of the tileset, to check if the tile is part of
SlickException
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


need help!!!....not really
this is a web page designed for helping me through the course. i am using this mode because this is the simplest way this could be done. this nowhere shows my interest in web development or in other words any kind of development. and if you see a 'k' missing anywhere fuck it!!!


Gateway
BOT
09-Sep-19 01:38 AM
"any chain with taddr can be dust attacked" -jl777c
Pirate $ARRR @PirateChain https://t.co/F4Y3MGydfE #privacycoin $XMR $ZEC $BTC
[telegram] <hansiharjunharja> What is a dust attack and taddr?
[telegram] <hansiharjunharja> I assume taddr is Trans Action Directory Dominating Republican, but i'm not 100% sure.
And in ARRR we only use zaddr. That i know. It is Zorro Anime Ding Dong Roarrrr.
[telegram] <Acura360> Tadrr = transparent adress / public adresses (re @hansiharjunharja: I assume taddr is Trans Action Directory Dominating Republican, but i'm not 100% sure.
And in ARRR we only use zaddr. That i know. It is Zorro Anime Ding Dong Roarrrr.)
[telegram] <hansiharjunharja> Nice. So in this case it means that one can convert this LTC to BNB, and better not transfer the LTC.
It would be wise for binance to list arrr.
[telegram] <EPIDEMIC_media> Any updates on the Atomic Dex iOS listing?
[telegram] <Vollka_Racho> In a few days. (re @EPIDEMIC_media: Any updates on the Atomic Dex iOS listing?)
[telegram] <Deliriumigniter> Watch out, he already got a few people!
[telegram] <Regnar> Remember everyone, if someone offers you a deal here through escrow, it's a scam.  They likely made another account and named it and use the same profile icon like one of the admins to trick you.
Do NOT trade with people here. They will say "Crypto is illegal in my country" etc, Do NOT trade with them. They are lying to you to steal your money.
[telegram] <RandomRich> (re @Regnar: Remember everyone, if someone offers you a deal here through escrow, it's a scam.  They likely made another account and named it and use the same profile icon like one of the admins to trick you.
Do NOT trade with people here. They will say "Crypto is illegal in my country" etc, Do NOT trade with them. They are lying to you to steal your money.)
[telegram] <RandomRich> That Van guys in every chat
[telegram] <Regnar> People come in all the time with the same old scam, offering to sell KMD for half the price, saying they are banned from trading in their country, has an escrow to do the trade, and the escrow is an admin here (really just them with fake account)
[telegram] <Regnar> If it's too good to be true, it probably is
[telegram] <Regnar> Btw, I started learning how to program because of Komodo. I saw so many opportunities to grow in a new industry and Komodo has an insane amount of tools available to use. My most recent project, working on the GUI for the nSPV wallet written in Python including Tor support!
[telegram] <hansiharjunharja> Nice!
[telegram] <Regnar> (re @hansiharjunharja: Nice!)
[telegram] <Regnar> I figured if I had a good idea, I could make suggestions to the team, or I could start doing. We need more community members to step up, explore some coding, think of some ideas they'd like to see happen :D
[telegram] <Regnar> The wallet functionality was built by TonyL, I just started redesigning the look of it, and recently started adding price calculations, multiple fiat currency support, Tor, an address book etc. Gotta thank Hush and Duke Leto, he even gave me a bounty :D
[telegram] <FtrSaroth> Excellent
[telegram] <Regnar> I'd love to see our community getting more active and building things or contributing ideas. There's also in development a "Komodo Coin Cap" project looking for some help too
[telegram] <polycryptoblog> For the less coding inclined there is an ambassador program. https://twitter.com/komodopioneers/status/1168490118191157248?s=21
Komodo had its first meetup on the continent of Africa!
It was organized by a group of students on the Kampala International University in Uganda.
@kiu_ug @KomodoPlatform $kmd #blockchain #meetup
[telegram] <hansiharjunharja> What did you do before you started learning coding? (re @Regnar: Btw, I started learning how to program because of Komodo. I saw so many opportunities to grow in a new industry and Komodo has an insane amount of tools available to use. My most recent project, working on the GUI for the nSPV wallet written in Python including Tor support!)
[telegram] <Regnar> Also it appears smk762 is hosting a demo of it on his website, worth checking out
http://dragonhound.info/
[telegram] <Regnar> I am coding in my free time, in fact I have a full time job, I volunteer here being an admin in this channel and helping on discord. (re @hansiharjunharja: What did you do before you started learning coding?)
[telegram] <Regnar> Still needs a lot of work, but I bet if someone is good at building graphs that would be helpful!
[telegram] <badmex> Any mainnet or token swap on schedule for hmq?
[telegram] <Vollka_Racho> AtomicDEX 0.1.7 (13) for iOS is now available to test.
[telegram] <EPIDEMIC_media> Nice, passing app store approval is always a big hurdle. You have a link I can send 2 a friend? (re @Vollka_Racho: AtomicDEX 0.1.7 (13) for iOS is now available to test.)
[telegram] <Vollka_Racho> Currently only valid for Testflight. In the AppStore will follow (re @EPIDEMIC_media: Nice, passing app store approval is always a big hurdle. You have a link I can send 2 a friend?)
[telegram] <torsten1> I think it will stay on TestFlight for the foreseeable future
[telegram] <torsten1> It’s beta software after all :)
[telegram] <torsten1> The only limitation of TestFlight is that it has a user cap of 10000. Should do for the beta.


This intention replaces an extension of an adapter class with a direct implementation of the listeners.
New in 9


Loading..
Statistics
Actions
Rules
Lists
Learn RSPAMD
Online scan suspected message
Paste and scan suspicious message
Scan results:
| Action | Score / Req. score | Symbols |
|---|
History
| Time | ID | IP | Action | Score / Req. score | Symbols | Size | Scan Time (ms) |
User |
|---|
- ««
- «
- of
- »
- »»


{% extends "adm/base_site.html" %} {% load i18n admin_static %} {% block coltype %}colM{% endblock %} {% block breadcrumbs %}
{{ booking.book_date|date:"l, F j, Y" }}
{{ booking.from_time|date:"H:i" }}-{{ booking.to_time|time:"H:i" }}
{{ booking.request_by }}
{{ booking.purpose }}
{{ booking.venue.venue_name }} ({{ booking.venue.venue_capacity }})
{{ booking.book_status }}
Update


Predict from component factors, linear regression
Human predicts, from knowledge of known factors to unknown future and make a decision. We look at
the sky and decide whether we should bring an umbrella. If the sky is dark and cloudy, most people will bring
an umbrella. A bank base on a person’s income, job nature, age and other component factors to make a
decision of approving a credit card for him or not.
In the simplest mathemacal term, it can be described by a simple equaon as following.
z
=
w
0
+
w
1
x
1
+
w
2
x
2
+
w
3
x
3
Equ 1.0
For example,
x
1
is income,
x
2
is job nature and
x
3
is age. We treat each factor as a predictor for the outcome z.
For each factor, we weigh it with some weights
w
1
,w
2
,w
3
. Furthermore, when all the weighted stuﬀ add
together, it must be greater than a threshold value for approving a credit card. Therefore if we select
w
0
as a
big enough negave number (say -100), then all the weighted sum
w
1
x
1
+
w
2
x
2
+
w
3
x
3
must greater than 100 to
make the outcome z posive. If z is posive, the bank approves the credit card. Equ 1.0 is called linear
regression [3].
The challenge here is how to select the weights (
w
i
) such that the above simple equaon can be used for the
bank’s manager as a guiding rule for approving the credit card. Similarly, the same approach can be used to
determine insurance premium decisions, but the weights to achieve this will diﬀer for the credit card approval
process. For a more detailed treatment on the credit card example, please refer to [1, 2]
. Somemes
we can ﬁnd the weights by analycal matrix algebra methods. But I will show only numerical methods here, as
they can be used for a broader spectrum of problems by modern computer soﬅware easily.
Most, if not all, of the machine deep learning methods, use this as the basic unit to build highly complicated
systems from online store recommendaon systems to Google’s Alpha Go and Alpha Zero, which outperform
humans in several Go compeons. Today, similar methods are using from a ﬁnancial trading system, genes
classiﬁcaon to Covid-19 virus classiﬁcaon system. Human’s capabilies in understanding the universe is
extending to another limit that never happened in our history before.
The system describe by Equ 1.0 can be build easy by Tensorﬂow Keras as following:
Dense(units=1, name="z")
Google Tensorﬂow called it Dense layer, and it is one unit in a layer.
Pictorially, it can be represented by a circle
with weights around it.


--- layout: index title: Mobility tagline: tags : [about, info] img : img-mobile : author : Marcin Koculak css: js: keywords: canonical: --- {% include JB/setup %}
Head of the Perception and Neuroarchitectural Mapping Group at the Center of Functionally Integrative Neuroscience at Aarhus University.
Dr Sandberg received his PhD and postdoctoral training from Professor Morten Overgaard at Aarhus University and Professor Geraint Rees at University College London (UCL) in 2007-2010, developing/comparing subjective reports of consciousness and examining the neural correlates of consciousness. He was awarded the Higher Doctorate in Medicine at Aarhus University in 2019 for his subsequent work in the field of consciousness research.
Dr Sandberg and his research group at Aarhus University conduct basic as well as clinical research. A main line of research within the group focuses on human perception, particularly conscious vision. Within this line of research, they use magnetic resonance imaging (MRI), magnetoencephalography (MEG), and transcranial magnetic stimulation (TMS) to examine the link between perception and brain structure/function. Their long-term aim is to build MRI based neuroarchitectural models that give exhaustive explanations for a range of perceptual and cognitive phenomena. In another line of research, they examine how individual neuroarchitectural models of patients with different types of brain disorders differ from that of healthy individuals and how these individual models explain patient outcome.


Gallinari, Paul lead Thunder past 76ers
OKLAHOMA CITY – When Danilo Gallinari hit a big 3-pointer in overtime, the crowd roared in support of the Oklahoma City Thunder.
It was just like old times.
Gallinari scored 28 points to help Oklahoma City beat the Philadelphia 76ers 127-119 on Friday night.
Chris Paul had 27 points for the Thunder, who had dropped three of four. Shai Gilgeous-Alexander scored 24 points and Terrance Ferguson finished with 19.
It was the biggest win of the season for a franchise that lost All-Stars Russell Westbrook and Paul George in offseason trades. The sellout Chesapeake Energy Arena crowd of 18,203 backed Oklahoma City with loud cheering in the fourth quarter and overtime and made it seem, for a night, like nothing had changed in a venue long known as one of the league’s loudest places.
“It was amazing,” Gallinari said. “These are the moments players live for and these are the moments you want at home. It was great to get them a W.”
Gallinari missed a jumper from the top of the key that would have won it at the end of regulation, but he made up for it with seven points in overtime.
The Thunder relentlessly attacked the bigger 76ers and outscored them 35-15 at the free-throw line. Oklahoma City shot 53.9 percent from the field for the night.
“I give our guys credit because I think we tried to play to our identity and tried to do it consistently through four quarters,” Thunder coach Billy Donovan said.
Joel Embiid had 31 points and 12 rebounds and Josh Richardson added 28 points for Philadelphia, which lost five of seven.
“We’re obviously frustrated,” forward Tobias Harris said. “Losing five of seven is not where we want to be. It’s early in the season, and right now, we’re going to progress and get better and find ways to figure out ways to help each other and help our team and go from there.”
Oklahoma City outscored Philadelphia 20-12 in overtime. The Thunder went 5-for-7 from the field and 8 for 8 at the line in the extra period.
“Lots of whistles,” 76ers coach Brett Brown said. “They called it how they wanted to call it. … Sometimes, the game is called that way, and that’s how it was.”
Wizards 137, Timberwolves 116
In Minneapolis, Bradley Beal scored 44 points for the second straight game and Washington snapped a three-game losing streak with a victory over short-handed Minnesota.
Moritz Wagner came off the bench for Washington to add 30 points and 15 rebounds — both career highs. Rookie forward Rui achimura added eight points, four rebounds, three assists and two steals in 25-plus minutes.
Karl-Anthony Towns, celebrating his 24th birthday, led the Timberwolves with 36 points. Minnesota was without scoring leader Andrew Wiggins because of personal reasons.
In Other Games
Rockets 111, Pacers 102
Lakers 99, Kings 97
Celtics 105, Warriors 100
Hornets 109, Pistons 106
Grizzlies 107, Jazz 106
Magic 111, Spurs 109
GET THE BEST OF THE JAPAN TIMES
IN FIVE EASY PIECES WITH TAKE 5
JOIN THE CONVERSATION


An Embeddable Scripting Engine |
Tweet |
Follow @jx9_engine |
Jx9 in 5 minutes or less
Here
is what you do to start experimenting with the Jx9 scripting engine without
having to do a lot of tedious reading and configuration:
download The Code
Get a copy of the last public release of Jx9 (A single 1.3 MB C file). Visit the download page for additional information.
Write Programs That Use Jx9
Below is a simple C program that demonstrates how to use the C/C++ interface to Jx9. This program compile and execute the following Jx9 scripts.
$my_data = {
// Greeting message
greeting : "Hello world!\n",
// Dummy field
__id : 1,
// Host Operating System
os_name: uname(), //Built-in OS function
// Current date
date : __DATE__,
// Return the current time using an anonymous function
time : function(){ return __TIME__; }
};
// invoke JSON object members
print $my_data.greeting; //Hello world!
print "Host Operating System: ", $my_data.os_name, JX9_EOL;
print "Current date: ", $my_data.date, JX9_EOL;
print "Current time: ", $my_data.time(); // Anonymous function
That is, this simple Jx9 script when running should display a greeting message, the current system time and the host operating system. A typical output of this program would look like this:
Host Operating System: Microsoft Windows 7 localhost 6.1 build 7600 x86
Current date: 2012-12-27
Current time: 10:36:02
Another Jx9 script that demonstrate how to use the built-in IO facility.
$num = [];
print "Enter a number (Decimal, Hex, Octal or Binary notation)\n";
//Populate the JSON array with the first entry
$num[] = (int)fgets(STDIN);
print "Another number\n";
$num[] = (int)fgets(STDIN);
print "Finally, one last number\n";
$num[] = (int)fgets(STDIN);
//show content
print "Before sorting\n";
print $num;
//Sort the array now
sort($num);
print "\nAfter sorting\n";
print $num;
This simple Jx9 script ask for three numbers (64 bit integers) from the standard input (STDIN), store the given numbers in a JSON array, perform a merge-sort using the built-in sort function and output the sorted array. A typical output of this program would look like this:
50232
Another number
80
Finally, one last number
0xff
Before sorting
[50232,80,255]
After sorting
[80,255,50232]
An implementation of the famous factorial function in Jx9.
print "Enter a number\n";
$num = (int)fgets(STDIN);
function factorial(int $num)
{
if( $num == 0 || $num == 1 )
return 1;
else
return
$num
* factorial($num – 1);
}
print "Facorial of $num = "..factorial($num);
One final Jx9 script that demonstrate how Jx9 can be used for processing external configuration file based on JSON using the built-in json_encode() and json_decode() functions.
// Create a dummy configuration using a JSON object
$my_config = {
bind_ip : "<IP_ADDRESS>",
config : "/etc/symisc/jx9.conf",
dbpath : "/usr/local/unqlite",
fork : true,
logappend : true,
logpath : "/var/log/jx9.log",
quiet : true,
port : 8080
};
// Dump the JSON object
print $my_config;
// Write to disk
$file = "config.json.txt";
print "\n\n------------------\nWriting JSON object to disk file: '$file'\n";
// Create the file
$fp = fopen($file,'w+');
if( !$fp )
exit("Cannot create $file");
// Write the JSON object
fwrite($fp,$my_config);
// Close the file
fclose($fp);
// All done
print "$file successfully created on: "..__DATE__..' '..__TIME__;
// ---------------------- config_reader.jx9 ----------------------------
// Read the configuration file defined above
$iSz = filesize($zFile); // Size of the whole file
$fp = fopen($zFile,'r'); // Read-only mode
if( !$fp ){
exit("Cannot open '$zFile'");
}
// Read the raw content
$zBuf = fread($fp,$iSz);
// decode the JSON object now
$my_config = json_decode($zBuf);
if( !$my_config ){
print "JSON decoding error\n";
}else{
// Dump the JSON object
foreach( $my_config as $key,$value ){
print "$key ===> $value\n";
}
}
// Close the file
fclose($fp);
The first script generate a JSON object holding some dummy configuration fields, create a disk file named config.json.txt using the built-in fopen() function and finally serialize the JSON object to disk using the fwrite() function. While the second script perform the reverse operation using the fread() and json_decode() functions.
As you can see, Jx9 is a powerful programming language with a friendly and familiar syntax with a rich standard library built with over 303 functions and 139 constants suitable for most purposes. Refer to the Jx9 Language Reference Manual for additional information.
Embedding Jx9 using the C/C++ API
Embedding Jx9 in a C/C++ host application is relatively easy. The three Jx9 scripts defined above can be embedded in an application with the same C/C++ interfaces. That is, this simple C program could be used to compile and execute all the Jx9 scripts defined above.
/*
* Compile this file together with the jx9 scripting engine source code to generate
* the executable. For example:
* gcc -W -Wall -O6 -o test jx9_intro.c jx9.c
*/
/* Make sure you have the latest release of the JX9 engine
* from:
* http://jx9.symisc.net/downloads.html
*/
#include <stdio.h>
#include <stdlib.h>
-
/* Make sure this header file is available.*/
#include "jx9.h"
-
/*
* Display an error message and exit.
*/
static void Fatal(const char *zMsg)
{
puts(zMsg);
/* Shutdown the library */
jx9_lib_shutdown();
/* Exit immediately */
exit(0);
}
/*
* VM output consumer callback.
* Each time the virtual machine generates some outputs, the following
* function gets called by the underlying virtual machine to consume
* the generated output.
* All this function does is redirecting the VM output to STDOUT.
* This function is registered later via a call to jx9_vm_config()
* with a configuration verb set to: JX9_VM_CONFIG_OUTPUT.
*/
static int Output_Consumer(const void *pOutput, unsigned int nOutputLen, void *pUserData /* Unused */)
{
/*
* Note that it's preferable to use the write() system call to display the output
* rather than using the libc printf() which everybody now is extremely slow.
*/
printf("%.*s",
nOutputLen,
(const char *)pOutput /* Not null terminated */
);
/* All done, VM output was redirected to STDOUT */
return JX9_OK;
}
/*
* Main program: Compile and execute the JX9 program defined above.
*/
int main(void)
{
jx9 *pEngine; /* JX9 engine handle*/
jx9_vm *pVm; /* Compiled JX9 program */
int rc;
-
/* Allocate a new jx9 engine instance */
rc = jx9_init(&pEngine);
if( rc != JX9_OK ){
/*
* If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory, there is no much we can do here.
*/
Fatal("Error while allocating a new JX9 engine instance");
}
/* Compile the test program defined above */
rc = jx9_compile(pEngine,JX9_PROG,-1,&pVm);
if( rc != JX9_OK ){
if( rc == JX9_COMPILE_ERR ){
const char *zErrLog;
int nLen;
/* Extract error log */
jx9_config(pEngine,
JX9_CONFIG_ERR_LOG,
&zErrLog,
&nLen
);
if( nLen > 0 ){
/* zErrLog is null terminated */
puts(zErrLog);
}
}
/* Exit */
Fatal("Compile error");
}
/*
* Now we have our script compiled, it's time to configure our VM.
* We will install the VM output consumer callback defined above
* so that we can consume the VM output and redirect it to STDOUT.
*/
rc = jx9_vm_config(pVm,
JX9_VM_CONFIG_OUTPUT,
Output_Consumer, /* Output Consumer callback */
0 /* Callback private data */
);
if( rc != JX9_OK ){
Fatal("Error while installing the VM output consumer callback");
}
/*
* And finally, execute our program. Note that your output (STDOUT in our case)
* should display the result.
*/
jx9_vm_exec(pVm, 0);
-
/* All done, cleanup the mess left behind. */
jx9_vm_release(pVm);
jx9_release(pEngine);
-
return 0;
}
We create a new Jx9 engine instance using a call to jx9_init() on line 62. This is often the first Jx9 API call that an application makes and is a prerequisite in order to compile Jx9 code using one of the compile interfaces.
We compile our Jx9 test program on line 73 using the jx9_compile interface.
We configure our Virtual Machine on line 99 by setting a VM output consumer callback named Output_Consumer(). All this callback does is redirecting the VM output to STDOUT using the libc printf() routine or the write() system call.
And
finally we execute our Jx9 program on
line 113 using
a call to jx9_vm_exec().
Your standard output (STDOUT) should display the result.
Clean-up is done on line 117 and 118 respectively via calls to jx9_vm_release() and jx9_release().
Compile the program
Compile the target C file together with the jx9 engine source code to generate the executable. For example:
gcc -W -Wall -O6 -o jx9_test jx9_intro.c jx9.c
Working Examples
jx9_intro.c: Hello world from C using Jx9 (First script).
jx9_terminal_io.c: Jx9 built-in IO facility from C (second script).
jx9_json_config_write.c: JSON configuration writer (third script).
jx9_json_config_read.c: JSON configuration reader (third script).
Visit the download page for additional working examples.
Sharing Data between the C Code and Jx9 Scripts.
Sharing data between the host application and the target Jx9 script such as passing environments information, command line arguments or registering predefined variables such as your application name, copyright notice and so forth is relatively easy and is done via the foreign variable mechanism.
This simple Jx9 script output the content of some foreign variable decalred below.
//Scalar foreign variable named $my_app
print "\$my_app =" , $my_app..JX9_EOL;
//foreign JSON object named $my_data
print "\$my_data = " , $my_data;
//Dump command line arguments
if( count($argv) > 0 ){
print "\nCommand line arguments:\n";
print $argv;
}else{
print "\nEmpty command line";
}
//Return a simple JSON object to the host application
$my_config = {
"jx9_version" : __JX9__, //JX9 Engine version
"time" : __TIME__, //Current time
"date" : __DATE__ //Current date
};
//terminate the script
die;
The following C program demonstrate how data is shared between the host application and the running Jx9 script. The main() function defined below creates and install two foreign variables named respectively $my_app and $my_data. The first is a simple scalar value while the last is a complex JSON object. these foreign variables are made available to the running script using the jx9_vm_config() interface with a configuration verb set to JX9_VM_CONFIG_CREATE_VAR.
/*
* Compile this file together with the jx9 scripting engine source code to generate
* the executable. For example:
* gcc -W -Wall -O6 -o test jx9_hostapp_info.c jx9.c
*/
/* Make sure you have the latest release of the JX9 engine
* from:
* http://jx9.symisc.net/downloads.html
*/
#include <stdio.h>
#include <stdlib.h>
-
/* Make sure this header file is available.*/
#include "jx9.h"
-
/*
* Display an error message and exit.
*/
static void Fatal(const char *zMsg)
{
puts(zMsg);
/* Shutdown the library */
jx9_lib_shutdown();
/* Exit immediately */
exit(0);
}
/*
* VM output consumer callback.
* Each time the virtual machine generates some outputs, the following
* function gets called by the underlying virtual machine to consume
* the generated output.
* All this function does is redirecting the VM output to STDOUT.
* This function is registered later via a call to jx9_vm_config()
* with a configuration verb set to: JX9_VM_CONFIG_OUTPUT.
*/
static int Output_Consumer(const void *pOutput, unsigned int nOutputLen, void *pUserData /* Unused */)
{
/*
* Note that it's preferable to use the write() system call to display the output
* rather than using the libc printf() which everybody now is extremely slow.
*/
printf("%.*s",
nOutputLen,
(const char *)pOutput /* Not null terminated */
);
/* All done, VM output was redirected to STDOUT */
return JX9_OK;
}
- /*
-
* The following walker callback is made available to the [jx9_array_walk()] interface
-
* which is used to iterate over the JSON object extracted from the running script.
-
* (See below for more information).
-
*/
-
static int JsonObjectWalker(jx9_value *pKey,jx9_value *pData,void *pUserData /* Unused */)
-
{
-
const char *zKey,*zData;
-
/* Extract the key and the data field */
-
zKey = jx9_value_to_string(pKey,0);
-
zData = jx9_value_to_string(pData,0);
-
/* Dump */
-
printf(
-
"%s ===> %s\n",
-
zKey,
-
zData
-
);
-
return JX9_OK;
-
}
-
/*
-
* Main program: Compile and execute the JX9 program defined above.
-
*/
-
int main(int argc,char **argv)
-
{
-
jx9_value *pScalar,*pObject; /* Foreign JX9 variable to be installed later */
-
jx9 *pEngine; /* JX9 engine handle*/
-
jx9_vm *pVm; /* Compiled JX9 program */
-
int rc;
-
int n;
-
-
/* Allocate a new jx9 engine instance */
-
rc = jx9_init(&pEngine);
-
if( rc != JX9_OK ){
-
Fatal("Error while allocating a new JX9 engine instance");
-
}
-
-
/* Compile the test program defined above */
-
rc = jx9_compile(pEngine,JX9_PROG,-1,&pVm);
-
if( rc != JX9_OK ){
-
if( rc == JX9_COMPILE_ERR ){
-
const char *zErrLog;
-
int nLen;
-
/* Extract error log */
-
jx9_config(pEngine,
-
JX9_CONFIG_ERR_LOG,
-
&zErrLog,
-
&nLen
-
);
-
if( nLen > 0 ){
-
/* zErrLog is null terminated */
-
puts(zErrLog);
-
}
-
}
-
/* Exit */
-
Fatal("Compile error");
-
}
-
/* Register script agruments so we can access them later using the $argv[]
-
* array from the compiled JX9 program.
-
*/
-
for( n = 1; n < argc ; ++n ){
-
jx9_vm_config(pVm, JX9_VM_CONFIG_ARGV_ENTRY, argv[n]/* Argument value */);
-
}
-
-
/*
-
* Now we have our script compiled, it's time to configure our VM.
-
* We will install the VM output consumer callback defined above
-
* so that we can consume the VM output and redirect it to STDOUT.
-
*/
-
rc = jx9_vm_config(pVm,
-
JX9_VM_CONFIG_OUTPUT,
-
Output_Consumer, /* Output Consumer callback */
-
0 /* Callback private data */
-
);
-
if( rc != JX9_OK ){
-
Fatal("Error while installing the VM output consumer callback");
-
}
-
/*
-
* Create a simple scalar variable.
-
*/
-
pScalar = jx9_new_scalar(pVm);
-
if( pScalar == 0 ){
-
Fatal("Cannot create foreign variable $my_app");
-
}
-
/* Populate the variable with the desired information */
-
jx9_value_string(pScalar,"My Host Application/1.2.5",-1/*Compule length automatically*/); /* Dummy signature*/
-
-
/*
-
* Install the variable ($my_app).
-
*/
-
rc = jx9_vm_config(
-
pVm,
-
JX9_VM_CONFIG_CREATE_VAR, /* Create variable command */
-
"my_app", /* Variable name (without the dollar sign) */
-
pScalar /* Value */
-
);
-
if( rc != JX9_OK ){
-
Fatal("Error while installing $my_app");
-
}
-
/* To access this foreign variable from the running script, simply invoke it
-
* as follows:
-
* print $my_app;
-
* or
-
* dump($my_app);
-
*/
-
-
/*
-
* Now, it's time to create and install a more complex variable which is a JSON
-
* object named $my_data.
-
* The JSON Object looks like this:
-
* {
-
* "path" : "/usr/local/etc",
-
* "port" : 8082,
-
* "fork" : true
-
* };
-
*/
-
-
pObject = jx9_new_array(pVm); /* Unified interface for JSON Objects and Arrays */
-
/* Populate the object with the fields defined above. */
-
jx9_value_reset_string_cursor(pScalar);
-
/* Add the "path" : "/usr/local/etc" entry */
-
jx9_value_string(pScalar,"/usr/local/etc",-1);
-
jx9_array_add_strkey_elem(pObject,"path",pScalar); /* Will make it's own copy of pScalar */
-
/* Add the "port" : 8080 entry */
-
jx9_value_int(pScalar,8080);
-
jx9_array_add_strkey_elem(pObject,"port",pScalar); /* Will make it's own copy of pScalar */
-
/* Add the "fork": true entry */
-
jx9_value_bool(pScalar,1 /* TRUE */);
-
jx9_array_add_strkey_elem(pObject,"fork",pScalar); /* Will make it's own copy of pScalar */
-
-
/* Now, install the variable and associate the JSON object with it */
-
rc = jx9_vm_config(
-
pVm,
-
JX9_VM_CONFIG_CREATE_VAR, /* Create variable command */
-
"my_data", /* Variable name (without the dollar sign) */
-
pObject /*value */
-
);
-
if( rc != JX9_OK ){
-
Fatal("Error while installing $my_data");
-
}
-
/* Release the two values */
-
jx9_release_value(pVm,pScalar);
-
jx9_release_value(pVm,pObject);
-
-
/*
-
* And finally, execute our program. Note that your output (STDOUT in our case)
-
* should display the result.
-
*/
-
jx9_vm_exec(pVm, 0);
-
/* Extract the content of the variable named $my_config defined in the
-
* running script which hold a simple JSON object.
-
*/
-
pObject = jx9_vm_extract_variable(pVm,"my_config");
-
if( pObject && jx9_value_is_json_object(pObject) ){
-
/* Iterate over object entries */
-
printf("\n\nTotal entries in $my_config = %u\n",jx9_array_count(pObject));
-
jx9_array_walk(pObject,JsonObjectWalker,0);
-
}
-
/* All done, cleanup the mess left behind.
-
*/
-
jx9_vm_release(pVm);
-
jx9_release(pEngine);
-
-
return 0;
-
}
We create a new Jx9 engine instance on line 82 using a call to jx9_init().
We compile our Jx9 test program on line 88 using a call to jx9_compile().
We pass command line arguments to the target Jx9 script ($argv predefined variable) on line 112 using a call to jx9_vm_config() with a configuration verb set to: JX9_VM_CONFIG_ARGV_ENTRY.
- We install a VM output consumer callback on line 120 using a call to jx9_vm_config() with a configuration verb set to: JX9_VM_CONFIG_OUTPUT.
We create a simple scalar foreign variable on line 131 using a call to jx9_new_scalar().
We populate the scalar variable with the desired value, here the application name on line 136 using a call to jx9_value_string().
We install the foreign variable as $my_app on line 141 using a call to jx9_vm_config() with a configuration verb set to: JX9_VM_CONFIG_CREATE_VAR.
We create an empty JSON object on line 168 using a call to jx9_new_array().
We populate our JSON object on line 170 til line 179 with the desired fields using the jx9_value_*() and jx9_array_add_*() interfaces.
We install our JSON object as a foreign variable named $my_data on line 182 using a call to jx9_vm_config() with a configuration verb set to: JX9_VM_CONFIG_CREATE_VAR.
We execute our JX9 program on line 200 using a call to jx9_vm_exec().
We extract the content of the variable named $my_config (A JSON object) declared inside the executed Jx9 script on line 204 using a call to jx9_vm_extract_variable().
We iterate over the elements of the extracted JSON object on line 208 using a call to jx9_array_walk().
finally, cleanup is done on line 212 and 213 using a call to jx9_vm_release() and jx9_release().
Standalone Interpreter For Jx9
The Jx9 download page includes a simple standalone Jx9 interpreter named jx9 (or jx9.exe on windows) that allows the user to enter and execute Jx9 files against a Jx9 engine. This utility is available in prebuilt binaries forms or can be compiled from source. You can get a copy of the Jx9 interpreter from the download page.
To start the jx9 program, just type "jx9" followed by the name of the Jx9 file to xecute. That is, the first argument is to the interpreter, the rest are scripts arguments, press "Enter" and the Jx9 code will be executed.
If something goes wrong while processing the Jx9 script due to a compile-time error, your error output (STDOUT) should display the compile-time error messages.
Usage example of the jx9 interpreter:
Running the interpreter
jx9 scripts/hello_world.jx9.txt
Running the interpreter with script arguments
jx9 scripts/mp3_tag.jx9.txt /usr/local/path/to/my_mp3s
The Jx9 interpreter package includes over 40 Jx9 scripts to test from simple hello world programs to ZIP archive extracting, MP3 tag extracting, JSON encoding/decoding, INI processing, UTF-8 encoding/decoding and many more. These scripts are available in the scripts directory of the zip archive.
Next
Check out the Introduction To The Jx9 C/C++ Interface for an introductory overview and roadmap to the dozens of Jx9 interface functions.
A separate document, The Jx9 C/C++ Interface, provides detailed specifications for all of the various C/C++ APIs for Jx9. Once the reader understands the basic principles of operation for Jx9, that document should be used as a reference guide.
Any questions, check the Frequently Asked Questions page or visit the Support Page for online community support.


Wright Brothers
Ticketing
Customer Info
Customer Search
Records
Questions
Parking Ticket Search
Check In Form
Please enter your information below.
Name
Email
Return Date
Phone
Flight Number
Pilots Only
Car Info
Please fill out all required fields.


The GraphQL mutations createPaste and importPaste allow creating and importing new pastes. The pastes may include any character without any restrictions. The pastes would then render in
the Public and Private paste pages, which would result in a Cross Site Scripting vulnerability (XSS).
# Create New Paste allows special characters that would render in HTML.
mutation {
createPaste(title:"<script>alert(1)</script>", content:"zzzz", public:true) {
pasteId
}
}
# Alternatively, importing a paste that includes Javascript will also result in the same behaviour.
mutation {
importPaste(host:"localhost", port:80, path:"/xss.html"")
}


403 Error
Forbidden
You are not authorized to access this page. Here's a link to the Home Page. You know, just in case.
{% extends "layout.html" %} {% block content %}
You are not authorized to access this page. Here's a link to the Home Page. You know, just in case.