Test Driven Development with Node, Postgres, and Knex (Red/Green/Refactor)
Today we will be developing a RESTful API with Node, Express, Knex - a SQL query builder - and PostgreSQL using test driven development (TDD).
This post assumes prior knowledge of:
- SQL
- Node/Express
- NPM Packages
Contents
Getting Started
Before we can start testing and writing code we need to set up our project, a database, and all the required dependencies…
Project Setup
First, we need to create a basic boilerplate Express application. To do this, first install the Express-Generator globally:
$ npm install<EMAIL_ADDRESS>-g
We can now generate a basic Express application boilerplate:
$ express mocha-chai-knex
$ cd mocha-chai-knex
$ npm install
Run npm start
to ensure the application works. Once the server is running, navigate to http://localhost:3000/, and you should see ‘Welcome to Express’ on the main page.
Database Setup
Start by installing PostgreSQL from the official download page.
If you’re on a Mac we recommend using Postgress.app.
As noted, we’ll be using Knex to interact with our database. Knex is a SQL query builder that we can use with PostgreSQL to handle migrations, manage the schema, and query the database.
Let’s start by installing Knex and pg, a module for interacting with Postgres.
$ npm install<EMAIL_ADDRESS><EMAIL_ADDRESS>--save
$ npm install<EMAIL_ADDRESS>-g
Next, we need to create two new databases, one for developing and the other for testing. Open psql in the terminal, and create a new database:
$ psql
psql (9.4.5)
Type "help" for help.
# CREATE DATABASE mocha_chai_tv_shows;
CREATE DATABASE
# CREATE DATABASE mocha_chai_tv_shows_test;
CREATE DATABASE
# \q
With our database created we can initialize Knex.
Knex Setup
Run the following command to create knexfile.js, the Knex configuration file:
$ knex init
Created ./knexfile.js
Update the default info to:
module.exports = {
test: {
client: 'pg',
connection: 'postgres://localhost/mocha_chai_tv_shows_test',
migrations: {
directory: __dirname + '/db/migrations'
},
seeds: {
directory: __dirname + '/db/seeds/test'
}
},
development: {
client: 'pg',
connection: 'postgres://localhost/mocha_chai_tv_shows',
migrations: {
directory: __dirname + '/db/migrations'
},
seeds: {
directory: __dirname + '/db/seeds/development'
}
},
production: {
client: 'pg',
connection: process.env.DATABASE_URL,
migrations: {
directory: __dirname + '/db/migrations'
},
seeds: {
directory: __dirname + '/db/seeds/production'
}
}
};
This sets up three different settings for our databases:
test
- for testing on the local environmentdevelopment
- for developing, again on the local environmentproduction
- for the production environment
Now, we can add schema migrations. Migrations allow us to define and update the database schema. We can create migrations in the terminal like so:
$ knex migrate:make tv_shows
Now, knex has automatically added in a “db/migrations” folder, with a timestamped file inside of it. Here is where we define our schema. It should just contain two empty functions at the moment.
Let’s add in our code to create and drop tables.
exports.up = function(knex, Promise) {
return knex.schema.createTable('shows', function(table){
table.increments();
table.string('name').notNullable().unique();
table.string('channel').notNullable();
table.string('genre').notNullable();
table.integer('rating').notNullable();
table.boolean('explicit').notNullable();
});
};
exports.down = function(knex, Promise) {
return knex.schema.dropTable('shows');
};
Here, the up
function creates the shows
table while the down
function drops the table. So we now have a schema defined, and a migration file ready to create that schema.
Create a new file called knex.js inside the “db” folder. In this file we specify the environment (test
, development
, or production
), require the knexfile.js, and export the configuration (based on the environment) for our database:
var environment = process.env.NODE_ENV || 'development';
var config = require('../knexfile.js')[environment];
module.exports = require('knex')(config);
Apply the migrations to both databases:
$ knex migrate:latest --env development
$ knex migrate:latest --env test
Knex Seeds
Seeding is simply the process of populating the database with initial data. Knex utilizes seed files for this.
Run the following in your terminal to create a seed for development:
$ knex seed:make shows_seed --env development
This will generate a folder called “seeds/development” in the “db” directory of your project, and in that file there will be a boilerplate setup for inserting data into the database:
exports.seed = function(knex, Promise) {
return Promise.join(
// Deletes ALL existing entries
knex('table_name').del(),
// Inserts seed entries
knex('table_name').insert({id: 1, colName: 'rowValue'}),
knex('table_name').insert({id: 2, colName: 'rowValue2'}),
knex('table_name').insert({id: 3, colName: 'rowValue3'})
);
};
Let’s change the file so we’re inserting relevant data. Notice how there’s also built-in promises so that the data will be seeded in the order that we specify:
exports.seed = function(knex, Promise) {
return knex('shows').del() // Deletes ALL existing entries
.then(function() { // Inserts seed entries one by one in series
return knex('shows').insert({
name: 'Suits',
channel: 'USA Network',
genre: 'Drama',
rating: 3,
explicit: false
});
}).then(function () {
return knex('shows').insert({
name: 'Game of Thrones',
channel: 'HBO',
genre: 'Fantasy',
rating: 5,
explicit: true
});
}).then(function () {
return knex('shows').insert({
name: 'South Park',
channel: 'Comedy Central',
genre: 'Comedy',
rating: 4,
explicit: true
});
}).then(function () {
return knex('shows').insert({
name: 'Mad Men',
channel: 'AMC',
genre: 'Drama',
rating: 3,
explicit: false
});
});
};
Since JavaScript is asynchronous, the order that data is inserted can sometimes change. We want to make sure that the data is in the same order each time we run our seed file(s).
Run the seed file:
$ knex seed:run --env development
Before moving on, follow the same process for the test seed. Just use the same data as the development seed.
Mocha/Chai Setup
With the database set up with data in it, we can start setting up our tests. Start by installing Mocha (test runner) and Chai (assertions) as well as ChaiHTTP (HTTP request module for integration testing). Make sure to also install mocha globally, so that we can run tests from the command line.
$ npm install<EMAIL_ADDRESS>-g
$ npm install<EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS>--save-dev
By default, Mocha searches for tests with a “test” folder.
This configuration can be changed with a mocha.opts file
Add a “test” folder to the root directory, and in that folder add a file called routes.spec.js. Then update routes/index.js:
var express = require('express');
var router = express.Router();
// *** GET all shows *** //
router.get('/shows', function(req, res, next) {
res.send('send shows back');
});
module.exports = router;
Then within app.js update this line-
app.use('/', routes);
-to-
app.use('/api/v1', routes);
Now every single route in that file will be prefixed with ‘/api/v1’ Try it out. Fire up the server, and navigate to http://localhost:3000/api/v1/shows. You should see the string ‘send shows back’ in the browser.
Finally, update this line in app.js-
app.use(logger('dev'));
-to-
if (process.env.NODE_ENV !== 'test') {
app.use(logger('dev'));
}
This prevents application log messages from displaying in the stdout when the tests are ran, making it much easier to read the output.
And make sure the error handlers return JSON:
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.json({
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.json({
message: err.message,
error: {}
});
});
Developing via TDD
The premise behind Test Driven Development (TDD) is that you write tests first that fail which you then make pass. This process is often referred to as Red/Green/Refactor.
Test Setup
In our test file, we’ll need to start by including the necessary requirements for testing:
process.env.NODE_ENV = 'test';
var chai = require('chai');
var should = chai.should();
var chaiHttp = require('chai-http');
var server = require('../app');
chai.use(chaiHttp);
describe('API Routes', function() {
});
The first line sets the NODE_ENV
to test
so that the correct Knex config is used from knexfile.js. The next line requires chai
, the assertion module, giving us access to all the chai
methods - like should()
.
By utilizing
should()
we are using the should assertion style. This is a personal preference. You could also use expect or assert.
Then we require chai-http
. This module allows us make http requests from within our test file. Next, we link to our app so that we can test the request-response cycle. Finally, the describe
block underneath the requirements is the wrapper for the tests. Keep in mind that you can nest describe
blocks to better organize your test structure by grouping similar tests together.
GET all shows
Red
In the first test case, which is nested inside the first describe
block, we want to get ALL shows in our database:
describe('GET /api/v1/shows', function() {
it('should return all shows', function(done) {
chai.request(server)
.get('/api/v1/shows')
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('array');
res.body.length.should.equal(4);
res.body[0].should.have.property('name');
res.body[0].name.should.equal('Suits');
res.body[0].should.have.property('channel');
res.body[0].channel.should.equal('USA Network');
res.body[0].should.have.property('genre');
res.body[0].genre.should.equal('Drama');
res.body[0].should.have.property('rating');
res.body[0].rating.should.equal(3);
res.body[0].should.have.property('explicit');
res.body[0].explicit.should.equal(false);
done();
});
});
});
So, we have a describe
block, and within that block, we have a single it
statement. An it
statement defines a specific test case. Here we hit the route ‘/api/v1/shows’ with a GET request and test that the actual response is the same as the expected response.
Let’s break this test down…
First, by removing the test conditions, we can look at the basic test structure:
it('should return all shows', function(done) {
chai.request(server)
.get('/api/v1/shows')
.end(function(err, res) {
done();
});
});
Since this is an asynchronous test, we need some way of telling the callback function that the test is complete. This is where the done()
callback method comes into play. Once called (or if a two second timer is exceeded), Mocha knows that the test is finished running, and it can move on to the next test.
Now let’s look at the assertions:
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('array');
res.body.length.should.equal(4);
res.body[0].should.have.property('name');
res.body[0].name.should.equal('Suits');
res.body[0].should.have.property('channel');
res.body[0].channel.should.equal('USA Network');
res.body[0].should.have.property('genre');
res.body[0].genre.should.equal('Drama');
res.body[0].should.have.property('rating');
res.body[0].rating.should.equal(3);
res.body[0].should.have.property('explicit');
res.body[0].explicit.should.equal(false);
The first thing we generally want to do, is test that the response has a status of 200. After that, these tests will change depending on what we return in the route handler. In this case, we are expecting that the content type is JSON and that the response body will be an array (of objects) and have a length equal to four (since there are four rows in the database). Finally, we are testing the keys and values within the first object of the array.
Try it out:
$ mocha
If all went well you should see this:
API Routes
GET /api/v1/shows
1) should return all shows
0 passing (59ms)
1 failing
1) API Routes GET /api/v1/shows should return all shows:
Uncaught AssertionError: expected 'text/html; charset=utf-8'
to include 'application/json'
Essentially, the second assertion - res.should.be.json;
- failed since we are sending plain text back. This is good! Remember: Red-Green-Refactor!
We just need to update the route to get the test to pass.
Green
Before updating the route, let’s create a queries module for handling, well, the database queries. Create a new file called queries.js with the “db” folder, and add the following code:
var knex = require('./knex.js');
function Shows() {
return knex('shows');
}
// *** queries *** //
function getAll() {
return Shows().select();
}
module.exports = {
getAll: getAll
};
Here, we made a reference to our database via the Knex config file, added a helper function for simplifying each individual query, and finally queried the database to get ALL shows.
Update the route:
var express = require('express');
var router = express.Router();
var queries = require('../db/queries');
// *** GET all shows *** //
router.get('/shows', function(req, res, next) {
queries.getAll()
.then(function(shows) {
res.status(200).json(shows);
})
.catch(function(error) {
next(error);
});
});
module.exports = router;
Run mocha again and see what happens:
API Routes
GET /api/v1/shows
✓ should return all shows (128ms)
1 passing (164ms)
Awesome! Just don’t forget the last step - refactor.
Refactor
What’s happening in the test database?
# psql
psql (9.4.5)
Type "help" for help.
# \c mocha_chai_tv_shows_test
You are now connected to database "mocha_chai_tv_shows".
mocha_chai_tv_shows=# SELECT * FROM shows;
id | name | channel | genre | rating | explicit
----+-----------------+----------------+---------+--------+----------
1 | Suits | USA Network | Drama | 3 | f
2 | Game of Thrones | HBO | Fantasy | 5 | t
3 | South Park | Comedy Central | Comedy | 4 | t
4 | Mad Men | AMC | Drama | 3 | f
(4 rows)
#\q
Since we seeded the database earlier, there’s data already in there, which could affect other tests (especially when rows are added, changed, and/or dropped). In the test, we are asserting that the length of the array is four. Well, if we add an item then that’s going to change the length, and that first test will fail.
Tests should be isolated from each other. So, we really should rollback the migrations before and after each test is ran, and then apply the migrations and re-seed the database before the next test is ran.
This is where beforeEach
and afterEach
come into play:
process.env.NODE_ENV = 'test';
var chai = require('chai');
var chaiHttp = require('chai-http');
var server = require('../app');
var knex = require('../db/knex');
var should = chai.should();
chai.use(chaiHttp);
describe('API Routes', function() {
beforeEach(function(done) {
knex.migrate.rollback()
.then(function() {
knex.migrate.latest()
.then(function() {
return knex.seed.run()
.then(function() {
done();
});
});
});
});
afterEach(function(done) {
knex.migrate.rollback()
.then(function() {
done();
});
});
describe('Get all shows', function() {
it('should get all shows', function(done) {
chai.request(server)
.get('/api/v1/shows')
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('array');
res.body.length.should.equal(4);
res.body[0].should.have.property('name');
res.body[0].name.should.equal('Suits');
res.body[0].should.have.property('channel');
res.body[0].channel.should.equal('USA Network');
res.body[0].should.have.property('genre');
res.body[0].genre.should.equal('Drama');
res.body[0].should.have.property('rating');
res.body[0].rating.should.equal(3);
res.body[0].should.have.property('explicit');
res.body[0].explicit.should.equal(false);
done();
});
});
});
});
Now, the migrations will run and the database will be re-seeded before each nested describe
block, and the migrations will be rolled back after each block (which will also drop the data).
Why rollback before each test? If any errors occur during a test, it won’t reach the
afterEach
block. So we want to make sure that if an error occurs we still rollback the database.
Run the tests again:
API Routes
GET /api/v1/shows
✓ should return all shows (52ms)
1 passing (325ms)
1 down, 4 to go!!!
Did you notice how the overall time is slightly slower? 325ms vs 164ms. This is because of the
beforeEach
andafterEach
. Think about what’s happening, and why this would slow down the tests.
GET single show
We have our route and test built to get All shows, so the next step is to just get one show back.
Red
Based on our test seed, the first show that should (you never know for certain with async code) is Suits
:
{
name: 'Suits',
channel: 'USA Network',
genre: 'Drama',
rating: 3,
explicit: false
}
We can write out a test for a new route that will return just a single show and the meta information about it. Remember our last test? It returned an array of objects. This time it should be a single object since we will be searching for a single item in the database.
describe('GET /api/v1/shows/:id', function() {
it('should return a single show', function(done) {
chai.request(server)
.get('/api/v1/shows/1')
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('object');
res.body.should.have.property('name');
res.body.name.should.equal('Suits');
res.body.should.have.property('channel');
res.body.channel.should.equal('USA Network');
res.body.should.have.property('genre');
res.body.genre.should.equal('Drama');
res.body.should.have.property('rating');
res.body.rating.should.equal(3);
res.body.should.have.property('explicit');
res.body.explicit.should.equal(false);
done();
});
});
});
This is very similar to the previous test. We’re still testing for a status code of 200, and the response should be JSON. This time, we expect that res.body
is an object. Each of the properties afterwards should be the properties of the item with id ‘1’ in the database. So now if we run the tests, the first assertion should fail because we haven’t written our route yet:
API Routes
GET /api/v1/shows
✓ should return all shows
GET /api/v1/shows/:id
1) should return a single show
1 passing (383ms)
1 failing
1) API Routes GET /api/v1/shows/:id should return a single show:
Uncaught AssertionError: expected { Object (domain, _events, ...) }
to have status code 200 but got 404
Green
Add the query to queries.js, making sure to update module.exports
:
function getSingle(showID) {
return Shows().where('id', parseInt(showID)).first();
}
module.exports = {
getAll: getAll,
getSingle: getSingle
};
Then build out the route:
// *** GET single show *** //
router.get('/shows/:id', function(req, res, next) {
queries.getSingle(req.params.id)
.then(function(show) {
res.status(200).json(show);
})
.catch(function(error) {
next(error);
});
});
Now run mocha, and let’s see if that worked:
API Routes
GET /api/v1/shows
✓ should return all shows (54ms)
GET /api/v1/shows/:id
✓ should return a single show
2 passing (499ms)
Two routes down, two tests passing.
POST
We now want to add an item to our database.
Red
For time’s sake, write the test assuming you will get a JSON object back that contains the data added to the database:
describe('POST /api/v1/shows', function() {
it('should add a show', function(done) {
chai.request(server)
.post('/api/v1/shows')
.send({
name: 'Family Guy',
channel : 'Fox',
genre: 'Comedy',
rating: 4,
explicit: true
})
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('object');
res.body.should.have.property('name');
res.body.name.should.equal('Family Guy');
res.body.should.have.property('channel');
res.body.channel.should.equal('Fox');
res.body.should.have.property('genre');
res.body.genre.should.equal('Comedy');
res.body.should.have.property('rating');
res.body.rating.should.equal(4);
res.body.should.have.property('explicit');
res.body.explicit.should.equal(true);
done();
});
});
});
You can see here that our test block is slightly different than the previous two since we need to send information with the request to replicate how a client might send information to the server.
Green
With the test written and failing (did you remember to run the tests?), we can write the query and add the route (notice the pattern yet?).
Query:
function add(show) {
return Shows().insert(show, 'id');
}
Route:
// *** add show *** //
router.post('/shows', function(req, res, next) {
queries.add(req.body)
.then(function(showID) {
return queries.getSingle(showID);
})
.then(function(show) {
res.status(200).json(show);
})
.catch(function(error) {
next(error);
});
});
.insert()
returns an array containing the unique ID of the newly added item, so in order to return the actual data, we utilized the getSingle()
query. This also ensures that the data has been inserted into the database correctly.
Do the tests pass?
API Routes
GET /api/v1/shows
✓ should return all shows (50ms)
GET /api/v1/shows/:id
✓ should return a single show
POST /api/v1/shows
✓ should add a show (71ms)
3 passing (791ms)
Excellent. Just two routes left to go.
PUT
We need to test the edit route.
Red
Similar to our POST route we will need to send data to the server. In this case, we’ll utilize the ID of an existing show in the database and send along an object with the updated fields. Then we’ll assert that the show has been updated correctly.
describe('PUT /api/v1/shows/:id', function() {
it('should update a show', function(done) {
chai.request(server)
.put('/api/v1/shows/1')
.send({
rating: 4,
explicit: true
})
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('object');
res.body.should.have.property('name');
res.body.name.should.equal('Suits');
res.body.should.have.property('channel');
res.body.channel.should.equal('USA Network');
res.body.should.have.property('genre');
res.body.genre.should.equal('Drama');
res.body.should.have.property('rating');
res.body.rating.should.equal(4);
res.body.should.have.property('explicit');
res.body.explicit.should.equal(true);
done();
});
});
});
So here we are stating that the response body should contain the updated object from the database.
Green
You know the drill - Start with the query:
function update(showID, updates) {
return Shows().where('id', parseInt(showID)).update(updates);
}
Then update the route:
// *** update show *** //
router.put('/shows/:id', function(req, res, next) {
queries.update(req.params.id, req.body)
.then(function() {
return queries.getSingle(req.params.id);
})
.then(function(show) {
res.status(200).json(show);
})
.catch(function(error) {
next(error);
});
});
Here, we again make two calls to the database. Once we’ve updated the item, we then nest another query to get that same item - which we then check to ensure that it has in fact been updated correctly.
The tests should pass.
Refactor
What happens if we try to change the ID? Update the test:
describe('PUT /api/v1/shows/:id', function() {
it('should update a show', function(done) {
chai.request(server)
.put('/api/v1/shows/1')
.send({
id: 20,
rating: 4,
explicit: true
})
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('object');
res.body.should.have.property('name');
res.body.name.should.equal('Suits');
res.body.should.have.property('channel');
res.body.channel.should.equal('USA Network');
res.body.should.have.property('genre');
res.body.genre.should.equal('Drama');
res.body.should.have.property('rating');
res.body.rating.should.equal(4);
res.body.should.have.property('explicit');
res.body.explicit.should.equal(true);
done();
});
});
});
Run the tests now and they should fail:
API Routes
GET /api/v1/shows
✓ should return all shows (43ms)
GET /api/v1/shows/:id
✓ should return a single show
POST /api/v1/shows
✓ should add a show (50ms)
PUT /api/v1/shows/:id
1) should update a show
3 passing (804ms)
1 failing
1) API Routes PUT /api/v1/shows/:id should update a show:
Uncaught AssertionError: expected '' to be an object
Why? Because the updated ID of the test does not equal the ID passed in as a query parameter. What does this all mean? The unique ID should never change (unless it’s removed altogether).
// *** update show *** //
router.put('/shows/:id', function(req, res, next) {
if(req.body.hasOwnProperty('id')) {
return res.status(422).json({
error: 'You cannot update the id field'
});
}
queries.update(req.params.id, req.body)
.then(function() {
return queries.getSingle(req.params.id);
})
.then(function(show) {
res.status(200).json(show);
})
.catch(function(error) {
next(error);
});
});
Now, let’s revert the changes in the test, by removing id: 20,
, and add a new test:
describe('PUT /api/v1/shows/:id', function() {
it('should update a show', function(done) {
chai.request(server)
.put('/api/v1/shows/1')
.send({
rating: 4,
explicit: true
})
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('object');
res.body.should.have.property('name');
res.body.name.should.equal('Suits');
res.body.should.have.property('channel');
res.body.channel.should.equal('USA Network');
res.body.should.have.property('genre');
res.body.genre.should.equal('Drama');
res.body.should.have.property('rating');
res.body.rating.should.equal(4);
res.body.should.have.property('explicit');
res.body.explicit.should.equal(true);
done();
});
});
it('should NOT update a show if the id field is part of the request', function(done) {
chai.request(server)
.put('/api/v1/shows/1')
.send({
id: 20,
rating: 4,
explicit: true
})
.end(function(err, res) {
res.should.have.status(422);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('object');
res.body.should.have.property('error');
res.body.error.should.equal('You cannot update the id field');
done();
});
});
});
Run the tests:
API Routes
GET /api/v1/shows
✓ should return all shows (49ms)
GET /api/v1/shows/:id
✓ should return a single show
POST /api/v1/shows
✓ should add a show (51ms)
PUT /api/v1/shows/:id
✓ should update a show
✓ should NOT update a show if the id field is part of the request
Boom!
DELETE
Now on to the final test - the delete.
Red
Again, let’s use the ID of the first item in our database as the starting point for the test:
describe('DELETE /api/v1/shows/:id', function() {
it('should delete a show', function(done) {
chai.request(server)
.delete('/api/v1/shows/1')
.end(function(error, response) {
response.should.have.status(200);
response.should.be.json; // jshint ignore:line
response.body.should.be.a('object');
response.body.should.have.property('name');
response.body.name.should.equal('Suits');
response.body.should.have.property('channel');
response.body.channel.should.equal('USA Network');
response.body.should.have.property('genre');
response.body.genre.should.equal('Drama');
response.body.should.have.property('rating');
response.body.rating.should.equal(3);
response.body.should.have.property('explicit');
response.body.explicit.should.equal(false);
chai.request(server)
.get('/api/v1/shows')
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json; // jshint ignore:line
res.body.should.be.a('array');
res.body.length.should.equal(3);
res.body[0].should.have.property('name');
res.body[0].name.should.equal('Game of Thrones');
res.body[0].should.have.property('channel');
res.body[0].channel.should.equal('HBO');
res.body[0].should.have.property('genre');
res.body[0].genre.should.equal('Fantasy');
res.body[0].should.have.property('rating');
res.body[0].rating.should.equal(5);
res.body[0].should.have.property('explicit');
res.body[0].explicit.should.equal(true);
done();
});
});
});
});
The test ensure that the deleted show is returned and that the database no longer contains the show.
Green
Query:
function deleteItem(showID) {
return Shows().where('id', parseInt(showID)).del();
}
Route:
// *** delete show *** //
router.delete('/shows/:id', function(req, res, next) {
queries.getSingle(req.params.id)
.then(function(show) {
queries.deleteItem(req.params.id)
.then(function() {
res.status(200).json(show);
})
.catch(function(error) {
next(error);
});
}).catch(function(error) {
next(error);
});
});
The Knex delete()
function returns a number indicating the number of rows in the database that have been affected, so to return the deleted object, we must query for it first.
Let’s run those tests!!
API Routes
GET /api/v1/shows
✓ should return all shows (69ms)
GET /api/v1/shows/:id
✓ should return a single show
POST /api/v1/shows
✓ should add a show (54ms)
PUT /api/v1/shows/:id
✓ should update a show
✓ should NOT update a show if the id field is part of the request
DELETE /api/v1/shows/:id
✓ should delete a show
6 passing (1s)
6 tests written. 5 routes built. All tests passing!
Conclusion
So there you have it: A test-first approach to developing a RESTful API. Are we done? Not quite since we are not handling or testing for all possible errors.
For example, what would happen if we tried to POST an item without all the required fields? Or if we tried to delete an item that isn’t in the database? Sure the catch()
methods will handle these, but they are simply passing the request to the built-in error handlers. We should handle these better in the routes and throw back appropriate error messages and status codes.
Try this out on your own. Be sure to grab the code from the repository. Cheers!
Edits made by Bradley Bouley. Thank you!


This site was built by Prof. Eugene Callahan, Gordon Lei, and Rihui Zheng for use with CS-UY 4513 and 4523 at NYU Tandon School of Engineering.


fullObject:
some content
someID:
someOtherID:
anotherID:
{ "someID": "foo", "someOtherID": "bar", "anotherID": "baz" }
submit


Blast Mojo is a patterns-based JavaScript framework that provides a consistent event- driven architecture for complex client-side web applications, built on existing best-of- breed JS libraries. Its objectives are to provide a structured way of developing Rich Internet Applications, abstract complexities by separation of concerns, and maximize re-use of existing code, in order to maintain knowledge and improve on speed and quality of deliverables.
Lightweight (4kb gzipped), provides you with structure, and is a great framework for building event-driven mobile web or desktop web applications for your distributed teams. The only dependency is jQuery (Sizzle) for its fast selector engine.
var app = mojo.create({ baseSrc: 'js/' }); // Create a Mojo application instance
app
.map('#login-example', function() { // Map login-example as an implementation silo
return [
{ controller: "ExampleApp.LoginController" } // Bind controller(s) to login-example
];
})
.start()
var app = mojo.create({ baseSrc: 'js/' });
app
.configure('locale', 'en_US') // locale aware applications! (load different languages)
.configure('environment', 'prod') // dev or prod for debugging mode!
.configure('pluginSrc', 'js/lib/plugins/') // setup plugins location directory
.configure('plugins', ['jqmodal', 'jcarousel']) // automagically fetch my jQuery plugins!
.map('#registration-example', function() {
return [
{ controller: "ExampleApp.RegistrationController", params: { user: 123, firstName: "Johnson" }}
];
})
.map('#login-example', function() {
return [
{ controller: "ExampleApp.LoginController" }
];
})
.start()
/*! * The Blast Mojo Framework * * Copyright (c) 2011 Blast Radius * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */
Post patches to the Blast Mojo Mailing List or provide a github pull request to jbueza.
if (condition)
not if(condition)
functionName(parameters)
not functionName (parameters)
if
statements must have braces.


I am getting super excited for the End Game DLC:
Capture the Flag
Air Superiority!!
Dropship
Another winter map
Dirt bikes!
I can't wait!
BrainFooLong
Administrator
The one thing i really looking for is "the bike".
hooaahh that will be fun as hell.
Nano
Global Moderator
Jihad Bike 4tw!
Micha
dapil wrote:
I am getting super excited for the End Game DLC:
Capture the Flag
Air Superiority!!
Dropship
Another winter map
Dirt bikes!
I can't wait!
The features...is this official?
If yes....i have a new gamemode: Air Superiority
Post edited 1 x times, last by
juress
Theme Developer
juress
Theme Developer
Micha wrote:
dapil wrote:
I am getting super excited for the End Game DLC:
Capture the Flag
Air Superiority!!
Dropship
Another winter map
Dirt bikes!
I can't wait!
The features...is this official?
If yes....i have a new gamemode: Air Superiority
Yes, its official, except the winter map, don't know the source of that.
Battlelog:
End Game
March, 2013
Battlefield 3™: End Game delivers some of the most high-speed warfare to date across four vast maps. Race through enemy lines using the new dirt bike, bringing speed and agility to the Battlefield, or fight back aerial assaults with new lightweight AA vehicles. Coordinate lightning fast attacks and defenses in the return of the classic Capture the Flag game mode, or engage in massive dog fights in Air Superiority. In the skies, the new dropship introduces the ability to turn the tide with rapid deployment air drops of troop transports.
KEY FEATURES
- Four vast and varied maps designed for high-speed combat and action
- Three new vehicles including the fast and agile dirt bikes
- New dropship provides support to ground troops with vehicle drop capabilities
- Return of the classic Capture the Flag and Air Superiority game modes
Meaurk
Global Moderator
Holy mother of god! Air superiority sounds like heaven.
juress
Theme Developer
Meaurk wrote:
Holy mother of god! Air superiority sounds like heaven.
 Hate overpowered jets...
Meaurk
Global Moderator
Everything will be overpowered in that game mode, so at the same time it's balanced. :) Don't underestimate a good chopper pilot or annoying stinger fcks.

Sh*tloads of jets!!!!
Winter map confirmed!
http://www.youtube.com/watch?v=S1hNooLKEQs
http://www.youtube.com/watch?v=omI2dlt1ejs
ORFK
Global Moderator
dapil wrote:
Winter map confirmed!
WINTER?!? i see only desert... no snow. sorry ^^
Topicstarter
dapil
Plugin Developer
It's in blogpost on batttlelog blog.
Amkhatar
Theme Developer
I saw it will be one map for each season
Post edited 1 x times, last by
ORFK
Global Moderator
ORFK
Global Moderator
ahh yeah ^^ founded...
Road to End Game: High-speed warfare
-
http://eeel.ch/5b
(Official Battlefield Blog)
"
Our fifth expansion pack End Game is looming ever closer. In this first in-depth reveal we detail the overall scope of this massive themed expansion pack – bringing speed and agility to the Battlefield and introducing the all-new dirt bike..
Road to End Game: Creating the perfect dirt bike playground
http://eeel.ch/5h
(Official Battlefield Blog)
Head to the blog for behind the scenes footage - "
The dirt bike is one of the fastest and most agile vehicles ever in a Battlefield game. In this blog post, QA Analyst Malin von Matern explains how End Game became the perfect playground for this new and exciting ride...
Road to End Game: Creating the perfect dirt bike playground
http://eeel.ch/5h
(Official Battlefield Blog)
Head to the blog for behind the scenes footage - "
The dirt bike is one of the fastest and most agile vehicles ever in a Battlefield game. In this blog post, QA Analyst Malin von Matern explains how End Game became the perfect playground for this new and exciting ride...
Yup, it's looking awesome :)
I dont like the snow map tho.. it looks a bit stale if you knwo what I mean. It reminds me of firestorm... Just a flat field with a buch of stuff in the middle...
ORFK
Global Moderator
juress wrote:
Just a flat field with a buch of stuff in the middle...
i dont think thats in the middle. i think thats one base with the flag and on the other side it would be something similar. or it could be something beetween but i think the area around the flag points is a bit more covered, like buildings or factory ^^
Post edited 1 x times, last by
José Ortega
Global Moderator
José Ortega
Global Moderator
It looks awesome indeed, there is some BC2 flavour in those maps which is awesome.
Post edited 1 x times, last by
juress
Theme Developer
juress
Theme Developer
ORFK wrote:
juress wrote:
Just a flat field with a buch of stuff in the middle...
i dont think thats in the middle. i think thats one base with the flag and on the other side it would be something similar. or it could be something beetween but i think the area around the flag points is a bit more covered, like buildings or factory ^^
Yea but its just a flat map, nothing exiting for me...
Monkey with a mouse and keyboard could do that.
Looks like a BC2 map (wich i can't remember the name)...
Port Valdez :)
Post edited 3 x times, last by
BrainFooLong
Administrator
BrainFooLong
Administrator
All what i see in those 4 maps looks quite symetric,flat and clean, looks like a complete other style than the previous bf3 maps. Maybe the lead designer or some leading producer has changed?
This second screen remember an Armored Fury (BF2) Map: Operation Harvest
ORFK
Global Moderator
well... i know operation harvest really good. was one of my favorite BF2 Maps!
Operation Harvest was mostly with forests. a mix between the 4rd and 2nd map would be harvest ^^


flowchart LR 100 --> 103 100 --> 98
Binomial models
The idea is to develop an intuition for delta hedging and risk-neutrality when valuing an option.
- S is the stock price at the start (time \(t=0\))
- \(\delta t\) is a one increment of time (one unit of time)
- \(u\) is the factor when stock price rise
- \(v\) is the factor when stock price fall
- \(0<v<1<u\)
- \(V\) is the option value at time \(t=0\)
- \(V^+\) is the option value at expiration when stock is ITM (case of a call option)
- \(V^-\) is the option value at expiration when stock is OTM (case of a call option)
Delta hedging and no-arbitrage
Now we are going to introduce \(\Delta\) as the amount of stock to hedge (a percentage of a stock) to be risk-free. Because the portfolio is risk-free it must return the risk-free rate to prevent arbitrage.
We can model our stock and option as part of a portfolio (we call it \(\Pi\)). Hence, \[\Pi = V - \Delta \cdot S\] At this stage, we are assuming that the probability to go up or down is the same (it’s basically irrelevant in this case).
If we want to hedge the stock to be risk-free, then at expiration we should have this equation
\[V^+ - \Delta us = V^--\Delta vs\] Solving for \(\Delta\), we get:
\[\Delta = \frac{V^+-V^-}{(u-v)S} = \frac{\text{range of options payoff}}{\text{range of asset prices}} \tag{1}\]
In other words, we could see \(\Delta\) as the rate of change of the option price in function of the stock price. \(\Delta = \frac{\partial{V}}{\partial{S}}\)
Once we found \(\Delta\), we could find \(V\) by just making today’s value of the trade = tomorrow’s value of the trade (at expiration). Just solve for \(V\) \[V - \Delta S = V^- - \Delta vS\] or \[V - \Delta S = V^+ - \Delta uS\] which ever is easier to calculate.
Now, of course, cash is not free and there is a time value associated to it. In that sense, today’s value for the trade should be equal a discounted value of tomorrow’s trade value (at expiration).
The thinking is that if we want to hedge to be risk-free, it should return the risk-free rate otherwise there is an arbitrate opportunity. \[\Pi = V - \Delta S = \frac{1}{1+r \delta t} \left(V^- - \Delta vS \right)\]
- \(r\) is the value of the risk-free asset
- we are dealing with annualized values, if assets expires in one month and risk-free asset is let’s say 3%, we would multiply 3% by 21 days or \(0.03 \cdot \frac{21}{252}\)
Using our value of \(\Delta\) from Equation 1, we can isolate \(V\) as \[V = \left(\frac{V^+-V^-}{u-v} \right) + \frac{1}{1+r \delta t} \left(V^- - \Delta vS \right) \tag{2}\]
With delta-hedging, we say that the portfolio is deterministic (aka risk-free)
A stock is trading at $100. A call option with strike price of $100. Stock can either go to $103 or $98.
- \(V^+ = 3\)
- \(V^- = 0\)
- \(\Delta = \frac{3-0}{103-98} = \frac{3}{5}\)
- \(V - \Delta S = V^+ - \Delta us\), plugging the value from above we get \(V = \$1.2\)
The Risk-Neutral
Using the same idea as earlier and introducing some probabilities. \(p'\) is the risk-neutral probability.
flowchart LR S -- p' --> uS S -- 1-p' --> vS
From a probabilistic perspective we could write: \[S = p'uS + (1-p')vS\] Or in the presence of a risk free asset, \[S = \frac{1}{1+r \delta t} \left(p' uS + (1-p')vS \right)\]
We could isolate \(p'\) in this last equation: \[s + s r \delta t = p' u s + vs - p'v s\] \[p' = \frac{s + s r \delta t - vs}{us - vs}\] \[p' = \frac{1+r \delta t - v}{u-v} \tag{3}\]
flowchart LR V -- p' --> V+ V -- 1-p' --> V-
To find \(V\): \[V = p' V^+ + (1-p') V^-\]
Interesting to note that the option price \(V\) is like an expectation (the sum of the probability) and \(p'\) is from Equation 3
Actually, we should also include the discounted factor (V is the present value of the expectation): \[V = \frac{1}{1 + r \delta t} \cdot \left( p' V^+ + (1-p') V^- \right) \tag{4}\]
Mixing real-world and risk-free world
Now if we collide both world: the real-world with drift and volatility (Equation 2) and the risk-free world (Equation 4) with \(p'\): we can set up this 2 equations: One for the expected mean rate of change of prices and another for the variance of these rate of change.
\[ \begin{equation} \begin{cases} \mu S \delta t = puS+(1-p)vS-S \\ \sigma^2S^2dt = S^2 (p \cdot [u-1-(pu + (1-p)v-1)]^2 + (1-p) \cdot [v-1-(pu + (1-p)v-1)]^2) \end{cases} \end{equation} \]
(TODO re-write these 2 equations)
2 equations and 3 unknowns, we can choose a solution (the prettiest one!) among the infinitely many:
- \(u = 1 + \sigma \sqrt{\delta t}\)
- \(v = 1 - \sigma \sqrt{\delta t}\)
- \(p = \frac{1}{2} + \frac{\mu \sqrt{\delta t}}{2 \sigma}\)
- \(p' = \frac{1}{2} + \frac{r \sqrt{\delta t}}{2 \sigma}\) \(p'\) is the risk-neutral probability.
The binomial tree
- After one time step \(\delta t\) our stock, initially at \(S\) will either be at \(uS\) or \(vS\).
- After two time steps, the stock will either be at \(u^2S\) or \(uvS\) or \(v^2S\)
- After three time steps, the stock will either be at \(u^3S\) or \(u^2vS\) or \(uv^2S\) or finally \(v^3S\)
- etc.
A bit of a crude representation using Geogebra
Using the equations from the previous sections, we can now create a function to price the value of an option.
<- function(spot, strike, rfr, sigma, time, steps) {
calculate_option_price = time/steps # get delta_t
dt = 1 + sigma * sqrt(dt) # multiplying factor when asset rise
u = 1 - sigma * sqrt(dt)
v = 0.5 + (rfr * sqrt(dt)/(2*sigma))
p_prime = 1 / (1 + rfr * dt)
discount_factor
# Calculating vector of prices at maturity
= rep(0, steps+1) # initialize a vector for prices at maturity - (terminal nodes on the trees)
s 1] = spot * v^steps # #initialize the first end-price - (the most bottom right node of the tree)
s[for (i in 2:(steps+1)) {
= s[i-1] * u/v # this is the trick: to go up one leave = going back one step and then up
s[i]
}
# Calculating vector of options values at maturity
= rep(0, steps + 1)
opt for (i in 1:(steps+1)) {
= max(0, s[i] - strike)
opt[i]
}
# We have now to work backward and up in the trees (from bottom right and up)
# We know the final option value.
# We need know to calculate the options in the intermediates nodes
for (i in steps:1) {
for (j in 1:i) {
= discount_factor * (p_prime * opt[j+1] + (1 - p_prime)*opt[j])
opt[j]
}
}#print(glue::glue('Asset price for each time step:', s))
#print(glue::glue('Option price for each time step: ', opt))
return(opt)
}
Let’s try our function to get some results
calculate_option_price(spot = 100, strike = 100, rfr = 0.03, sigma = 0.1, time = 1, steps = 4)
[1] 5.415051 8.117623 11.822154 16.506917 21.550625


“The poetry is drugged, and as we read [Francis Thompson's] poems through in the order of their publication, we feel the power of the poppy more and more. At last the hand seems to lose its power and the will its control, though in flashes of sheer flame the imagination shows wild and beautiful as ever. His gorgeousness is beyond that of the Orient. The eccentric and arresting words that constantly amaze the ear, bring with them a sense of things occult yet dazzling, as if we were assisting at some mystic rite, in a ritual which demanded language choice and strange.” — John Kelman, Among Famous Books


EndTailImputer¶
-
class
missing_data_imputers.
EndTailImputer
(distribution='gaussian', tail='right', fold=3, variables=None)[source]¶ Transforms features by replacing missing data in each feature for a given value at the tail of the distribution.
This Imputer works only with numerical variables.
The estimator first calculates the values at the end of the distribution for the indicated features. The values at the end of the distribution can be given by the Gaussian limits or the quantile limits.
- Gaussian limits:
- right tail: mean + 3* std left tail: mean - 3* std
- Quantile limits:
right tail: 75th Quantile + 3* IQR left tail: 25th quantile - 3* IQR
where IQR is the inter-quantal range.
You can select to tune how far out you place your missing values by tuning the number by which you multiply the std or the IQR, using the parameter ‘fold’.
The transformer fills the missing data with the estimated values.
Parameters: - distribution (str, default=gaussian) – Desired distribution. Can take ‘gaussian’ or ‘skewed’.
- tail (str, default=right) – Whether the missing values will be placed at the right or left tail. Can take ‘left’ or ‘right’
- fold (int, default=3) – How far out to place the missing data. Fold will multiply the std or the IQR. Recommended values, 2 or 3 for Gaussian, 1.5 or 3 for skewed.
- variables (list) – The list of variables to be imputed. If none, it defaults to all numerical type variables.
-
imputer_dict_
¶ dictionary – The dictionary containing the values at end of tails to use to replace missing data for each variable. It is calculated when fitting the transformer.
-
fit
(X, y=None)[source]¶ Learns the values that should be used to replace mising data in each variable.
Parameters: - X (pandas dataframe of shape = [n_samples, n_features]) – The training input samples. Must be the entire dataframe, not just selected variables.
- y (None) – y is not needed in this transformer, yet the sklearn pipeline API requires this parameter for checking.


Four years after the sudden death of his wife, forty-year-old bestselling novelist Mike Noonan is still grieving. Unable to write, and plagued by vivid nightmares set at the western Maine summerhouse he calls Sara Laughs, Mike reluctantly returns to the lakeside getaway. There, he finds his beloved Yankee town held in the grip of a powerful millionaire, Max Devore, whose vindictive purpose is to take his three-year-old granddaughter, Kyra, away from her widowed young mother, Mattie. As Mike is drawn into Mattie and Kyra's struggle, as he falls in love with both of them, he is also drawn into the mystery of Sara Laughs, now the site of ghostly visitations and escalating terrors. What are the forces that have been unleashed here—and what do they want of Mike Noonan?
On a very hot day of August of 1994, my wife told me she was going down to the Derry Rite Aid to pick up a refill on her sinus medicine prescription -- this is stuff you can buy over the counter these days, I believe. I'd finished my writing for the day and offered to pick it up for her. She said thanks, but she wanted to get a piece of fish at the supermarket next door, anyway; two birds with one stone and all of that.  The next time I saw her, she was on TV. That's how you identify the dead here in Derry -- no walking down a subterranean corridor with green tiles on the walls and long fluorescent bars overhead, no naked body rolling out of a chilly drawer on casters; you just go into an office marked PRIVATE and look at a TV screen and say yep or nope.


JavaScript is disabled on your browser.
Skip navigation links
Overview
Package
Class
Tree
Deprecated
Index
Help
Prev
Next
Frames
No Frames
All Classes
SEARCH:
JavaScript is disabled on your browser.
Hierarchy For All Packages
Package Hierarchies:
ure
,
ure.actors.actions
,
ure.actors
,
ure.areas
,
ure.actors.behaviors
,
ure.commands
,
ure.sys.dagger
,
ure.examplegame
,
ure.math
,
ure.render
,
ure.terrain
,
ure.things
,
ure.ui
,
ure.ui.modals
Class Hierarchy
java.lang.Object
ure.sys.dagger.
AppModule
ure.examplegame.
ExampleGame
(implements ure.
UTimeListener
)
ure.
ExampleMain
ure.render.
FontTexture
ure.
Injector
com.fasterxml.jackson.databind.JsonDeserializer<T> (implements com.fasterxml.jackson.databind.deser.NullValueProvider)
ure.actors.
ActorDeserializer
ure.terrain.
TerrainDeserializer
ure.things.
ThingDeserializer
ure.terrain.
TerrainDeco
(implements ure.actors.actions.
Interactable
, ure.terrain.
UTerrain
)
ure.terrain.
TerrainI
(implements java.lang.Cloneable, ure.
UAnimator
, ure.terrain.
UTerrain
)
ure.terrain.
Blank
(implements ure.terrain.
UTerrain
)
ure.terrain.
Door
(implements ure.terrain.
UTerrain
)
ure.terrain.
Lava
(implements ure.terrain.
UTerrain
)
ure.terrain.
Pit
(implements ure.terrain.
UTerrain
)
ure.terrain.
Stairs
(implements ure.terrain.
UTerrain
)
ure.terrain.
Water
(implements ure.terrain.
UTerrain
)
ure.things.
ThingDeco
(implements ure.actors.actions.
Interactable
, ure.things.
UThing
)
ure.things.
ThingI
(implements java.lang.Cloneable, ure.actors.actions.
Interactable
, ure.things.
UContainer
, ure.things.
UThing
)
ure.things.
Blank
(implements ure.things.
UThing
)
ure.things.
Clothing
(implements ure.things.
UThing
)
ure.things.
Container
(implements ure.things.
UThing
)
ure.things.
Food
(implements ure.things.
UThing
)
ure.things.
Lightsource
(implements ure.things.
UThing
)
ure.actors.
UActor
ure.actors.
UNPC
ure.actors.
Blank
ure.actors.
UPlayer
ure.things.
Weapon
(implements ure.things.
UThing
)
ure.actors.actions.
UAction
ure.actors.actions.
UActionDrop
ure.actors.actions.
UActionEmote
ure.actors.actions.
UActionGet
ure.actors.actions.
UActionInteract
ure.actors.actions.
UActionPass
ure.actors.actions.
UActionWalk
ure.actors.
UActorCzar
ure.areas.
UArea
(implements java.io.Serializable, ure.
UTimeListener
)
ure.actors.behaviors.
UBehavior
ure.actors.behaviors.
UBehaviorWander
ure.areas.
UCartographer
ure.areas.
UCell
(implements ure.things.
UContainer
)
ure.things.
UCollection
ure.math.
UColor
ure.commands.
UCommand
ure.commands.
CommandDrop
ure.commands.
CommandGet
ure.commands.
CommandInteract
(implements ure.ui.modals.
HearModalDirection
)
ure.commands.
CommandInventory
ure.commands.
CommandPass
ure.commands.
CommandTravel
ure.commands.
UCommandMove
ure.commands.
CommandLatchE
ure.commands.
CommandLatchN
ure.commands.
CommandLatchS
ure.commands.
CommandLatchW
ure.commands.
CommandMoveE
ure.commands.
CommandMoveN
ure.commands.
CommandMoveS
ure.commands.
CommandMoveW
ure.
UCommander
(implements ure.render.
URenderer.KeyListener
)
ure.areas.
ULandscaper
ure.examplegame.
ExampleCaveScaper
ure.examplegame.
ExampleComplexScaper
ure.examplegame.
ExampleDungeonScaper
ure.examplegame.
ExampleForestScaper
ure.ui.
ULight
ure.ui.
ULightcell
ure.ui.
UParticle
(implements ure.
UAnimator
)
ure.math.
UPath
ure.render.
URendererOGL
(implements ure.render.
URenderer
)
ure.math.
USimplexNoise
ure.ui.
USpeaker
ure.terrain.
UTerrainCzar
ure.things.
UThingCzar
ure.ui.
View
ure.ui.
UCamera
(implements ure.
UAnimator
, ure.areas.
UArea.Listener
)
ure.ui.modals.
UModal
ure.ui.modals.
UModalDirection
ure.ui.
UREStatusPanel
ure.ui.
UScrollPanel
Interface Hierarchy
ure.sys.dagger.
AppComponent
ure.ui.modals.
HearModal
ure.ui.modals.
HearModalDirection
ure.actors.actions.
Interactable
ure.
UAnimator
ure.areas.
UArea.Listener
ure.things.
UContainer
ure.render.
URenderer
ure.render.
URenderer.KeyListener
ure.terrain.
UTerrain
ure.things.
UThing
ure.
UTimeListener
Skip navigation links
Overview
Package
Class
Tree
Deprecated
Index
Help
Prev
Next
Frames
No Frames
All Classes
JavaScript is disabled on your browser.


|
anon ymous donated $12.00
September 24, 2016
zaphodx, Crusty Bread, finalsA6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) B2 x1 (1 Orbital Launcher) zaphodx, Sweet Surprise, finals A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) B2 x1 (1 Orbital Launcher) |
|
Malte Vennemeyer donated $5.00
September 24, 2016
Reach for the stars guys ;-)
|
|
Don Keyboard donated $2.00
September 24, 2016
|
|
Kai Habermann donated $10.00
September 24, 2016
zaphodx, Ascendance, match4C3B x1 (1 Advanced Bot Factory) C3V x1 (1 Advanced Vehicle Factory) |
|
anon ymous donated $12.00
September 24, 2016
zaphodx, Tomato Soup, finalsA6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) B2 x1 (1 Orbital Launcher) zaphodx, Rusty Barbeque, finals A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) B2 x1 (1 Orbital Launcher) |
|
Nic Bestauros donated $6.00
September 24, 2016
elodea, Amalgam, match2A1 x3 (24 Boom) A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) boom bot spam op |
|
Malte Vennemeyer donated $5.00
September 24, 2016
Good luck and have fun guys !!
|
|
anon ymous donated $9.00
September 24, 2016
Admiral, Amalgam, match3A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) Admiral, Ascendance, match3 A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) Admiral, Gaia Haven, match3 A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) |
|
anon ymous donated $9.00
September 24, 2016
cola_colin, Amalgam, match4A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) cola_colin, Ascendance, match4 A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) cola_colin, Gaia Haven, match4 A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) |
|
[RLM]Doge sayed donated $25.00
September 24, 2016
Welcome back ZaphodX!
|
|
anon ymous donated $9.00
September 24, 2016
Alpha2546, Amalgam, match2A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) Alpha2546, Ascendance, match2 A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) Alpha2546, Gaia Haven, match2 A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) |
|
OrbitalNetwork donated $32.00
September 24, 2016
Alfredo, match3A1 x10 (80 Boom) B1 x4 (4 Vanguard) C3V x2 (2 Advanced Vehicle Factory) |
|
anon ymous donated $3.00
September 24, 2016
KillerKiwiJuice, Gaia Haven, match1A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) |
|
anon ymous donated $3.00
September 24, 2016
KillerKiwiJuice, Ascendance, match1A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) |
|
anon ymous donated $3.00
September 24, 2016
KillerKiwiJuice, Amalgam, match1A6B x1 (1 Bot Factory) A6V x1 (1 Vehicle Factory) A6A x1 (1 Air Factory) |
|
#ChocolateOrangesNot Penguins donated $4.00
September 24, 2016
cdrkf, match1A2 x3 (60 Land Mine) 20 on each planet at 5 minutes please preferably placed in weird shapes |
|
waku waku donated $10.00
September 24, 2016
D3 Clopse, 5 mins
|
|
Chris Warner donated $15.00
September 24, 2016
stuart98, Amalgam, match4C3B x1 (1 Advanced Bot Factory) D2 x1 (10 Locusts) Because he needs all the help he can get ;) #CashOutForHarambe |
|
Robert Footitt donated $15.00
September 24, 2016
Flubb, match3A1 x1 (8 Boom) A5 x1 (5 Pelican) B3 x1 (5 Inferno) D1 x1 (1 Omega) At 5 mins please |
|
Robert Footitt donated $15.00
September 24, 2016
theiban, Gaia Haven, match2E1 x1 (1 Colonel) st 5 mins please. |
|
. DeathByDenim donated $30.00
September 23, 2016
cdrkf, Amalgam, match1E1 x2 (2 Colonel) |
|
Lula Mae donated $15.00
September 23, 2016
clopse, match1A1 x5 (40 Boom) A2 x3 (60 Land Mine) A4 x2 (2 Hermes) C3B x1 (1 Advanced Bot Factory) On starting planet ASAP |
|
Anonymous donated $10.00
September 23, 2016
|
|
PRoeleert The Amazing donated $50.00
September 23, 2016
ljfed, match1A1 x8 (64 Boom) A2 x1 (20 Land Mine) A5 x1 (5 Pelican) C1 x1 (2 Lob) C2 x1 (2 Teleporter) E1 x2 (2 Colonel) Directly After the 5 min delay All on start planet except 1 teleporter on a planet of choice From the Amazing PRoeleert |
Get the word out


Bolivia leader warns of bloodshed as opponents vow to oust him
by AFPLA PAZ: Bolivia’s government accused its rivals Sunday of plotting deadly violence against it after an opposition figure vowed to oust leftist President Evo Morales and called for the military’s support.
Deadly unrest has gripped the South American country since Morales was named winner of the October 20 election for a fourth term.
His opponents have branded the result a fraud, and Carlos Mesa, who ran against Morales in the recent polls, has called for a new vote to be held.
“We believe… that the best solution to this crisis in the current circumstances is a new election, administered by an impartial new (electoral body) and with rigorous observation of the international community,” Mesa said Sunday.
Late on Saturday, a conservative opposition leader in the eastern Santa Cruz region threatened to drive Morales out.
“He has 48 hours to step down, because at 7pm (2300 GMT) on Monday, we are going to take decisive action right here and we are going to make sure that he goes,” Luis Fernando Camacho told a gathering of supporters.
He called on the military to “be on the side of the people.”
Morales responded by accusing his opponents of seeking bloodshed.
“They want people to be killed by the police and the military,” he said in a televised interview.
Interior Minister Carlos Romero alleged a “coup strategy” was under way.
He told reporters the government had intelligence “indicating that a violent confrontation is being prepared” for Monday night near the presidential palace in La Paz.
“Whoever asks for military intervention is asking for blood and is asking for death,” Romero said.
Camacho did not specify what kind of action he had in mind. His supporters have previously taken over public buildings.
The military has so far stayed neutral in the electoral dispute but calling on it to intervene is a delicate move in Bolivia.
The country saw numerous military uprisings and dictatorships before civilian rule was established in 1982.
Morales is looking to remain in power until 2025 with a fourth term.
His election win was ratified by the Supreme Electoral Tribunal — but only after an abrupt and unexplained shift in the vote count in his favour.
The Organisation of American States is carrying out an audit of the vote. The opposition has rejected that as a distraction to help Morales hold on to power.
Bolivia’s constitution limits a president to two successive terms. But the constitutional court authorised Morales to stand for a fourth mandate.
The court, like the election tribunal, is made up of members appointed by Morales’s Movement for Socialism.
The interior minister last week said two demonstrators were killed in clashes. State authorities say 140 people have been hurt in the unrest.
Unrest has also erupted in recent weeks in other Latin American countries, including neighbouring Chile and Ecuador where protesters are angry at economic hardship.


Hello. I am Mariya.
Welcome to my web-site.
Some information about me.
I am:
* Serious
* Observant
* Resonable
And these are 3 of my states:
Happy Sad Now
My favorite quote is:
All that we are is the result of what we have thought. ― Gautama Buddha
MY FAVORITE MOVIES:
I live in Kharkiv.
It is the second-largest city in Ukraine and has a population of 1.5 million
people.
Kharkiv was the first capital of the Ukrainian, from December 1919 to January
1934, after that the capital relocated to Kiev.
There are 6 museums, 7 theatres and 80 libraries.
Presently, Kharkiv is a major cultural, scientific, educational, transport and
industrial centre of Ukraine.
Kharkiv is the largest city at 50 parallel.
Kharkiv is not considered the largest city in Ukraine and neighboring countries, but if
you draw an invisible line of 50 parallels, then it is really the largest.
Kharkiv is an international student city.
Due to the large number of universities with directions for foreign students,
from September to June in the streets you can meet people from all over Africa, Asia,
Europe and Latin America.
For the first time the atomic nucleus was cleaved in Kharkov.
A group of scientists led by Georgy Latyshev split the nuclear core in Kharkov for the
first time. This event took place in 1932 at the Physicotechnical Institute.
Depth of Pushkinskaya metro station.
Metro station "Pushkinskaya" on the Saltovskaya branch has a depth of 10-storey house,
that is, 35 meters. The Pushkin station was built in 1984, it is decorated with reliefs and compositions from
the life of the famous Russian poet Alexander Pushkin. This is the deepest station of the Kharkiv Metro.
Adress: Pushkinskaya street 79/1
Telephone number: +38(050)61-96-498


{% if page.comments_id %} {% capture github_base_url %}{{ site.author.github }}/{{ site.author.github }}.github.io/issues/{{ page.comments_id }}{% endcapture %} {% capture github_url %}https://github.com/{{ github_base_url }}{% endcapture %}
Want to leave a comment? Visit this post's issue page on GitHub.
Comments
Want to leave a comment? Visit this post's issue page on GitHub.


Survey Questions
About You
Name (Required)
Link to Photo Image (Required)
Question 1
You like animals.
Select and Option
1 (Strongly Disagree)
2
3
4
5 (Strongly Agree)
Question 2
You get frustrated easily when you think others are acting "dumb."
Select and Option
1 (Strongly Disagree)
2
3
4
5 (Strongly Agree)
Question 3
You are impulsive.
Select and Option
1 (Strongly Disagree)
2
3
4
5 (Strongly Agree)
Question 4
You like activities that involve water.
Select and Option
1 (Strongly Disagree)
2
3
4
5 (Strongly Agree)
Question 5
You enjoy spending time outdoors.
Select and Option
1 (Strongly Disagree)
2
3
4
5 (Strongly Agree)
Question 6
You can relate to most people.

Select and Option
1 (Strongly Disagree)
2
3
4
5 (Strongly Agree)
Question 8
You prefer science-fiction and fantasy over non-fiction and documentaries.

Select and Option
1 (Strongly Disagree)
2
3
4
5 (Strongly Agree)
Question 10
When it comes to friends, you believe quality over quantity.
Select and Option
1 (Strongly Disagree)
2
3
4
5 (Strongly Agree)
Submit
Required Fields
×
You have left some questions unanswered.
Please go back and answer all of the questions.
Your New BFF!
×
Hello, friend! My name is


The personal questionnaire for part-time Bachelor programmes
PERSONAL DATA
Surname (family name):
Name (names) /first name/:
Gender:
male
female
Father's first name:
Mother's first name:
Date of birth:
Place of birth:
Citizenship (country):
BELARUS
GERMANY
LITHUANIA
POLAND
RUSSIAN FEDERATION
SLOVAKIA
UKRAINE
Nationality:
Permanent Residence Card:
applicable to foreign residents
Card of the Pole:
applicable to foreign residents
Your visa: country of issue:
applicable to foreign residents
BELARUS
GERMANY
LITHUANIA
POLAND
RUSSIAN FEDERATION
SLOVAKIA
UKRAINE
Country of origin:
BELARUS
GERMANY
LITHUANIA
POLAND
RUSSIAN FEDERATION
SLOVAKIA
UKRAINE
IDENTIFICATION DATA
PESEL No.:
ID/Passport No.:
Passport/ID card expiration date:
PERMANENT ADDRESS
Country:
BELARUS
GERMANY
LITHUANIA
POLAND
RUSSIAN FEDERATION
SLOVAKIA
UKRAINE
Postal code, City:
Street, number:
CORRESPONDENCE ADDRESS
applicable if different then the official address
Country:
BELARUS
GERMANY
LITHUANIA
POLAND
RUSSIAN FEDERATION
SLOVAKIA
UKRAINE
Postal code, City:
Street, number:
DISABILITY DETAILS
Candidate with disabilities:
Loss of or poor hearing ability
Blind persons or those with poor sight
Mobility dysfunction, able to walk
Mobility dysfunction, unable to walk
Other disabilities
CONTACT
Home telephone number:
Mobile:
Email:
ATTENDED SECONDARY SCHOOL
Type of school:
secondary-school attended abroad
secondary-school attended in Poland
Full name of attended school:
Place:
Year of graduation:
Number of school leaving certificate:
Date of certificate:
FINAL SECONDARY SCHOOL EXAMINATION
Basic Level
biology
chemistry
geography
history
knowledge of society
mathematics
physics
% points
Advanced Level
biology
chemistry
geography
history
knowledge of society
mathematics
physics
% points
Foreign language - Basic Level:
% points
Foreign language - Advanced Level:
% points
TYPE OF UNIVERSITY PROGRAMMES
Class sessions:
1 (classes from Monday to Thursday)
Major study programme and
place of studies 1:
Finance and Accounting - Corporate finance and accounting
International Economic Relations - International Business
Kraków
Major study programme and
place of studies 2:
Finance and Accounting - Corporate finance and accounting
International Economic Relations - International Business
Kraków
Major study programme and
place of studies 3:
Finance and Accounting - Corporate finance and accounting
International Economic Relations - International Business
Kraków
Number of CUE's album:
If you are a student or graduate of CUE,
enter your album's number


september 2019
Reinforcement Learning as a valid solution for real problems
Edurado Pereira
Concolutional Neural Networks and Image Classification
João Matias
Artificial Intelligence vs Augmented Intelligence
Ricardo Pereira
september 2018
Reinforcement Learning as a valid solution for real problems
Edurado Pereira
Concolutional Neural Networks and Image Classification
João Matias
Artificial Intelligence vs Augmented Intelligence
Ricardo Pereira


System Architect Symbol details for "Heading"
Heading (Class)
- Description:
Method of grouping "Subject Phenomena".
Heading/Essential Type (Generalization Node)
- Base Class:
Heading
- Definitions Used:
-
Heading (Class)
Phenomenon As Heading (Class)
- Description:
"Heading" being a "Subject Phenomenon" used as a heading for one or more other "Subject Phenomena".
- Comment:
For instance, a clinician may wish associate all relevant properties and activities with a "focus"
property. A myocardial infarct may act as the focus for an emergency admission, a subsequent by-pass
procedure, follow up medication and physiotherapy.
Standard Heading (Class)
- Child Diagrams:
-
Standard Heading (
UML Class)
- Description:
Method for an "Agent" to subdivide "Subject Phenomena".
- Comment:
Note that Headings may be devised by a variety of authorities and may be orthogonal.


Tutorial #9
- Font Creation
- Creating a glyph (tracing outlines)
- Create glyph outlines using spiro points
- Importing a glyph from Inkscape (or Illustrator, or some other vector editor)
- Navigating to other glyphs
- On to the next glyph (consistent directions)
- Consistent serifs and stem widths
- Building accented glyphs
- Building a ligature
- Examining metrics
- Kerning
- Glyph variants
- Anchoring marks
- Conditional features
- Checking your font
- Bitmaps
- Generating it
- Font Families
- Final Summary
- Opening & Importing Bitmap strikes
- Creating Bitmap Strikes
- Bitmap Properties
- Creating a bitmap only font
- Bitmaps in the Font View
- Editing Bitmaps
- Sparse Bitmap Strikes
- Scripting Tutorial
- Notes on various scripts
Opening & Importing Bitmap strikes
FontForge is primarily an outline font editor, but it does have some facility for editing bitmap (and greymap, or anti-aliased) fonts. A useful term here is a "strike"; a strike is one particular size of a bitmap font. When FontForge displays a font, that font will contain at most one outline but potentially many bitmap (or greymap) strikes (for several different pixel sizes).
You might wonder if it is really necessary to provide bitmaps along with outlines given the high quality results of modern rasterizers, and for Latin (Greek, Cyrillic) fonts it may not be, but for CJK fonts at small pixel sizes a human eye can still make a better choice than even the best rasterizer. Back in the 1980s when Apple first adopted PostScript fonts they felt it was essential to have bitmaps to go with the outline -- so much so that it was not even possible to use a PostScript font without also providing at least one bitmap with it. Even today, when using a Type1 font on a mac there must be a bitmap font to point to it.
Of course Type1 fonts are a bit old-fashioned now, but the sfnt file format (the format used for both OpenType and TrueType fonts) supports embedded bitmap strikes along with the outline version of the font. These strikes will be used in preference to rasterizing the outline in any pixel sizes for which they are present.
If you have an sfnt with both an outline font and bitmap strikes you can open it directly with the File->Open command and FontForge will load all the bits and pieces.
You can also open a bitmap only font directly with the File->Open command, however if you have multiple strikes of the same underlying font in separate files, you will probably want to open only the first (or only the outline version) with Open, and use File->Import to merge the other strikes into one FontForge font.
Suppose you have Ambrosia.pfb
(an outline font), Ambrosia-12.bdf
, and Ambrosia-24.bdf
(two bitmap strikes, one 12 pixels high, one 24), and you want them all in one font. First use File->Open to open Ambrosia.pfb, then File->Import and select both of the bitmap strikes (hold down the shift key).
On the other hand, if you have only two bitmaps: Ambrosia-12.bdf
, and Ambrosia-24.bdf
, then use File->Open to open either strike, and use File->Import and import the other.
You may have noticed that Import has a checkbox labeled [] As Background
. If you check this, then your bitmap font will not be loaded as a font itself, but will be loaded into the background of the outline font whence you can Element->Autotrace
it to provide an outline font from a bitmap. Be warned: This produces fairly bad results unless you have a large (100+ pixel) font to trace.
Creating Bitmap strikes
If you want to add a bitmap strike with a given pixel size to a font then use Element->Bitmap Strikes Available
. Simply add the pixel size you are interested in to the list at the bottom of the screen.
If you are more comfortable dealing in point sizes, be aware that those depend on screen resolution. This dialog shows you the conversion between point and pixel sizes for two standard resolutions. The resolutions differ depending on what windowing system you use.
You may add more than one pixel size, of course. You may also remove pixel sizes if you no longer want them.
Normally when you create a new strike it will be rasterized from the outline font -- if there is no outline font then FontForge will attempt to scale the biggest strike available to the new size (in most cases this will be fairly ugly, but it may be better than nothing.
There is also a checkbox [*] Create Rasterized Strikes (Not empty ones)
at the bottom of the dialog. If you turn this off, then the rasterization process described above will not happen, and any new strikes will be created containing no glyphs (you can add glyphs later, of course).
Bitmap Properties
In the old days of bdf and pcf fonts on X11 each font had a set of properties attached to it. It is not clear to me whether these properties are still useful as X11 moves to OpenType Bitmaps. They may be. At any rate FontForge will store them both in BDF fonts and in OpenType Bitmap fonts. Each strike may have its own set of properties. FontForge will generate them automatically when you create a strike (and will retain them when it reads in a font that has them). You may override the current values with the Element-Bdf Info
dialog.
Creating a new bitmap only font
If you want to create a new font with no outlines, only bitmap strikes, you would use File->New to create a new font, and then Element->Bitmap Strikes Available
to add some (empty) strikes to it. As soon as you add a strike to a new font, the font will become a bitmap only font.
Apple has a bitmap only version of the sfnt file format, and X11 does too. Of course the two formats are slightly different. Windows has no support for a bitmap only sfnt format.
Bitmaps in the Font View
The View
menu of the Font View (and the Metrics View) contains a list of all bitmap strikes in the font. You may select which one will be displayed in the Font View. You may also change the magnification at which a strike is displayed with View->Bitmap Magnification... (it can be hard to see the details of an 8 pixel font on a high resolution screen, so you might want to display it at 3 times its actual size).
Many commands in the Font View will apply to all strikes (and the outline) in the font. For instance Edit->Copy
will copy the outline glyph and all bitmap glyphs. Sometimes you only want to affect one strike, if so then deselect Edit->Copy From->All Fonts
.
The Element->Build
commands will build accented bitmap glyphs just as it builds accented outline glyphs.
If the Font View is displaying a bitmap strike and you double click on a character, then FontForge will bring up a bitmap editing window displaying that character in the current strike (rather than opening an outline editing window). If the character does not have a matching glyph in the current strike FontForge will create one by rasterizing the outline version of the font.
Editing Bitmaps
The bitmap editing window should be fairly self explanatory. The window is a simple bitmap editor. With the pencil tool, clicking on a pixel will make it change. The line tool will draw a straight line between the start and end points.
You can see the outline glyph in the background of the bitmap.
You can regenerate the bitmap (by rasterizing the outline) by pressing the [Recalculate Bitmaps]
button.
Editing an anti-aliased greymap has the added complexity that you need to select a color (actually a level of greyness) to be applied with the pencil. There will be an additional palette with all possible greys for this.
Sparse Bitmap Strikes ---------------------
Sometimes you don't need a complete set of bitmap glyphs in a strike. Perhaps the rasterizer does a good job for all glyphs except one. Then you can create an empty strike (with Element->Bitmap Strikes Available
unchecking the [*] Create Rasterized Strikes
checkbox) and then select the one glyph you care about and say Element->Regenerate Bitmap Glyphs
.
Alternately you could create a fully rasterized strike and then select the glyphs you don't need and say Element->Remove Bitmap Glyphs
.


Password reset
@IfNot.SuccessEnter your email to have a new password sent to you
@EndIf @If.SuccessAn E-Mail with your new password should be in your inbox soon (if not make sure to check your spam folder)
@EndIfEnter your email to have a new password sent to you
@EndIf @If.SuccessAn E-Mail with your new password should be in your inbox soon (if not make sure to check your spam folder)
@EndIf


Before Change
unit tests for MLENgramModel class
def setUp(self):
self.model = MLENgramModel(self.bigram_counter)
def test_unigram_score(self):
// total number of tokens is 14, of which "a" occured 2 times
self.assertUnigramScoreEqual(2.0 / 14, "a")
After Change
unit tests for MLENgramModel class
def setUp(self):
vocab = NgramModelVocabulary(["a", "b", "c", "d", "z", "<s>", "</s>"], unk_cutoff=1)
training_text = [list("abcd"), list("egadbe")]
self.model = MleLanguageModel(2, vocabulary=vocab)
self.model.fit(training_text)
def test_unigram_score(self):
// total number of tokens is 14, of which "a" occured 2 times
self.assertUnigramScoreEqual(2.0 / 14, "a")


{% load i18n %}
{% blocktrans trimmed %} At their last login, did this user meet the criteria set forth in the terms of use? {% endblocktrans %}
{% trans "No" %}
{% blocktrans trimmed with username=editor.wp_username %} {{ username }} may still be eligible for access grants at the coordinators' discretion. {% endblocktrans %}
{% blocktrans trimmed %} In particular, editors who meet the criteria, but whose activity is spread across multiple wikis, may be erroneously marked as unqualified. The Library Card Platform only checks for home wiki activity. {% endblocktrans %}
{% endif %}{% blocktrans trimmed %} The following information is visible only to you, site administrators, and (where required) publishing partners. It is not visible to volunteer Wikipedia Library coordinators. {% endblocktrans %}
{% url 'users:pii_update' as update_url %} {% blocktrans trimmed %} You may update or delete your data at any time. {% endblocktrans %}
{% trans "This will be automatically updated from Wikipedia." %}


A ticket you subscribed to just got a price change!
From {{ origin.cityName }} to {{ destination.cityName }}
Price: {{ price }}
Date: {{ date }}
Departure Time: {{ departureTime }}
Arrival Time: {{ arrivalTime }}


In this second blog post I go over how to loads scripts in the mongo shell and how to automate tasks in mongo shell
Loading scripts in the Mongo Shell
You can load scripts in the mongo shell as long as the mongo shell knows the path.
Let us get mongodb running with the following bash script:
#! /bin/bash
docker run --name jbelmont-mongo-image-4 \
--rm \
-v ~/mongod_data.4.0.5:/data/db \
-p 27017:27017 \
-v /var/run/docker.sock:/var/run/docker.sock \
-d jbelmont/mongo-vim:4.0.5
Notice that this is a custom docker image that I created
Not let us say that we wanted to write a script that shows all the numbers in the numbers collection and in particular the val field.
In the mongo shell we could get it like this:
Now let us write a script in a javascript file to do the same thing:
"use strict";
db = connect("localhost:27017/nosql_workshop");
db.numbers.find({}).forEach(num => print(num.val));
We will put this script in the following path in my computer:
/Users/jean-marcelbelmont/go/src/github.com/jbelmont/nosql-workshop/scripts
The mongo shell needs to know the path in order to load the script. Notice that we used the native function pwd()
to verify the path and then we passed in the path to our script in the load()
function.
We can set an environment variable in our ~/.bashrc,~/.zshrc for our mongodb scripts like this:
echo $MONGO_SCRIPT_PATH
/Users/jean-marcelbelmont/go/src/github.com/FoodLogiQ/playground/scripts
Now we can call the javascript file outside of the mongo shell like this:
Notice how we used the environment variable of $MONGO_SCRIPT_PATH here and then just invoked our script file.
Some advantages of using the javascript file instead of the mongo shell is that the mongo shell has limits when you copy and paste large BSON objects and can explode at times.
If you use your javascript file you can use all the power of ESNext JavaScript features to do CRUD Operations in MongoDB.
Let us create the following script that stores 2 numbers in the numbers collection and then prints out the val field in the first number:
"use strict";
db = connect("localhost:27017/nosql_workshop");
let id1 = new ObjectId();
let id2 = new ObjectId();
let numbers = [
{
"_id": id1,
"val" : 2.1,
"description" : "Decimal"
},
{
"_id": id2,
"val": 3.1,
"description" : "Decimal"
}
];
db.numbers.insertMany(numbers);
let num1 = db.numbers.find({
_id: id1
})[0].val;
print(num1);
Let us run the new script like this:
Now in the mongo shell we can look at our newest documents that we have added:
Adding global configuration with ~/.mongorc.js
I have the following defined in my ~/.mongorc.js:
DBQuery.prototype._prettyShell = true
DBQuery.prototype.unpretty = function () {
this._prettyShell = false;
return this;
}
currentDir = pwd()
currentDir = currentDir.split("/").slice(0, -1).join("/")
callScript = function(script_name) {
load(`${currentDir}/playground/scripts/${script_name}`);
}
So from the top I have defined pretty print to be the default and have created a function called unpretty to get the regular behavior.
Notice that we can define functions in JavaScript and we can use ESNext Features in JavaScript.
I created a custom function called callScript that calls the load script function but takes an argument for the script name and looks at your current shell path.
Looks like at a live example using the callScript command and a new JavaScript file:
"use strict";
let ids = [];
for (let i = 0; i < 10; i++) {
let objectId = new objectId()
ids.push({
_id: objectId
});
}
printjson(ids);
Here we create an array of objects with ObjectIds in the mongo shell.
Here is an example session in the mongo shell:
Notice here that we called the javascript file without passing a path because we have defined the script path location in the callScript function definition already.
There is a lot more you can do with scripts if you use your imagination :)
Please follow me at jbelmont @ github and jbelmont80 @ twitter
Feel free to leave a comment if you like.
Until Next Time :)


What is bakuchiol? It’s time we know about retinol’s alternative
Bakuchiol unlike retinol is not harsh on the skin and has been used for many centuries in Ayurvedic and Chinese ingredients. Read more if you want to add this to your skincare regime.
by Lifestyle DeskIf skincare is your thing, we bet you know about retinol. While for all those who are new to this arena, retinol is skincare aficionados’ favourite magical potion. It is a vitamin A derivative responsible for stimulating collagen production and accelerating skin cell renewal to help reduce fine lines and wrinkles. But the ingredient can often be harsh on sensitive skin and cause signs of irritation like redness, peeling, and itching.
Since it doesn’t go down well with certain skin types, the beauty industry has searched extensively for a natural alternative that is not hard on the skin. The good news is that they’ve found it, and bakuchiol is becoming hotter than ever.
Scroll down to know everything about this trending skincare ingredient.
What is bakuchiol?
Bakuchiol, which is pronounced “buh-koo-chee-all”, is simply a plant derivative from the seeds and leaves of Eastern Asia’s ‘babchi’ plant (or psoralea corylifolia). A little FYI, this component has been used for thousands of years in Ayurvedic and Chinese ingredients. A major reason to impose faith and involve it in your skincare regime, isn’t it?
Benefits of bakuchiol
While retinol comes from the family of Vitamin A, bakuchiol is derived from a natural plant. However, they have incredibly similar effects, including an increase in collagen production stimulation and reduced hyperpigmentation.
However, unlike retinol, bakuchiol provides these skin benefits without any uncomfortable side-effects. As much as we love retinol, we cannot look over the fact that some skin types struggle with it, particularly in terms of sensitivity, redness and irritation. Retinol also increases the skin’s sensitivity to the sun, meaning it’s best used at night only and in the day you have to amp up your SPF.
However, Bakuchiol, is different and can potentially be used by those with more sensitive skin.
Is bakuchiol better than retinol?
We are pretty sure, this question would be lingering on your mind. Let us tell you that almost all skin types can benefit from the use of bakuchiol. It is ideal for anyone who cannot tolerate retinol, such as patients with sensitive skin or rosacea, or anyone on the lookout for a non-irritant, natural ingredient with anti-ageing benefits. Also, thanks to bakuchiol’s antibacterial properties, it’s also suitable for acne-prone skin as a topical treatment.
How do we apply bakuchiol?
While retinol works best when applied at night, bakuchiol can be used in the morning or at night, as it does not increase the skin’s sensitivity to the sun. As it is also brilliant for sensitive skin, you don’t need to build up to using it or start slow; you can dive right in if you want to.


Parameter expansion starts with unexpected quotes. Double check syntax.
echo ${"Hello World"}
echo $"Hello World"
ShellCheck found a parameter expansion ${...}
that contains an unexpected syntax element, such as single or double quotes.
In the example, this was due to wrapping a translated string $".."
with curly braces, which is not valid.
It is unclear what the intention is with invalid expansions like ${'foo'}
, ${$"foo"}
, so please look up how to do what you were trying to do.
If this warning triggers for working code, please submit a bug.


TABLE OF CONTENTS
A. GS1 Related B. GS2 Related POLITY 1. New J&K surrender policy to target local militants 2. J&K government to set up ‘milk villages’ 3. ‘Dispose of old cases in mission mode’ 4. Making caste slur on SC/STs over phone an offence, says SC 5. 210 govt. websites made Aadhaar details public: UIDAI 6. Govt. nod to suggestion on Haj quota increase C. GS3 Related ECONOMY 1. RBI to launch multimedia campaign 2. Centre to spur local electronics output 3. Centre readies institutional body to push electric mobility 4. ‘India up one notch in per capita GDP’ INTERNAL SECURITY AND DEFENSE RELATED DEVELOPMENTS 1. Tejas world-class fighter jet, plays defined role’ MISCELLANEOUS NEWS 1. ‘Trump village’ gets the biggest toilet pot model D. GS4 Related E. Prelims Fact F. UPSC Prelims Practice Questions G. UPSC Mains Practice Questions
Nothing here for Today!!!
1. New J&K surrender policy to target local militants
Fresh surrender policy:
- Earlier, the surrender policy was limited to those who crossed the Line of Control into Pakistan-occupied Kashmir in the early 1990s and were stuck there.
- The new surrender policy is considering provision of “passports and jobs to any local youth who gives up the gun” and “support for his full assimilation into society.
2. J&K government to set up ‘milk villages’
In news:
- The Jammu and Kashmir government has hit upon the idea of setting up ‘milk villages’ across the State in an attempt to bridge the demand-supply deficit of milk.
- Under this ambitious project of the Animal Husbandry Department, 50 identified beneficiaries of the village will be provided 100% subsidy to establish dairy farm units on modern lines.
- The project would also provide an opportunity to Gujjars — the main milk producer’s group — to grow up economically and contribute to the State.
- Establishing ‘milk villages’ will not only improve the standard of life of the community, but also boost the economy and social status of the tribe.
3. ‘Dispose of old cases in mission mode’
In news:
- Union Law Minister Ravi Shankar Prasad urged judges of the High Courts and the district courts to work in a ‘mission mode’ to dispose of all 10-year-old pending cases as quickly as possible.
- He also called upon lawyers to give pre-litigation services and start pro bono advocacy to give honest, credible and free legal advice to the poor.
4. Making caste slur on SC/STs over phone an offence, says SC
In news:
- The Supreme Court has ruled that using casteist remarks over phone in a public place against the Scheduled Caste and Scheduled Tribe category amounts to criminal offence, warranting a jail of a maximum five years.
- The apex court refused to stay criminal proceedings and quash an FIR against a person, who allegedly used derogatory casteist remarks over phone to a woman from the the SC/ST category.
5. 210 govt. websites made Aadhaar details public: UIDAI
In news:
- More than 200 central and State government websites publicly displayed details such as names and addresses of some Aadhaar beneficiaries
- The UIDAI took note and got the Aadhaar data removed from the said websites
UIDAI and Data security:
- UIDAI has a well-designed, multi-layer approach robust security system in place
- It is being constantly upgraded to maintain the highest level of data security and integrity
- The architecture of the Aadhaar ecosystem has been designed to ensure data security and privacy which is an integral part of the system from the initial design to the final stage
How does UIDAI ensure data security?
- Various policies and procedures have been defined, these are reviewed and updated continually
- This helps to appropriately control and monitor any movement of people, material, and data in and out of UIDAI premises
- Security audits are conducted on a regular basis to further strengthen security and privacy of data
6. Govt. nod to suggestion on Haj quota increase
In news:
- The government has accepted a high-level committee’s recommendation of increasing by over 3% the quota of private tour operators sending Haj pilgrims to Saudi Arabia.
- The high-level committee formed by the government to frame the draft ‘Haj Policy 2018-2022’ had made the recommendation last month.
- The committee had recommended that the quota of private tour operators be increased from the present 26.47% to 30%.
- Key fact: India has an annual Haj quota of 1.70 lakh. Out of this, according to the allocation for 2017, 1.25 lakh pilgrims could travel to Saudi Arabia through the Haj Committee of India (HCoI).
1. RBI to launch multimedia campaign
Context:
- New innovative approach to educate the citizens.
In news:
- The Reserve Bank is planning to launch a full-fledged multimedia and multilingual campaign to create general awareness among citizens of its regulations and initiatives.
- The RBI’s communication department has sought applications from advertising agencies for designing the creatives for the pan-India awareness campaign.
- The campaign will be in 14 languages — Hindi, Assamese, Bangla, Gujarati, Kannada, Malayalam, Marathi, Odia, Punjabi, Sindhi, Tamil, Telugu, Urdu, and English — with focus on regional languages.
- The media mix will include traditional ones such as newspapers, magazines, radio, television channels and cinema halls and new ones that include digital.
- It also plans to create an awareness campaign — Suno RBI Kya Kehta Hai — through SMSs to warn the public against falling prey to unsolicited and fictitious offers from fraudsters.
2. Centre to spur local electronics output
Context:
- Net zero imports in electronics by 2020
In news:
- The government is set to bring out a new policy to spur domestic electronics production by March 2018 in a bid to boost its flagship ‘Make in India’ programme and curb the country’s trade deficit.
- The government had first unveiled an Electronics Manufacturing Policy in 2012 , which included schemes such as Modified Special Incentive Package Scheme and electronic development fund.
- The new policy is likely to take a re-look at the utility of these schemes which have either ended or will expire soon.
- Innovation, R&D: the revised National Policy on Electronics will strive to increase the competitiveness of the electronics manufacturing industry; innovation, R&D and start-ups; promoting research in emerging technologies and India-specific initiatives and strategies to promote/ incentivise exports in electronics system design and manufacturing.
- Key Fact: Domestic consumption of electronic hardware in India was $63.6 billion in 2014-15. Imports stood at $36.9 billion, as per NITI Aayog.
3. Centre readies institutional body to push electric mobility
In news:
- The government plans to set up a committee for an institutional framework on large-scale adoption of electric vehicles in India as a viable clean energy mode — particularly for shared mass transport — to help bring down alarming levels of pollution in big cities.
- The government think-tank NITI Aayog has sought comments from Ministries, including heavy industry, environment, road, transport and highways, and power on the issue and is in the process of chalking out the nitty-gritty of the framework.
- The panel will be tasked with issues related to electric mobility, including setting up of charging stations across the country and subsidising the cost of electric vehicles on a long-term basis.
- The Centre has recently invited proposals from cities with population of above 10 lakh for extending grants under the FAME India (Faster Adoption and Manufacturing of Electric and Hybrid Vehicles in India) scheme to promote large-scale adoption of EVs (electric vehicles) in multi-modal public transport.
4. ‘India up one notch in per capita GDP’
IMF data:
- India has moved up one position to 126 in terms of GDP per capita of countries.
- India still ranked lower than all its BRICS peers.
- Qatar remains the world’s richest on this parameter.
- The data, which forms part of the latest World Economic Outlook report of the International Monetary Fund (IMF), ranks over 200 countries in terms of per capita GDP based on purchasing power parity (PPP).
What is PPP?
- PPP is the rate at which the currency of one country needs to be converted into that of a second country to ensure that a given amount of the first country’s currency will purchase the same volume of goods and services in the second country as it does in the first.
Category: INTERNAL SECURITY AND DEFENSE RELATED DEVELOPMENTS
1. Tejas world-class fighter jet, plays defined role’
In news:
- Hindustan Aeronautics Ltd (HAL) manufacturer of Tejas states : The indigenously developed Tejas Light Combat Aircraft is a world class fighter jet and can effectively play its “defined” role in securing Indian skies.
- Tejas is a four-and-half generation world class fighter jet.
- IAF remarks: The aircraft is not enough to maintain its combat readiness and it needed to quickly procure a fleet of foreign single engine fighters to deal with any possible security challenges, in the backdrop of the dwindling size of its fighter fleet.
1. ‘Trump village’ gets the biggest toilet pot model
- World’s biggest toilet pot model was unveiled at Marora, popularly known as the ‘Trump village’, in Haryana on the World Toilet Day on Sunday in a bid to create awareness towards sanitation and use of toilets.
- The nondescript village, with a population of 1,800, in Mewat region was in June rechristened as ‘Trump village’ by NGO Sulabh International Social Service Organisation in a gesture to U.S. President Donald Trump ahead of Prime Minister Narendra Modi’s visit to Washington.
- A mega pot of toilet made up of iron, fibre, wood and plaster of Paris — measuring 20×10 feet — was unveiled in the hamlet to mark the World Toilet Day, which is observed on November 19 to inspire action to tackle the global sanitation crisis.
Nothing here for Today!!!
Nothing here for Today!!!
F. Practice Questions for UPSC Prelims Exam
- Air Defence Identification Zone (ADIZ) is airspace over land or water in which the identification, location, and control of civil aircraft is performed
- The concept of an ADIZ is defined in Tokyo Convention
- It covers only that country’s territory
- Only 1 and 2
- Only 2 and 3
- Only 1 and 3
- All of the above
G. UPSC Mains Practice Questions
GS Paper I
- Clarify how mid-eighteenth century India was beset with the spectre of a fragmented polity. (2017)
GS Paper IV
- One of the tests of integrity is complete refusal to be compromised. Explain with reference to a real life example.(2017)