Node Twitter Sentiment
In this tutorial we’ll be building an app to pull in real-time Tweets using a Twitter client library for Node called Twit along with NodeJS, Express, and Sentimental (for sentiment analysis).
This is for the Node-js-Denver-Boulder Meetup <3 Cheers!
You can grab the example code here.
Requirements: This tutorial starts where this intro tutorial, Getting Started with Node, ends. If you’ve never set up a Node/Express application before, please start with the intro tutorial. Thanks.
Contents
Project Setup
As you know, Node uses Javascript for both the client and server side. Because of this, the project structure is even more important to not only separate out different concerns (client vs server) but also for your own understanding - e.g., so you can distinguish between client and server side code.
Let’s get to it.
1. Setup basic project structure with Express
$ express twit-decision
2. Install dependencies for Node, Express, and Jade:
$ cd twit-decision && npm install
3. Your project structure should now look like this:
.
├── app.js
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── user.js
└── views
├── index.jade
└── layout.jade
What’s going on?
- Server side code includes app.js (app configurations, middleware, and routing), the “routes” folder (controller/business logic), and the views folder (views, templates, partials)
- Meanwhile, client side code includes the “public” folder (images, Javascript files, and stylesheets)
4. Run the server
$ node app
You should see the “Welcome to Express” Text.
Server Side Code
We’ll start with the server side. Our server code will be responsible for serving up our main index
page, which will display two input boxes where the end user can enter data for comparison. When the data is passed to the server, via jQuery and AJAX on the client end, the server connects to Twitter, pulls the live tweets, and processes sentiment. Finally, the server sends the results back to the client.
1. Install dependencies
$ npm install twit --save
$ npm install Sentimental --save
2. Updated app.js code
// module dependencies
var express = require('express'),
routes = require('./routes'),
http = require('http'),
path = require('path'),
fs = require('fs');
// create express app
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
// routes
app.get('/', routes.index);
app.get('/ping', routes.ping);
// create server
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
You’ve seen the majority of this code already, from the original tutorial, so I won’t go into too much detail. Plus, it’s heavily commented and, right now, it resembles a pretty standard Node/Express app.
Let’s setup our routes next.
3. Routes
var path = require("path");
exports.index = function(req, res){
res.render('index', { title: "Twit-Decision"});
};
exports.ping = function(req, res){
res.send("pong!", 200);
};
Again, pretty straightforward here. We are serving up one page, index, while the second render parameter passes the title to the view. We also added a test route, called ping, which will just display ping on the page.
Test it out. Navigate to http://localhost:3000/ping. You should see “pong!” in the top left corner.
4. Views
Update index.jade
doctype html
html
head
title= title
meta(charset='utf-8')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
meta(name='description', content='')
meta(name='author', content='Michael Herman')
link(href='http://netdna.bootstrapcdn.com/bootswatch/3.1.0/yeti/bootstrap.min.css', rel='stylesheet', media='screen')
link(href='/stylesheets/main.css', rel='stylesheet', media='screen')
body
.container
.jumbotron
h1 Need to make a decision?
p.lead Use Twitter sentiment analysis.
br
br
.form-container
form(action='', method='post')
input#choice1.choice(type='text', data-choice='1', placeholder='Choice #1...', name='choice1')
input#choice2.choice(type='text', data-choice='2', placeholder='Choice #2...', name='choice2')
input#decision.btn.btn-success.btn-lg(type='submit', value='Decide!')
br
br
.decision-container
p#status
p#decision-text
p#score
input#again.btn.btn-success.btn-lg(value='Again?')
script(src='http://code.jquery.com/jquery-1.11.0.min.js')
script(src='http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js')
script(src='javascripts/main.js')
This is our only template that we need. It’s the index page, used for markup, and coded using the Jade Template Language. If this is confusing, I suggest converting this code to HTML and comparing the differences. We have the typical meta tags a links to CSS sheets in the <head>
. The <body>
includes a form as well as a number of selectors for appending the results of the sentiment analysis. Most of the styling is done in Bootstrap.
Let’s quickly jump to the client side.
Client Side
1. Styles
Add these custom styles to the main.css style within the “stylesheets” folder:
.container {
max-width: 1000px;
padding-top: 50px;
text-align: center;
}
.choice {
width:100%;
height:50px;
font-size:25px;
padding:10px;
}
#decision-text {
font-weight:bold;
font-size:60px;
}
#decision {
margin-top:10px;
}
#status, #score {
font-size:25px;
}
.form-container {
margin: auto;
max-width: 500px;
}
.decision-container {
margin: auto;
max-width: 500px;
}
If you’re curious, see how these CSS styles (values and properties) align up to the selectors in the jade template.
2. Client Side Javascript
$(function () {
// highest # of choices (inputs) allowed
window.highestChoice = 2;
// hide again button on page load
$("#again").hide();
var goDecide = function(e) {
// prevent default browser behavior upon submit
e.preventDefault();
// erase old values
$("#status").text('');
$("#score").text('');
// hide decision text
$("#decision-text").hide();
$("#again").hide();
// display processing text, update color to black in case of an error
$("#status").css("color", "black");
$("#status").text("Processing ...");
// create variable to see if any of the inputs are input
var anyEmpty = false;
// array to hold inputs
var choices = [];
// grab values, add to choices array
for(var i = 1; i <= window.highestChoice; i++) {
var choiceValue = $("#choice"+i).val();
if(choiceValue == '') {
anyEmpty = true;
} else {
if(choices.indexOf(choiceValue) == -1) {
choices.push(choiceValue);
}
}
}
// Handling *some* errors
if(!anyEmpty) {
if($("#choice1").val() != $("#choice2").val()) {
// send values to server side for processing, wait for callback, getting AJAXy
$.post('/search', {'choices': JSON.stringify(choices)}, function(data) {
data = JSON.parse(data);
// append data to the DOM
$(".form-container").hide()
$("#status").text("and the winner is ...");
$("#decision-text").text(data['choice']);
$("#score").text('... with a score of ' + data['score'] + '');
$("#decision-text").fadeIn();
$("#score").fadeIn();
$("#again").show()
});
} else {
// error code
$("#status").css("color", "red");
$("#status").text("Both choices are the same. Try again.");
}
} else {
// error code
$("#status").css("color", "red");
$("#status").text("You must enter a value for both choices.");
}
}
// ----- MAIN ----- //
// on click, run the goDecide function
$("#decision").click(goDecide);
// on click new form is shown
$("#again").click(function() {
$(".form-container").show()
$("#again").hide()
// erase old values
$("#status").text('');
$("#score").text('');
$("#choice1").val('');
$("#choice2").val('');
// hide decision text
$("#decision-text").hide();
});
});
Now comes the fun part! Add a main.js file to your “javascripts” folder.
Yes, there’s a lot going on here. Fortunately, it’s well documented.
Start with the // ----- MAIN ----- //
code. This essentially controls everything else. Nothing happens until the decision button is clicked. Once that happens the goDecide()
function fires. This is where things get, well, interested.
Go through it line by line, reading the comment, then code. Make sure you understand what each statement is doing.
Notice how the magic starts happening when the data is grabbed from the inputs, added to an array, and then sent to the server side via AJAX. Notice the /search
endpoint. We pass the stringified choice
array to that endpoint, which needs to be setup on the server side, then what for the data to comeback before appending it to the DOM.
Check out the rest of the code on your own. Follow the comments for assistance.
Back to the Server Side
So, we need to set up a new route, ‘/search’, on the server side to handle the data sent from the client side.
1. app.js
First, add the route to app.js:
app.post('/search', routes.search)
2. Update routes:
Then add the following code to index.js in the “routes” folder:
exports.search = function(req, res) {
// grab the request from the client
var choices = JSON.parse(req.body.choices);
// grab the current date
var today = new Date();
// establish the twitter config (grab your keys at dev.twitter.com)
var twitter = new twit({
consumer_key: config.consumer_key,
consumer_secret: config.consumer_secret,
access_token: config.access_token,
access_token_secret: config.access_token_secret
});
// set highest score
var highestScore = -Infinity;
// set highest choice
var highestChoice = null;
// create new array
var array = [];
// set score
var score = 0;
console.log("----------")
// iterate through the choices array from the request
for(var i = 0; i < choices.length; i++) {
(function(i) {
// add choice to new array
array.push(choices[i])
// grad 20 tweets from today
twitter.get('search/tweets', {q: '' + choices[i] + ' since:' + today.getFullYear() + '-' +
(today.getMonth() + 1) + '-' + today.getDate(), count:20}, function(err, data) {
// perform sentiment analysis
score = performAnalysis(data['statuses']);
console.log("score:", score)
console.log("choice:", choices[i])
// determine winner
if(score > highestScore) {
highestScore = score;
highestChoice = choices[i];
console.log("winner:",choices[i])
}
console.log("")
});
})(i)
}
// send response back to the server side; why the need for the timeout?
setTimeout(function() { res.end(JSON.stringify({'score': highestScore, 'choice': highestChoice})) }, 5000);
};
Again, I’ve commented this heavily. So go through, line by line, and see what’s happening.
Points of note:
- Add your Twitter config keys to a new file called config.js. More on this in the next section.
- Why are we using a timeout? Try removing it. What happens? Why is this a bad practice?
3. Config
Open the config_example.js file. Save the file as config.js, then add your own Twitter keys. Add this as a dependency along with Twit and Sentimental to your index.js file:
var twit = require('twit');
var sentimental = require('Sentimental');
var config = require("./config")
4. Twitter
Remember this line from your routes file, index.js:
score = performAnalysis(data['statuses']);
Well, we pass the pulled tweets as arguments into the performAnalysis()
function.
performAnalysis
Let’s add that function:
function performAnalysis(tweetSet) {
//set a results variable
var results = 0;
// iterate through the tweets, pulling the text, retweet count, and favorite count
for(var i = 0; i < tweetSet.length; i++) {
tweet = tweetSet[i]['text'];
retweets = tweetSet[i]['retweet_count'];
favorites = tweetSet[i]['favorite_count'];
// remove the hastag from the tweet text
tweet = tweet.replace('#', '');
// perform sentiment on the text
var score = sentimental.analyze(tweet)['score'];
// calculate score
results += score;
if(score > 0){
if(retweets > 0) {
results += (Math.log(retweets)/Math.log(2));
}
if(favorites > 0) {
results += (Math.log(favorites)/Math.log(2));
}
}
else if(score < 0){
if(retweets > 0) {
results -= (Math.log(retweets)/Math.log(2));
}
if(favorites > 0) {
results -= (Math.log(favorites)/Math.log(2));
}
}
else {
results += 0;
}
}
// return score
results = results / tweetSet.length;
return results
}
After the tweets are passed in, the text is parsed and sentiment is analyzed. Finally a score is calculated and returned.
Boom. That’s it!
Your project structure should now look like:
.
├── app.js
├── config.js
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ │ └── main.js
│ └── stylesheets
│ └── main.css
├── routes
│ └── index.js
└── views
└── index.jade
Test time!
Conclusion
Test this out a few times. Make sure it all works. Perhaps go through it iteratively, following along with the code for further understanding.
Think about what you could add to make this app more fun/unique?
- Perhaps add a persistence layer, such as MongoDB, to retain the history of your searches to see sentiment over time.
- Ability to display actual tweets.


General info
Snow cover 'detection'
This tool is aimed at trail runners and/or mountain bikers who want to go somewhere relatively high up in the mountains early in the seasons. This is a very simple tool showing satellite data and potential snow cover side-to side, which can help in route planning. On the left, the latest Sentinel 2 RGB (visible light) data are displayed, on the pixels with potential snow cover are highlighted in red. Nothing fancy is done; simply all pixels with a signal above a fairly arbitrary threshold are considered to be 'snow covered'. A way better solution is built by Exolabs, who's snow cover layers are built using observational data and models, and supply snow depth too. Yet, for whoever wants to know whether there's any snow left on the planned route, this janky thing might come in useful :)
No satellite imagery is available for my region of interest!
Most likely this means that you need to select another satellite signal: you can do this under the drop-down menu on the top-right. If you're unlucky and there were clouds on the moment the imagery was collected, clouds or blank pixels will be displayed.
Disclaimer / small print
Please note that this is not a real snow detection tool - it simply highlights pixels above an arbitrary threshold. Hence, clouds, buildings or other bright pixels can be detected as snow; and snow covered by debris go undetected. Actual snow cover might differ significantly from what is predicted, and the data might be faulty or outdated. So, be careful and take none of these results for granted. Always use common sense, don't take any of these predictions as sole tour planning tool.
I cannot take any responsibility nor can I be held liable for any information displayed on this page. Any reliance you place on the displayed information is therefore strictly at your own risk.
Copyright (c) Johan van den Hoogen 2022 - released under MIT License; code is here


A funcy way to track progress of your personal project at http://ticktee.herokuapp.com
Intro to Android AppA wonderful ordering system. It serves both restaurant and simple fast sale cafe including many useful feature specified designed for hospitality business like Sales Analysis Reporting System, Customized Menu Building System, Multiple Type of Printing Support.
Multiple Terminal Support: iPad, self-checkout terminal, Web Service
Double card games in one including traditional set card game and double matching game, developed under iOS 7. Check out at my github


Bio(graphical)
A bit about me
Ever since I was a kid I have loved running. They only problem seemed to be that I couldn't run in a straight line. Mother used to tie me to the clothes line so I could practice, but I kept zigging and zagging. The day we went to Aunt Maudes farm was the day my life changed. Cousin Rupert accidently let go of the dinner chicken, and it ran free. No one could catch it, not even Cletis, who had two legs the same lenth! Mother looked at me, and in that momment I knew what I was destined to do. That chicken zigged and zagged but I zagged when it zigged and snatched that chicken up. I found my calling and, now I am the best free range chicken catcher in all of Oregon!
Edu(cational)
Study this I did
Home school wasn't even a thing back then. Light sockets, don't stick a fork in them. I'm a fast learner, no one had to teach me that, learned it all by myself.
Things I learned quickly.
- Don't touch your tougue to a nine volt battery.
- Cletis doesn't have candy in his pocket, just a hole.
- Don't play baseball with cousin Bertha. First base is not what you think.
Exp(eriential)
Did stuff here
Senior Leghorn Chicken Hawk - Praire City Chicken Ranch
Urban Farmers Chicken Search and Rescue - City of Portland, Or
Entry Level Catcher - Bend Boneless Chicken Farm
Amb(itions)
Lofty Ideals
Working as free range chicken catcher has been as rewarding a blessing from heaven, but I know that life has more in store for me. There are greater things on the horizon for me as I see myself moving twords bigger and better things. Someone has to catch those turkeys, so it may as well be me. And someday, maybe, I'l just grab that bull by its horns.
Top Ten Movies
These are my top ten favorite movies
- Chicken Chaser
- The Man with a Chicken Head
- Luv Shuv Tey Chicken Khurana
- Chicken Is Barefoot
- Dynamite Chicken
- King Chicken
- The Hoboken Chicken Emergency
- The Chicken Chronicles
- Chicken Run
- The Ghost and Mr. Chicken


Paban Bhuyan
Master Student in Climate Science & Technology.
Research Interest includes Ocean dynamics, Submesoscale Processes, Ocean Current, Biogeochemistry, Upwelling systems, and Physical-Biological ocean modeling.
Boundary currents are essential for maintaining the balance of heat and salt over a domain and for the transport of nutrients, which is needed for the marine organisms to thrive. I use HF Radar current, Drifter, Satellite Altimetry derived (Geostrophic current) SSHA, SST, SSS to study boundary current along the western Bay of Bengal. Currently I am working as a Junior Research Fellow at IIT Delhi, I am working on numerical simulation of submesoscale processes driven by river plumes in the Bay of Bengal for which I use ROMS (Regional Ocean Modeling System). In this project I am interested in findingout the mechanism by which submesoscale eddies forms due to river plumes.
I completed my Masters from School of Earth, Ocean and Climate Sciences, Indian Institute of Technology Bhubaneswar.
You can find a PDF version of my CV here.


class: center, middle, title-slide count: false # Opening the black box
.bold[Marc Lelarge] .citation.tiny[ With slides from A. Sablayrolles] --- # How do we make sure that our model works? How do we make sure that our model works ? - We can look at its performance on a validation set - We will know that it works, but not how -- It is important to understand how our models work, in particular for: - debugging our training code / algorithm - getting ideas on how to improve the model - be compliant with regulations if our model is used in production - using pre-trained models for a new task (transfer learning) --- # Looking at network activations Basic idea: ReLU represent how useful the signal is: - if a ReLU is activated (> 0), the signal useful to predict the class - if a ReLU is not activated (< 0), the signal is useless .center[
] .citation[Credit: Alexandre Sablayrolles] --- # Visualization of activations We can run t-sne on the last activation of the neural net. .center[
]
.citation[Credit: A. Karpathy [t-SNE visualization of CNN codes](https://cs.stanford.edu/people/karpathy/cnnembed/)] --- # Class Activation Mapping .center[
] from [Learning Deep Features for Discriminative Localization](http://cnnlocalization.csail.mit.edu/)
.citation[Practical example: [Notebook](https://github.com/mlelarge/dataflowr/blob/master/CEA_EDF_INRIA/CAM_colab.ipynb) ] --- # Inverting deep image representations .center[
] from [Understanding Deep Image Representations by Inverting Them](https://www.cv-foundation.org/openaccess/content_cvpr_2015/html/Mahendran_Understanding_Deep_Image_2015_CVPR_paper.html)
For a given image, take the 1,000-dimensional vector at the end of the network and starting from random noise, learn an image with the same 1,000-dimensional code (while the network weights are frozen). All images above are equivalent from the viewpoint of the network. --- class: end-slide, center count: false The end.


To achieve this, an object reactor is planted on each EMPLOYEE block reference in order to detect when the block reference is opened for a modify operation. This will occur before the actual transformation takes place. To detect the new position for the block reference after the transformation has taken place, we will also need to implement the editor reactor's notification for 'command ended'.
Finally, we need to detect when new EMPLOYEE block references are created, this can be achieved with a database reactor.
Bear in mind that a user can decide to apply the edit commands to a selection set and the selection set can contain one or more EMPLOYEE block references in addition to other types of entities. To handle such a case, we need to use an array of objectIds (AcDbObjectIdArray) for the EMPLOYEE block reference(s) being modified. In parallel to this, we also need to maintain an array of points (AGePoint3dArray) to store the corresponding original position(s) of the EMPLOYEE block reference(s).
To further manage the AcDbObjectIdArray and the AcGePoint3dArray, we need to manage this data on a document by document basis. Each document will manage its own set of AcDbObjectIdArray and AcGePoint3dArray data. We therefore need a document manager reactor to manage the appropriate set of data when the active document is switched.
- Load project "Step03", which was created with the ObjectARX Wizard or continue with the files you created from the previous step.
- Prepare the document data.
- Add and implement an editor reactor for the application.
- Add and implement an object reactor for the application.
- Implement the user defined 'attachEmployeeReactorToAllEmployee()' utility function
- Implement the user defined 'detachAllEmployeeReactors()' utility function
- Add and implement a database reactor for the application.
- Test the application.
Prepare the document data
The ObjectARX Wizard automatically creates the class CDocData (see DocData.h, DocData.cpp and AsdkDMgr.h). The CDocData class can be used to implement document dependent data. If you are continuing from the previous step, make sure the "Project" application is the active project in Visual C++.
- Add the member variables outlined in the following table to the CDocData class in DocData.h file:
Member variables to be added to the CDocData Class Data Type Variable Name bool m_editCommand bool m_doRepositioning AcDbObjectIdArray m_changedObjects AcGePoint3dArray m_employeePositions
- m_editCommand will be used to record if one of our monitored editing commands is active.
- m_doRepositioning will be use to let us know if repositioning of an EMPLOYEE block reference is required, so that we can ignore/monitor reactor callbacks.
- m_changedObjects will be used to record which EMPLOYEE block references were modified.
- m_employeePositions will be used to store the original positions of EMPLOYEE block references.
NOTE: Access to the document dependent data is achieved through DocVars.docData(). See the declaration of AsdkDataManager DocVars global variable, in CDocData.cpp for details.
- In the constructor of CDocData in CDocData.cpp we initialize
m_editCommand = false;
m_doRepositioning = false;
Add and implement an editor reactor for the application
- Use the ObjectARX Wizard toolbar (see Step 7 Figure 1) to create an editor reactor class AsdkEdEmployeeReactor derived from AcEditorReactor. The Wizard automatically prefixes the class with the RDS symbol.
Step 7 Figure 1 - Selecting Transient Reactors from ObjectARX Toolbar
- Using the ObjectARX Wizard, add the functions commandWillStart() and commandEnded().
NOTE: Make sure that the ObjectARX application is the active project in Visual C++ and not an ObjectDBX application. ObjectDBX applications do not support AcEditorReactor's and hence you will not see this type of reactor in the drop-down list.
Step 7 Figure 2 - Adding Transient Reactor functions
- Add code to commandWillStart() that does the following :
- Check if one of the commands "MOVE", "ROTATE", "STRETCH", "SCALE" or "GRIP_STRETCH" is started (use a string comparison function such as strcmp() current command being use is passed in through the parameter).
- If it is one of the monitored commands, set m_editCommand = true; and m_doRepositioning = false; (Use DocVars.docData().<appropriate variable here>).
- Reset any objectIds and position information (AcDbObjectIdArray::setLogicalLength()) to zero.
- Add code to commandEnded() that does the following:
- If the command being monitored is not a monitored command from the above list of commands then set m_editCommand == false; and simply return.
- Reset m_editCommand to false.
- Set m_doRepositioning to true and start repositioning the moved objects
- For every object in m_changedObjects (AcDbObjectIdArray::length()) do the following
- Open the entity (acdbOpenObject()).
- If the actual position is different from the stored position reposition the object (AcDbBlockReference::position(), m_employeePositions.at(), AcDbBlockReference::setPosition())
- Create an AsdkEdEmployeeReactor reactor instance.
- Create a global pointer to your editor reactor. Place this reactor in the "Project.cpp" file as follows:
AsdkEdEmployeeReactor *pEdEmployeeReactor = NULL;
- Create an instance of the AsdkEdEmployeeReactor editor reactor when the application loads, place this in the 'InitApplication()' of the "Project.cpp" file.
pEdEmployeeReactor = new AsdkEdEmployeeReactor(true); NOTE: Normally when working with transient reactors we utilize the functions 'addReactor()' and 'removeReactor()' to place/remove our transient reactors at the appropriate time during the life of our application. In this particular case the AsdkEdEmployeeReactor class was generated by the ObjectARX Wizard and the ObjectARX Wizard delegates the responsibility of adding/removing the AsdkEdEmployeeReactor to the constructor/destructor of the class respectively. See "rEditorReactor.cpp" for details. Also an editor reactor is added only when we load our application and removed when we unload our application. It is extremely important to remove your editor reactor if you unload your application. Failing to do so can cause AutoCAD to crash. It's your responsibility.
- If the application unloads delete the editor reactor. Place the following in 'UnloadApplication()':
delete pEdEmployeeReactor;
Add and implement an object reactor for the application
- Use the ObjectARX Wizard to create object reactor class AsdkEmployeeReactor derived from AcDbObjectReactor. The Wizard automatically prefixes the class with the RDS symbol.
- Using ObjectARX Wizard, add the function openedForModify()
Examine the files created by the ObjectWizard, "rObjectReactor.h" and "rObjectReactor.cpp".- Add code to openedForModify() such that:
- If we are currently repositioning (m_doRepositioning == true) then return. (Use DocVars.docData().<appropriate variable here>).
- If none of the monitored commands is active (m_editCommand == false) then return.
- Verify that the AcDbObject passed in, is an AcDbBlockReference entity, if not return.
- Retrieve the name of the AcDbBlockReference. For this you will need to get the AcDbBlockReference's block definition AcDbBlockTableRecord and query the name of the AcDbBlockTableRecord. (Use AcDbBlockReference::blockTableRecord ()). If it is not an EMPLOYEE block reference, just return.
- Store the position of the 'openedForModify()' object in m_employeePositions (AcGePoint3dArray::append()).
- Store the objectId of the 'openedForModify()' object in m_changedObjects (AcDbObjectIdArray::append()).
- Create an AsdkEmployeeReactor reactor instance.
- Create a global pointer to your object reactor. Place this reactor in the "Project.cpp" file as follows:
AsdkEmployeeReactor *pEmployeeReactor = NULL;
- Create an instance of the object reactor when the application loads,, place this in the 'InitApplication()' of the "Project.cpp" file.
pEmployeeReactor = new AsdkEmployeeReactor();
- If the application unloads delete the object reactor. Place the following in 'UnloadApplication()':
delete pEmployeeReactor; NOTE: Here we create a single global instance of AsdkEmployeeReactor (an AcDbObjectReactor object), as you will see later we attach this instance to the EMPLOYEE block references. We could also have created new instances of the AsdkEmployeeReactor and attached each instance to each EMPLOYEE block reference found. We just want you to be aware that an AcDbObjectReactor can be attached to more than one object.
Implementation of the user defined 'attachEmployeeReactorToAllEmployee()' utility function
NOTE: As mentioned earlier we add/remove transient reactors to our objects using addReactor()/removeReactor(). Here we are going to attach reactors to all EMPLOYEE block reference objects. Remember that more than one open drawing can contain EMPLOYEE block references. The AsdkDataManager class manages CDocData classes and there is one CDocData class per document. In the constructor for the CDocData we will call the user defined function 'attachEmployeeReactorToAllEmployee()'. This will be called for every drawing open in the current AutoCAD session and also when new drawing are created or existing drawing are opened. This function will be responsible for attaching/removing the AsdkEmployeeReactor objects for each drawing.
- Attach the object reactor to all "EMPLOYEE" references which are already in the drawing. Write the function:
Acad::ErrorStatus
attachEmployeeReactorToAllEmployee(bool attach) that will:- Get the block table (AcDbDatabase::getBlockTable()).
- Get the model space record (AcDbBlockTable::getAt(), ACDB_MODEL_SPACE).
- Get a block table record iterator (AcDbBlockTableRecordIterator, AcDbBlockTableRecord::newIterator()).
- Iterate through the Model Space records and retrieve the entities (AcDbBlockTableRecordIterator::getEntity()). If the retrieved block reference entity is not an EMPLOYEE object, just return.
- If the retrieved entity is an "EMPLOYEE" block reference, attach the global object reactor (AcDbObject::addReactor()) or if the parameter attach is false then remove the already attached object reactor (AcDbObject::removeReactor()).
- Finally, don't forget to delete the iterator and to close the objects.
- Call attachEmployeeReactorToAllEmployee() inside the CDocData constructor.
Implementation of the user defined 'detachAllEmployeeReactors()' utility function
- If you unload your application you must detach all object reactors attached to EMPLOYEE block reference entities. Implement 'detachAllEmployeeReactors()' to do this.
void detachAllEmployeeReactors()
This function will:
- Get an AcApDocumentIterator (acDocManager->newAcApDocumentIterator()). acDocManager is a global macro that is used to retrieve the AcApDocManager which is responsible for all the documents in an AutoCAD session. Refer to the AcApDocManager in the ObjectARX online help for details.
- Store a pointer to the current document, so you can reset the document after iterating (acDocManager->curDocument()).
- Iterate through all documents, make each document the current document and call attachEmployeeReactorToAllEmployee(false).
- After iterating, reset the current document to be the one that was current before iterating.
- Call detachAllEmployeeReactors() if your application unloads.
Add and implement a database reactor for the application
- Use the ObjectARX Wizard to create a database reactor class AsdkDbEmployeeReactor derived from AcDbDatabaseReactor. The Wizard automatically prefixes the class with the RDS symbol.
- Using the ObjectARX Wizard, add the function objectAppended().
- Implement the 'objectAppend()' function.
- Check if the appended object is an AcDbBlockReference ( cast ). If not return.
- Get the block table record of the reference. (AcDbBlockReference::blockTableRecord()).
- Get the name of the block table record and check if it is an EMPLOYEE block reference. If not return. (AcDbSymbolTable::getName()).
- Attach the AsdkEmployeeReactor object reactor to the appended block reference. (AcDbObject::addReactor()). Remember we are watching the database to see if any EMPLOYEE block references are being added and if so we are attaching the AsdkEmployeeReactor object reactor to the block reference.
- Create a new instance of the database reactor for every new drawing. You can do this when you receive the kLoadDwgMsg message in the acrxEntryPoint() function.
- From the ObjectARX Wizard toolbar, click the 'ObjectARX entry point messages' button.
Step 7 Figure 3 - Entry Point Messages on the ObjectARX Wizard toolbar
- From the ObjectARX Entry Point Messages dialog select 'kLoadDwgMsg' message.
Step 7 Figure 4 - ObjectARX Entry Point Messages Dialog
The ObjectARX Wizard will create an function 'OnkLoadDwgMsg()' in the "Project.cpp" file.
- Create a new AsdkDbEmployeeReactor object in the 'OnkLoadDwgMsg()' message function.
new AsdkDbEmployeeReactor (true, curDoc()); - Examine the "rDatabaseReactor.h" and the "rDatabaseReactor.cpp" files created by the ObjectARX Wizard.
NOTE: In the constructor for the AsdkDbEmployeeReactor class we add our database reactor to the document using 'addReactor()' and also we initialize the pointer variable m_pAsdkDbEmployeeReactor to point to this AsdkDbEmployeeReactor database reactor object. The m_pAsdkDbEmployeeReactor is part of the CDocData class and was put there by the ObjectARX Wizard. When a drawing is closed, the ~CDocData destructor is called, here we check to see if m_pAsdkDbEmployeeReactor is not NULL and delete the pointer. This in turn will call the destructor for the AsdkEmployeeReactor class and removes the database reactor with a call to 'removeReactor()'.
Test the application
Create some EMPLOYEE block references as you did within Step03. Try to MOVE these EMPLOYEE block references. Save the drawing. Unload the application. Open the saved drawing and reload the application. The MOVE command will have had no effect on the EMPLOYEE block reference, because the reactors that are attached were transient in nature..
You have now completed the ObjectARX 2000 Training Tutorial. We hope that you have enjoyed this small sampler and we wish you every success in your future as an ObjectARX programmer.


Signup
Username
Required
Email
Required
Invalid email address
Password
Required
Must match the previous entry
Confirm Password
Required
Must match the previous entry
Remember me
Reset


$().SPServices
Lists
GetListContentTypes
This is an example from jenglish. I wrote a blog post about this example as well.
If you have a better, real life example, please create an issue or an PR.
var queryStringVals = $().SPServices.SPGetQueryString(); // The SPGetQueryString function parses the Query String values out into an array
var contentTypeIdValue = queryStringVals["ContentTypeId"]; // This grabs the value of the ContentTypeId Query String parameter
var contentTypeName = ""; // Define a variable to hold the name of the Content Type
// Get the list's Content Types
$().SPServices({
operation: "GetListContentTypes", // See the MSDN SDK at http://msdn.microsoft.com/en-us/library/lists.lists.getlistcontenttypes.aspx for details on this operation
listName: $().SPServices.SPListNameFromUrl(), // The SPListNameFromUrl function gets the list name for the current context based on the URL
async: false, // We'll do this asynchronously
completefunc: function (xData, Status) {
$(xData.responseXML).find("ContentType").each(function() { // All of the list's Content Types will be returned. We'll loop through to get the one we are interested in
if($(this).attr("ID") == contentTypeIdValue) { // If the contentTypeId matches...
contentTypeName = $(this).attr("Name"); // ...store the name in our variable...
return false; // ...and return false, which breaks us out of the loop. (We've found what we need, so no reason to continue looking.)
}
});
}
});
//... do something with the Content Type Name ...


|
In TprMemoObj, TprRichObj and TprTxMemoObj objects you can write expressions
in square brackets, like: [Table.Name]. These expressions will be calculated
by the parser and replaced with the actual values. For each expression the
format mask can be defined.
Syntax of the expressions:
[[FormatMask]Expression]
Example:
Company: [Customers.Company]
Here Customers.Company - expression, the format mask in this example is
not specified.
Syntax of the format mask:
:[NType of value if NULL][Width and alignment][<DisplayFormat>]
Type of value if NULL:
By default if the expression returns NULL its value is replaced with empty string. This format parameter allows defining the default value that will be formatted. Format parameter consists of two chars: [NX], where X can be:
S - If the expression is equal NULL, while formatting
the value equal to an empty string will be used
D - If the expression is equal NULL, while formatting
the value equal to empty date (30.12.1899) will be used.
N - If the expression is equal NULL, while formatting
the value equal to 0 will be used.
Width and alignment
The formatted expression should be levelled in a line of indicated length, the line is supplemented by gaps. After a width the numeral assigning alignment should be necessary indicated:
L - On the left edge
R - On the right edge
C - On centre
Display format
Specified in angular brackets. The syntax of the format string is determined by type of formatted value:
- for string values the format string should have the same format as for function FormatMaskText.
- for numeric values the format string should have the same format as for function FormatFloat.
- for TDateTime values the format string should have the same format as for function FormatDateTime.
| Format |
Constant |
Default value |
|
<c> |
CurrencyFormat |
#,0.00?''.'';-#,0.00?''.''' |
|
<s> |
ShortCurrencyFormat |
0.00?''.'';-0.00?’'.'' |
|
<r> |
SimpleCurrencyFormat |
0.00;-0.00 |
|
<p> |
PercentFormat |
0.00%;-0.00% |
|
<d> |
ShortDateFormat |
System constant |
|
<q> |
SpacedCurrencyFormat |
#,0.00;-#,0.00 |
|
<b> |
BankCurrencyFormat |
\ds-0.00;-0.00 |
Examples:
| Value |
Type of value |
FormatMask |
Result of formatting |
| 123 |
Number |
[:<c>] |
123.00?. |
| 12.12.1999 |
Date |
[:<dd mmm yyyy>] |
12 December 1999 |
| 10.145 |
Number |
[:12r<0.00>] |
_______10.15 |
| Null |
|
[:<c>] |
Empty line |
| Null |
|
[:NN<c>] |
0.00?. |
|


Tasker
Home
Dummy
Tutorial
About
Please enter title
Please enter description
SUBMIT
Completed Tasks
Pending Tasks


It is estimated that bitcoin is using approximately 23,312 megawatt hours per day (see electric consumption at blockchain.info/stats (24 hour stats)) of electric for block solving algorithms.
The aim of the gridcoin project is to shift the computational power primarily to Boinc projects while the mining operations become a second priority - so as the network is scaled up, boinc utilization is scaled up in tandem.
The coin miners will be rewarded with a small token subsidy if they fail to mine boinc shares, but a much larger subsidy when mining with boinc.
This digital cryptocurrency allows instant peer to peer transactions, worldwide payments and very low processing fees. The source code is open source and allows everyone to take part in the success of the currency.
Gridcoin is based on the Bitcoin protocol but differs from Bitcoin in that it can be efficiently mined with consumer-grade hardware, therefore is not as likely to be replaced by specialized ASIC mining chips in the future.
Gridcoin provides faster transaction confirmations (2.5 minutes on average) and uses memory intensive scrypt-based proof-of-work algorithms to verify transactions.
Vital Statistics:
Algorithm: Scrypt, Re-target: 30 minutes with 2.5 min block targets, Block reward: 5-150, 5 GRC wihtout Boinc, 6-150 - receiving a calculated subsidy based on boinc utilization.
Total coins: Gridcoin is scheduled to produce approximately 168 million currency units (based on an average block subsidy of 100GRC).
Official Mining Launch Date: 10/16/2013 @ 11:00PM CST
Its free, and harnesses the unused clock cycles from PC and Video cards to aid in the research for the project goal.
Some of the major projects that you can participate in:
Miners are currently awarded with 5-150 new gridcoins per block, an amount which gets halved roughly every 4 years (every 840,000 blocks). The gridcoin network is therefore scheduled to produce approximately 168 million gridcoins (based on an average subsidy of 100grc), which is 8 times as many currency units as Bitcoin
Wallet encryption allows you to secure your wallet, so that you can view transactions and your account balance, but are required to enter your password before spending gridcoins.
This provides protection from wallet-stealing viruses and trojans as well as a sanity check before sending payments.
Not sure where to start? Visit the forum.


Main
News
Info
Russian
avatarusgames
Main
News
Info
Russian
Navigate the site…
All news
Our new site delta :)
Our new site epsilon :)
Our new site alfa :)
Our new site gama :)
Our new site beta :)
Our new site :)
Our new site :)
∞
>> news >> 10.07.2016
Welcome to our site! SSSS.
Stay tuned
!


Hide Page | Reload Cached
The goal of this page is to use CSS to show a loading message while the headline's font is loading, then hide the loading message and show the headline once the font has rendered.


Spondool is a SaaS business based in Dublin, Ireland.
Spondool makes software that helps companies change their cashflow management culture, so they can develop positive cashflow and grow their business.
Spondool has a unique, contrarian approach to the software business. We believe in helping human beings actively collaborate. We discourage excessive automation, which can lead to a lack of clear responsibility and which can conceal important information. We view the software as the tool, not the user.
Spondool is a process, a way of managing information about cash that gets you the realtime data you want. No percentages, no actuarial gobbledygook, no guesses: just cold, hard numbers.


Creating and Using a Custom Converter
A JavaServer Faces converter class converts strings to objects and objects to strings as required. Several standard converters are provided by JavaServer Faces for this purpose. See for more information on these included converters.
As explained in Conversion Model, if the standard converters included with JavaServer Faces cannot perform the data conversion that you need, you can create a custom converter to perform this specialized conversion. This implementation, at a minimum, must define how to convert data both ways between the two views of the data described in Conversion Model.
All custom converters must implement the Converter interface. This section explains how to implement this interface to perform a custom data conversion.
The Duke's Bookstore case study uses a custom Converter implementation, located in tut-install/examples/case-studies/dukes-bookstore/src/java/dukesbookstore/converters/CreditCardConverter.java, to convert the data entered in the Credit Card Number field on the bookcashier.xhtml page. It strips blanks and hyphens from the text string and formats it so that a blank space separates every four characters.
Another common use case for a custom converter is in a drop-down menu for a nonstandard object type. In the Duke's Tutoring case study, the Student and Guardian entities require a custom converter so they can be converted to and from a UISelectItems input component.
Creating a Custom Converter
The CreditCardConverter custom converter class is created as follows:
@FacesConverter("ccno") public class CreditCardConverter implements Converter { ... }
The @FacesConverter annotation registers the custom converter class as a converter with the name of ccno with the JavaServer Faces implementation. Alternatively, you can register the converter with entries in the application configuration resource file, as shown in Registering a Custom Converter.
To define how the data is converted from the presentation view to the model view, the Converter implementation must implement the getAsObject(FacesContext, UIComponent, String) method from the Converter interface. Here is the implementation of this method from CreditCardConverter:
@Override public Object getAsObject(FacesContext context, UIComponent component, String newValue) throws ConverterException { String convertedValue = null; if ( newValue == null ) { return newValue; } // Since this is only a String to String conversion, // this conversion does not throw ConverterException. convertedValue = newValue.trim(); if ( (convertedValue.contains("-")) || (convertedValue.contains(" "))) { char[] input = convertedValue.toCharArray(); StringBuilder builder = new StringBuilder(input.length); for ( int i = 0; i < input.length; ++i ) { if ( input[i] == ’-’ || input[i] == ’ ’ ) { continue; } else { builder.append(input[i]); } } convertedValue = builder.toString(); } return convertedValue; }
During the Apply Request Values phase, when the components’ decode methods are processed, the JavaServer Faces implementation looks up the component’s local value in the request and calls the getAsObject method. When calling this method, the JavaServer Faces implementation passes in the current FacesContext instance, the component whose data needs conversion, and the local value as a String. The method then writes the local value to a character array, trims the hyphens and blanks, adds the rest of the characters to a String, and returns the String.
To define how the data is converted from the model view to the presentation view, the Converter implementation must implement the getAsString(FacesContext, UIComponent, Object) method from the Converter interface. Here is an implementation of this method:
@Override public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException { String inputVal = null; if ( value == null ) { return null; } // value must be of a type that can be cast to a String. try { inputVal = (String)value; } catch (ClassCastException ce) { FacesMessage errMsg = new FacesMessage(CONVERSION_ERROR_MESSAGE_ID); FacesContext.getCurrentInstance().addMessage(null, errMsg); throw new ConverterException(errMsg.getSummary()); } // insert spaces after every four characters for better // readability if they are not already present. char[] input = inputVal.toCharArray(); StringBuilder builder = new StringBuilder(input.length + 3); for ( int i = 0; i < input.length; ++i ) { if ( (i % 4) == 0 && i != 0) { if (input[i] != ’ ’ || input[i] != ’-’){ builder.append(" "); // if there are any "-"’s convert them to blanks. } else if (input[i] == ’-’) { builder.append(" "); } } builder.append(input[i]); } String convertedValue = builder.toString(); return convertedValue; }
During the Render Response phase, in which the components’ encode methods are called, the JavaServer Faces implementation calls the getAsString method in order to generate the appropriate output. When the JavaServer Faces implementation calls this method, it passes in the current FacesContext, the UIComponent whose value needs to be converted, and the bean value to be converted. Because this converter does a String-to-String conversion, this method can cast the bean value to a String.
If the value cannot be converted to a String, the method throws an exception, passing an error message from the resource bundle that is registered with the application. Registering Application Messages explains how to register custom error messages with the application.
If the value can be converted to a String, the method reads the String to a character array and loops through the array, adding a space after every four characters.
You can also create a custom converter with a @FacesConverter annotation that specifies the forClass attribute, as shown in the following example from the Duke's Tutoring case study:
@FacesConverter(forClass=Guardian.class) public class GuardianConverter implements Converter { ...
The forClass attribute registers the converter as the default converter for the Guardian class. Therefore, whenever that class is specified by a value attribute of an input component, the converter is invoked automatically.
A converter class can be a separate Java POJO class, as in the Duke's Bookstore and Duke's Tutoring case studies. If it needs to access objects defined in a managed bean class, however, it can be a subclass of a JavaServer Faces managed bean, as in the address-book persistence example and the Duke's Forest case study, where the converters use an enterprise bean that is injected into the managed bean class.
Using a Custom Converter
To apply the data conversion performed by a custom converter to a particular component’s value, you must do one of the following:
Reference the converter from the component tag’s converter attribute.
Nest an f:converter tag inside the component’s tag and reference the custom converter from one of the f:converter tag’s attributes.
If you are using the component tag’s converter attribute, this attribute must reference the Converter implementation’s identifier or the fully-qualified class name of the converter. Creating and Using a Custom Converter explains how to implement a custom converter.
The identifier for the credit card converter class is ccno, the value specified in the @FacesConverter annotation:
@FacesConverter("ccno") public class CreditCardConverter implements Converter { ...
Therefore, the CreditCardConverter instance can be registered on the ccno component as shown in the following example:
<h:inputText id="ccno" size="19" converter="ccno" value="#{cashier.creditCardNumber}" required="true" requiredMessage="#{bundle.ReqCreditCard}"> ... </h:inputText>
By setting the converter attribute of a component’s tag to the converter’s identifier or its class name, you cause that component’s local value to be automatically converted according to the rules specified in the Converter implementation.
Instead of referencing the converter from the component tag’s converter attribute, you can reference the converter from an f:converter tag nested inside the component’s tag. To reference the custom converter using the f:converter tag, you do one of the following:
Set the f:converter tag’s converterId attribute to the Converter implementation’s identifier defined in the @FacesConverter annotation or in the application configuration resource file. This method is shown in bookcashier.xhtml:
<h:inputText id="ccno" size="19" value="#{cashier.creditCardNumber}" required="true" requiredMessage="#{bundle.ReqCreditCard}" > <f:converter converterId="ccno"/> <f:validateRegex pattern="\d{16}|\d{4} \d{4} \d{4} \d{4}|\d{4}-\d{4}-\d{4}-\d{4}" /> </h:inputText>
Bind the Converter implementation to a managed bean property using the f:converter tag’s binding attribute, as described in Binding Converters, Listeners, and Validators to Managed Bean Properties.
The JavaServer Faces implementation calls the converter's getAsObject method to strip spaces and hyphens from the input value. The getAsString method is called when the bookcashier.xhtml page is redisplayed; this happens if the user orders more than $100 worth of books.
In the Duke's Tutoring case study, each converter is registered as the converter for a particular class. The converter is automatically invoked whenever that class is specified by a value attribute of an input component. In the following example, the itemValue attribute (highlighted in bold) calls the converter for the Guardian class:
<h:selectManyListbox id="selectGuardiansMenu" value="#{guardianManager.selectedGuardians}" size="5"> <f:selectItems value="#{guardianManager.allGuardians}" var="selectedGuardian" itemLabel="#{selectedGuardian.name}" itemValue="#{selectedGuardian}" /> </h:selectManyListbox>


We believe that today's betting platforms are full of ads that polute the game itself. We want to create a platform that people can use to bet/play with their friends and family or anyone they want, without any ads and without asking for any money.
You can find the code of this web app in github.com here as well as the description of how we built it and the stack of technologies that we used.
We, Santiago and Remy, built this project from scratch without really knowing how it would turn out but with the will to learn something new. And we did.
Carmen helped us a lot with the design of the app, the logo and character (bidulio) and giving us her opinion concerning the usability and design of the app.
We hope you enjoy playing as much as we enjoyed making it.
gonawin logos and images are property of gonawin, you must always request the permission to use them to Carmen.


Value:
Fee:
Contract address:
Function name:
Function params (each param one row, use " to denote string)
Send (Write)
Call (Read)


|
Perl Weekly
Issue #97 - 2013-06-03 - It's YAPC::NA Time!
latest | archive | by Yanick Champoux
|
|
As you are reading this, a vast contingent of the Perl community, including PerlWeekly's very own overlord (hi Gabor!), will already have undergone their yearly migration to the North American edition of YAPC. From Monday to Wednesday, a teeming mass of perl hackers will haunt the streets of sunny Austin, Texas. Wish you were there? Then do the next best things: lurk in the #yapc channel of perl.irc.org, and watch the conference website for announcements of live streaming. ~ Yanick
|
|
|
|
Sponsors
|
We're Hiring Telecommuters - Grant Street Group
We're a growing software company using open source software/modern Perl practices to build innovative e-payment, auction, and tax collection web applications. We're looking for talented, motivated professionals committed to flawless work and customer service. Email resume<EMAIL_ADDRESS>|
|
Headlines
|
Announcing the Perl Companies project
VM Brasseur and Jeff Thalhammer had a chat earlier this month and mused how nice it'd be to have a place listing all companies using Perl. And now, tadah, say 'hi!' to the Perl Companies project.
|
|
My Pro-Tips for YAPC First-Comers
Yanick is a hardened veteran of, uh, 2 YAPCs. Still, he offers some advices to YAPC first-timers on things to do to optimize their conference experience.
|
|
Articles
|
On the importance of localisation
You think you have it hard with localisation? Booking.com services deal with over forty languages. Simona Lazarovici shares with us how they get around dealing with this impressive tower of Babel.
|
|
Paying respect to Module::Build
David Golden proposed earlier this month to move Module::Build out of Perl 5 core. He explains here his rationale, and provides a comprehensive overview of what Module::Build managed to achieve (which is a lot), and what weaknesses proved to be its Achilles's heels.
|
|
|
|
The Design of Four
'ack', 'cpanm', 'local::lib', 'perlbrew'. Four tools that do one thing, and do it exceedingly well. Jeffrey Kegler muses for a few instants on their streamlined design, and discusses on how they can be taken as examples of exquisitely effective interfaces.
|
|
Discussions
|
Using Perl in the Real World (Cookbook)
rlauer laments the lack of Perl one-stop cookbook focusing on interacting with the big applications -- Google Docs, Flickr, Amazon, etc -- out there, and wonders if a wiki or a collaborative venture shouldn't be organized to fill that void.
|
|
Code
|
How I manage new perls with perlbrew
Perl 5.10, 5.12, 5.14, 5.16, 5.18, and all their patch versions... There sure are a lot of perls out there. Even more if you play with the development versions. But thanks to perlbrew and cpanm, compiling a wide selection of them is fairly easy. David Golden walks us through the handful of scripts and tricks he uses to make managing the herd even easier.
|
|
Type::Tiny rescues Moo
Joel Berger gives three cheers for Type::Tiny, which allows for a more homogenous type management throughout the Moo / Moose / Mouse ecosystem.
|
|
|
|
given & smartmatch in Perl 5.18
So the smartmatch has been sort of deprecated in perl 5.18. Turns out that the official documentation showing how to silence its warnings has a small error. domm shows us the corrected version (alongside some legit and sane uses of smartmatch).
|
|
Catalyst Sicilian Buttercup Update
John Napiorkowski gives us a quick update on the current development cycle of Catalyst. He's also at YAPC::NA, and might organize a Catalyst hackaton. If you are there and interested, keep your ears peeled during the lightning talks.
|
|
Perl 6
|
|
|
Weekly Collections
|
|
|
|
|
|
|
|
|
Events
|
|
|
|
|
YAPC::Asia Tokyo
September 19-21, 2013, Keio University Hiyoshi Campus, Tokyo, Japan
|
|
You know, you could get the Perl Weekly right in your mailbox. Every Week. Free of charge!
|


|
SC2API
An API for AI for StarCraft II
|
Data about an ability. More...
#include <sc2_data.h>
Public Types | |
| enum | Target { Target::None = 1, Target::Point = 2, Target::Unit = 3, Target::PointOrUnit = 4, Target::PointOrNone = 5 } |
| Type of target this ability applies to. More... | |
Public Member Functions | |
| AbilityData () | |
| AbilityData constructor. | |
| void | ReadFromProto (const SC2APIProtocol::AbilityData &ability_data) |
| std::string | Log () const |
| Serialize this ability to a string. | |
Public Attributes | |
| bool | available |
| If true, the ability is available to the current mods/map. | |
| AbilityID | ability_id |
| Stable ID. For a given ability, this value will be immutable throughout different patches. | |
| std::string | link_name |
| Catalog (game data xml) name of the ability. | |
| uint32_t | link_index |
| Catalog (game data xml) index of the ability. | |
| std::string | button_name |
| Name of the button for the command card. | |
| std::string | friendly_name |
| In case the button name is not descriptive. | |
| std::string | hotkey |
| UI hotkey. | |
| uint32_t | remaps_to_ability_id |
| This ability id may be represented by the given more generic id. | |
| std::vector< uint32_t > | remaps_from_ability_id |
| Other abilities remapped to this generic ability. | |
| Target | target |
| Determines if a point, unit, both or none is required as a target. | |
| bool | allow_minimap |
| Can be cast in the minimap. (Not implemented) | |
| bool | allow_autocast |
| Autocast can be set. | |
| bool | is_building |
| Requires placement to construct a building. | |
| float | footprint_radius |
| If the ability is placing a building, give the radius of the footprint. | |
| bool | is_instant_placement |
| Placement next to an existing structure, e.g., an add-on like a Tech Lab. | |
| float | cast_range |
| Range unit can cast ability without needing to approach target. | |
Data about an ability.
|
strong |
| void sc2::AbilityData::ReadFromProto | ( | const SC2APIProtocol::AbilityData & | ability_data | ) |
Serialize this ability entry from the .proto file (used internally).
| ability_data | The proto entry for this ability. |


project
classwork assignments
CW_2 NFA & DFA
CW_3 Regular Expressions
homework assignments
HW1
useful links
»
developer.mozilla
»
w3schools
»
tutorialspoint
»
javascript.info


If you want to display many dataset of the same structure you might consider using the List object.
The List object supports multi-line list items and can show icons. Multi-line items are created by dividing each list item up using the “:” (colon) character. If you need to use a colon character in your item text then use this character sequence: “^c^”.
You can have one icon and some body text using the following formats:
“title”
“title:icon”
“title:body:icon”
Alternatively you can use the AddItem method which accepts title, body and icon as parameters to generically build up your list.
You can specify your own icon file for example “Img/MyIcon.png”, or one of the special built-in icons using the following key words: “audio”, “photo”, “video”, “folder”, “audiofolder”, “photofolder”, “videofolder” and “playlist”.
Example - Title + Icon
function OnStart()
{
lay = app.CreateLayout( "Linear", "VCenter,FillXY" );
var data = "Folder:folder,Audio:audio,Photo:photo,Video:video";
lst = app.CreateList( data, 0.8, 0.4 );
lst.SetOnTouch( lst_OnTouch );
lay.AddChild( lst );
app.AddLayout( lay );
}
function lst_OnTouch( title, body, type, index )
{
app.ShowPopup( "Touched Item = " + title );
}
Example - Title + Body
function OnStart()
{
lay = app.CreateLayout( "Linear", "VCenter,FillXY" );
var data = "The Hobbit:Author^c^ J.R.R. Tolkien:null";
data += ",Watership Down:Author^c^ Richard Adams:null";
lst = app.CreateList( data, 0.8, 0.4 );
lst.SetOnTouch( lst_OnTouch );
lay.AddChild( lst );
app.AddLayout( lay );
}
function lst_OnTouch( title, body, type, index )
{
app.ShowPopup( "Touched Item = " + title );
}
You can use the SetOnTouch and SetOnLongTouch methods to define a function you want to be called when a list item is selected. The selected item title, body, type and index are passed into your OnTouch callback function as parameters.
Example - Simple
function OnStart()
{
lay = app.CreateLayout( "Linear", "VCenter,FillXY" );
lst = app.CreateList( "Fred,Bill,Jim", 0.8, 0.4 );
lst.SetOnTouch( lst_OnTouch );
lst.SetOnLongTouch( lst_OnLongTouch );
lay.AddChild( lst );
app.AddLayout( lay );
}
function lst_OnTouch( title, body, type, index )
{
app.ShowPopup( "Item = " + title + ", Index = " + index, "Short" );
}
function lst_OnLongTouch()
{
app.ShowPopup( "Long Touch Item = " + title + ", Index = " + index, "Short" );
}
You can change the look of a List using the SetBackColor and SetTextColor functions on the list object. You can also set a background image/pattern or background gradient for the List using the SetBackground and SetBackGradient functions.
Example - Gray on White
function OnStart()
{
lay = app.CreateLayout( "Linear", "VCenter,FillXY" );
lst = app.CreateList( "Fred,Bill,Jim", 0.8, 0.4 );
lst.SetTextColor( "#ff666666" );
lst.SetBackColor( "#ffffffff" );
lst.SetOnTouch( lst_OnTouch );
lay.AddChild( lst );
app.AddLayout( lay );
}
function lst_OnTouch( title, body, type, index )
{
app.ShowPopup( "Touched Item = " + title );
}
You can also create lists items that look like buttons by using one of the following options: “AlumButton”, “GreenButton”, “OrangeButton”.
Example - Orange Buttons
function OnStart()
{
lay = app.CreateLayout( "Linear", "VCenter,FillXY" );
var data = "Button 1,Button 2,Button 3,Button 4";
lst = app.CreateList( data, 0.8, 0.8, "OrangeButton" );
lst.SetBackColor( "#ffffff" );
lst.SetPadding( 0.1, 0.1, 0.1, 0.1 );
lst.SetOnTouch( lst_OnTouch );
lay.AddChild( lst );
app.AddLayout( lay );
}
function lst_OnTouch( title, body, type, index )
{
app.ShowPopup( "Touched Item = " + title );
}
Or create lists with Gradient backgrounds like this:
Example - Gradient Background
function OnStart()
{
lay = app.CreateLayout( "Linear", "VCenter,FillXY" );
var data = "";
for( var i = 1; i <= 30; i++ )
{
if( i > 1 ) data += ",";
data += "Item " + i + ":Details for item " + i + ":null";
}
lst = app.CreateList( data, 1, 1, "WhiteGrad" );
lst.SetTextColor1( "#ff555558");
lst.SetTextColor2( "#ff555558" );
lst.SetTextMargins( 0.04, 0, 0, 0 );
lst.SetOnTouch( lst_OnTouch );
lay.AddChild( lst );
app.AddLayout( lay );
}
function lst_OnTouch( title, body, type, index )
{
app.ShowPopup( "Touched Item = " + title );
}
Methods
The following methods are available on the List object:
boolean
app object
number
string
unknown
number: angle in degrees (0..360)
number: factor
number: fraction (0..1)
number: integer
number: milliseconds
number: -180..180
number: -100..100
number: 0..100
number: 0..0.99 or 1..256
string:
hexadecimal: “#rrggbb”, “#aarrggbb”
colourName: “red”, “green”, ...
string: comma “,” separated
string: path to file or folder ( “/absolute/...” or “relative/...” )
string: comma “,” separated: “Expand”,
“Menu”,
“Horiz”,
“html”,
“FontAwesome”,
“monospace”,
“Normal”,
“WhiteGrad” or
“AlumButton” or
“GreenButton” or
“OrangeButton”,
“NoSound”
string: “px”
string: “screen”, “px”
string: “left-right” or “right-left” or “top-bottom” or “bottom-top” or “bl-tr” or “br-tl” or “tl-br” or “tr-bl”
string: “repeat”
string: “Add” or “Multiply” or “clear” or “darken” or “lighten” or “overlay” or “screen” or “xor” or “src_in” or “src_out” or “src_atop” or “src_over” or “dst_in” or “dst_out” or “dst_atop” or “dst_over”
string: “px” or “sp” or “dip” or “mm” or “pt”
string: “start” or “middle” or “end”
string: separated: “title” or “title:icon” or “title:body:icon”
string: “px” or “sp” or “dip” or “dp” or “mm” or “pt”
string: “px” or
“dip” or
“sp” or
“mm” or
“pt” or
“pl” or
“ps”
string: “Show” or “Hide” or “Gone”
string: “Linear.None” or “Quadratic.In/Out” or “Cubic.In/Out” or “Quartic.In/Out” or “Quintic.In/Out” or “Sinusoidal.In/Out” or “Exponential.In/Out” or “Circular.In/Out” or “Elastic.In/Out” or “Back.In/Out” or “Bounce.In/Out”
object: {
x,
y,
w,
w,
sw,
sh,
rot }
list: boolean,char,byte,short,int,long,float,double,String,CharSequence,...
function()
lst.AddItem
Adds an entry to the list.
lst.AdjustColor
Adjust the visual color effect of the control by setting the Hue (by angle in degrees in a color circle), the saturation, brightness and contrast of the control.
lst.ClearFocus
Removes the focus of the control so that the user no longer has immediate access to it.
lst.Focus
Set the focus to the control so that the user can interact with it immediately.
lst.GetAbsHeight
Get the absolute height of the control in pixels.
lst.GetAbsWidth
Get the absolute width of the control in pixels.
lst.GetHeight
Get the height of the control as screen height relative float or in pixels with the px option.
lst.GetItem
Returns item data of an item with a specific title.
lst.GetItemByIndex
Returns item data of an item on a specific index.
lst.GetLeft
Get the distance from the control to the left parent border as width relative float or in pixels with the px option.
lst.GetLength
Returns the amount of items in the lists.
lst.GetList
Returns the full list data as an object.
lst.GetParent
Returns the parent control object where the object was added to - commonly a layout.
lst.GetPosition
Returns data about the position and size of the control.
If the screen option is given the position on the screen will be returned. Otherwise relative to the parent control.
The px options turns the relative values into pixels.
lst.GetTextSize
Returns the current size of the contained text. If the px option is given the size will be retured in pixels.
lst.GetTop
Get the distance from the control to the upper parent border as height relative float or in pixels with the px option.
lst.GetType
Returns the control class name.
lst.GetVisibility
Returns the current visibility state of the control. The Values are:
Show: visible
Hide: invisible but still consuming space
Gone: invisible and not consuming space
lst.GetWidth
Get the width of the control as screen width relative float or in pixels with the px option.
lst.Gone
Hides the control without consuming any more layout space as if it were never there.
lst.Hide
Hide the control but keep the layout space free.
lst.InsertItem
Inserts an item at s specific index in the list.
lst.IsEnabled
Returns whether the control is currently useable by the user.
lst.IsOverlap
Returns whether the control overlaps with another by a given distance.
lst.IsVisible
Returns whether the control is currently visible to the user, ignoring overlaying controls.
lst.MethodAllows access to other functions defined on the object in Java via reflection.
Note: This function is a premium feature. Please consider subscribing to Premium to use this feature and support DroidScript in its further development.
lst.RemoveAll
Removes all entries of the list.
lst.RemoveItem
Removes an item with a specific title from the list.
lst.RemoveItemByIndex
Removes an item on a specific index from the list
lst.ScrollToItem
Scrolls the list to an item with a specific title.
lst.ScrollToItemByIndex
Scrolls the list to an item on a specific index.
lst.SelectItem
Highlights an item with a specific title.
lst.SelectItemByIndex
Highlights an item on a specific index.
lst.SetBackAlpha
Set the transparency of the background by an alpha value between 0 (no transparency) and 0.99 (full transparent) or 1 (no transparency) and 256 (full transparent)
lst.SetBackColor
Changes the background color of the control.
lst.SetBackGradient
Define the background color of the control with a gradient. The default gradient direction is from top to bottom, but you can change it from left to right and the reversed versions of course.
lst.SetBackGradientRadial
Define a radial color gradient for the background of control.
lst.SetBackground
Changes the background to an image which can be repeated using the repeat option.
An image which is often used with that option is '/res/drawable/pattern_carbon' - try it out!
lst.SetColorFilterAdjust the visual color effect with a color and a given BlendMode. More information about BlendMode can be found in the
Android Developer page.
lst.SetColumnWidths
Changes the coloumn withs for title, body and icon. Often used with the “Horiz” option.
lst.SetDivider
Changes the item divider height and color.
lst.SetEllipsize
Will cause the inner text to be broken with ... at the start or the end if it cannot fit in the control.
lst.SetEllipsize1
Will cause the element titles to be broken with ... at the start or the end if it cannot fit in the control.
lst.SetEllipsize2
Will cause the element bodies to be broken with ... at the start or the end if it cannot fit in the control.
lst.SetEnabled
En/Disable the control physically and visually so that the user can/can not access the control. Events like OnTouch will still be fired.
lst.SetFontFile
Change the font style by defining a font file.
lst.SetHiTextColor1
Change the highlight color of titles when selected.
lst.SetHiTextColor2
Change the highlight color of bodies when selected.
lst.SetIconMargins
Change the outer icon border distance.
lst.SetIconSize
Changes the icon size.
lst.SetItem
Change the content of an element with a specific title.
lst.SetItemByIndex
Change the content of an element on a specific index.
lst.SetList
Set the content of the whole list.
lst.SetMargins
Define a distance to other controls on each side of the control.
lst.SetOnLongTouch
Define a callback function which is called when the object has been long pressed.
lst.SetOnTouch
Define a callback function that is called when the user touches the control.
lst.SetPadding
Define distances that elements within the control are to maintain from the control borders.
lst.SetPosition
Defines the position and size for the control if the parent is an absolute layout.
lst.SetScale
Scales the control along with its contents by the factors passed to the function.
lst.SetSize
Change the size of the control in either screen relative values or in pixels if the px option was given.
lst.SetTextColor
Change the text color of the contained text.
lst.SetTextColor1
Change the default text color of titles.
lst.SetTextColor2
Change the default text color of bodies.
lst.SetTextShadow
Define a shadow displayed around the control.
The sun is always shining so there has to be one. Always.
lst.SetTextShadow1
Apply text shadows to titles.
lst.SetTextShadow2
Apply text shadows to bodies.
lst.SetTextSize
Change the size of the contained text.
lst.SetTextSize1
Change the text size for titles.
lst.SetTextSize2
Change the text size for bodies.
lst.SetVisibility
Change the visibility of the control to one of the available modes:
Show: visible
Hide: invisible but still consuming space
Gone: invisible and not consuming space
lst.Show
Set the visibility of the control to “Show”.
lst.Tween
Performs an animation on the control.
The target object is for the position, size and rotation that the control has at the end of the animation.
The type specifies the behavior and the speed of the animation. Separated by a dot, you must also specify whether you want to apply this behavior to the beginning (In), end (Out), or to both (InOut) times of the animation.

If you have jojo activated, the animation will alternate between forward and backward playback, so that if the repetition value is odd, the control will be at the start position again at the end of the animation.
Finally the callback function will be called after the animation has finished. Well, it's about time!


Confirming the JavaScript dialog on this page will clear your browser's localStorage for
GW2Timer.com


Total Users (Since $var-dateSince$)
Total Referrals:
Nr. of referrals by Total Users:
Nr. of referrals by Referring Users:


Zmanim Parshas Bamidmar
Friday, May 26, 2017 - Rosh Chodesh Sivan
Erev Shabbos Kodesh Parshas Bamidmar
Candle Lighting - 7:57 pm
First Minyan for Mincha - 7:00 pm
Mincha B'Zman - 8:15 pm
Please repeat Krias Shma and count Sefira after 9:06 pm
Shabbos, May 27, 2017 - Shabbos Kodesh Parshas Bamidmar
Shachris - 9:15 am
Sof Z’man Kriyas Shma – 8:34 am/9:10 am
Groups - 9:30 am
Ruv's Pirkei Avos Shiur - 7:45 pm
Mincha - 8:1o pm
Followed by Sholosh Seudas
Maariv - 9:06 pm
Sunday-Thursday
Mincha/Maariv - 8:55 pm
Friday, June 2, 2017 - Erev Shabbos Kodesh Parshas Naso
Candle Lighting - 8:02 pm
First Minyan for Mincha - 7:00 pm
Mincha B'Zman - 8:20 pm
Shavuos Zmanim to Follow
Contact us and we'll get back to you shortly.
352 West Broadway, Cedarhurst NY 11516
(516) 791-1001


File Scan allows the user to scan large volumes of data together. The format of the file can be csv or xml file. It has a build-in algorithm to check the unique of each record if the record itself does not have a unique Id. The scan result will be loaded into Watch List Alert database for review.
Click the File Scan in the left navigation menu under Screening management, a new File Scan Tab folder will be created in the right panel. T
Click on Next button to go to file upload page.
Click the Browse.. Button to open a window. Then select a file to be uploaded. The file will be saved temporarily in the server. The user can check the “append timestamp” checkbox to append the current timestamp into the file name. If the same file name exists in the server, it will be automatically renamed by adding _v# in the end of the file, where # can be 1, 2, 3, etc. For example, if the file name is customer_data_file.csv, it will be renamed to customer_data_file_v1.csv.
Click the Submit Button to upload the file into server. Depending on the size of the file, it may take a couple of minutes to upload.
Click OK to close this popup window; then click Next Button.
| Field Name | Description |
|---|---|
| OrgUnit Code | The Orgunit the watch list alert will be saved to. select a value from the orgunit dropdown list. This is a mandatory field. |
| File Fame | Preset from the previous page. This is the file just uploaded. |
| File Format | The format of this file just uploaded; Select a value from the dropdown list. This is a mandatory field. |
| Full File Scan | If this checkbox is checked, the watch list alerts for this ORGUNIT that are not in this file will be deleted from the database. |
Note
Users need to define a batch scan file format. Each client list (Organization Unit) can have different file formats or/and screening engine service parameters, based on its risks. Please see File Format for details.


The brainy, briny waters of destiny beckoned him forward, informing him that his future would be both extraordinary and unpredictable. [G|D]
He felt a deep sense of grainyhominy and ignominy fill the air, signifying that he was doomed to a life of shame and humiliation. [G|D]
When the crew of the ship decided to mutiny against their captain, they were met with a great deal of scrutiny and shiny glares of disapproval from their peers. [G|D]
The spiny tentacles of villainy wrapped around him, radiating a whiny hum that made his skin crawl with dread. [G|D]


--- redirect_from: - /supervisors-and-students/ - /advisory-board/ - /advisors/ - /students/ - /supervisors/ layout: default ---
{{ student.project }}
{{ supervisor.role }}
{{ advisor.role }}
{{ advisor.institution }}


Blog Category - VS2010
- Visual Studio 2010 downloads (30 Nov 2009)
- Visual Studio 2010 intellisense "consume first" (04 Dec 2009)
- Visual Studio 2010 Release Candidate (13 Feb 2010)
- Microsoft TechDays roundup (31 Mar 2010)
- Visual Studio 2010 editions (22 Apr 2010)
- Visual Studio navigation (04 May 2010)
- Smart Paste in 2010 (06 Jun 2010)
- Database Schema Reader (01 Nov 2010)
- Publish and Transform in MSBuild script (07 Apr 2011)
- T4 preprocessing (10 Jun 2011)
- MCPD Web Developer .Net 4 (10 Dec 2011)
- Visual Studio 2010 - find TFS working directory (05 Jan 2012)


| | |
- builtins.object
-
- EGWTemplate
class EGWTemplate(builtins.object) |
| |
EGWTemplate(name=None, box=[], box_format=0)
provides the interface for working with a template.
properties with `_max`-suffix represent the maximum values for the template
without need for upscaling it (and nope, we don't upscale). |
| |
Methods defined here:
- __init__(self, name=None, box=[], box_format=0)
- Initialize self. See help(type(self)) for accurate signature.
- add_text(self, **kwargs)
- adds text (title) below the paste-box
returns
Image instance
- get_image(self)
- btw. don't forget to call .paste() first
returns
Image instance with pasted image in template
- paste(self, image, alpha_blend=1.0, max=False, return_only_region_blended=False)
- pastes Image instance into the .box of the template
(not init box_max! but usually they are the same for now
but we'll change this, see #11)
returns
Image instance
- resize(self, size=None)
- resizes the ("work copy"-) template (only downscaling is allowed)
(and changes the .box, .size, ... properties accordingly - the properties
with the suffix _max will not be touched: they represent the original
template (maximum quality))
Data descriptors defined here:
- __dict__
- dictionary for instance variables (if defined)
- __weakref__
- list of weak references to the object (if defined)
- box
- returns
list(left, upper, right, lower) - positioning of the current paste-area
- box_format
- returns format of the paste-area (box) human-readable
- box_max
- returns
list(left, upper, right, lower) - positioning of the max-sized paste-area
- box_size
- returns
tuple(w,h) : width, height of the current paste-area for template
- box_size_max
- returns
tuple(w,h) : width, height of the max paste-area for template
without upscaling the template
- fqfn
- help
- iface_version
- returns interface version
- image
- returns
Image instance : the custom-size template
(at the moment 1:1 _max but we wanna change this later
and use .scale-funcs etc. #11)
- image_max
- returns
Image instance : the original template (max size)
- info
- shows infos about the current state of the template
- name
- search_paths
- size
- returns
tuple(w,h) : current width, height of the template
- size_max
- returns
tuple(w,h) : max width, height of the template
Data and other attributes defined here:
- BOX_FORMATS = {'free': 10, 'square': 0}
- l_search_paths = ['/home/s3h10r/development/einguteswerkzeug/venv/l...s/einguteswerkzeug/core/template/../../templates/']
| |


I'm a software engineer who wants to be a craftsman in his profession one day.
I'm a software engineer who wants to be a craftsman in his profession one day.
Member of k6 Ecosystem Team
(Go, JavaScript, React, HTML, CSS)
System architect of navigation services
Support and coach software architects
Architect authentication/authorization/licensing related development
Lead by example in software development, automated testing, documenting
Evaluating and selecting technologies to use
(Go, JavaScript, Java, HTML, CSS)
Leader of 4 Engineering Managers (4 developer teams, 2 operation teams)
Support and coach Engineering Managers
Emphasis on Software Engineering
Supporting the recruitment of a successor
System Architect of navigation related Enterprise Java development projects
Leading the architecture team (3 java architects)
Technical leader of 18 java developers and 3 test automation developers
Evaluating and selecting new technologies
Making technology related decisions
Recruiting new java developers
Managing code quality (measure, create quality profiles)
Introduction of Continuous Delivery
(J2EE, JavaScript, HTML, CSS, REST, Maven, SVN, Ant, Struts, Linux, PostgreSQL, Apache httpd, Jenkins, Sonar, JUnit, EasyMock, Mockito, JaCoCo, ANTLR)
Formation of server-side development teams
Leading the development team (15 java programmers)
Supervising the system administrator team (3 system administrators)
Designing system architecture
Evaluating and selecting technologies to use
Recruiting new java developers
Cooperating with project managers in a matrix structure
Making technology related decisions
(J2EE, JavaScript, HTML, CSS, REST, Maven, SVN, Ant, Struts, Linux, PostgreSQL, Apache httpd, Jenkins, Sonar, JUnit, EasyMock, Mockito, JaCoCo, ANTLR)
Architect and technical lead of Bonus.com development (was a popular kid web site in US)
Technical leader of development team (6-10 java developers)
Technical leader of system administrator team (2 Unix administrators)
Creating system architecture (web, geographic DNS based load balancer, database)
Recruiting new team members
Making technology related decisions
(Java Servlets, Tomcat, Apache httpd, MySQL, CVS, Ant, Struts, JSP, HTML, CSS, JavaScript)
Developing key software components of Bonus.com (was a popular kid web site in US)
Operation of 6-8 production servers (Solaris, Digital Unix, Linux) and several staging server
Managing network and server security, firewalls
Maintaining company email system
(C/C++, Java Applets, PHP, Python, Unix shell scripts, RPM, APT, Digital Unix, Sun Solaris, Linux, FreeBSD)
Developed software components of Bonus.com (was a popular kid web site in US)
(C/C++, HTML, CSS)
Developed and administered company internal network and production web servers
Design and implementation of company internet services and connections
Design and implementation of network firewalls for company and for production servers
Installation and operation of several different Unix systems
Managing network and server security
(Digital Unix, Linux, Cisco routers, Unix shell scripts, HTTP, SMTP, DNS, NTP, SSH, SSL, DHCP)
I taught programming languages (C/C++ and x86 assembly), object oriented programming and computer networks for programmers.
(C/C++, x86 assembly, TCP/IP, Novell NetWare)
Probably it was one of the first intranet applications, but at that time the term intranet was not introduced yet.


Tutorial: Writing a simple extension¶
This section is intended as a walkthrough for the creation of custom extensions. It covers the basics of writing and activating an extension, as well as commonly used features of extensions.
As an example, we will cover a “todo” extension that adds capabilities to include todo entries in the documentation, and to collect these in a central place. (A similar “todo” extension is distributed with Sphinx.)
 These are:
- Application
The application object (usually called
app
) is an instance ofSphinx
. It controls most high-level functionality, such as the setup of extensions, event dispatching and producing output (logging).If you have the environment object, the application is available as
env.app
.- Environment
The build environment object (usually called
env
) is an instance ofBuildEnvironment
. It is responsible for parsing the source documents, stores all metadata about the document collection and is serialized to disk after each build.Its API provides methods to do with access to metadata, resolving references, etc. It can also be used by extensions to cache information that should persist for incremental rebuilds.
If you have the application or builder object, the environment is available as
app.env
orbuilder.env
.- Builder
The builder object (usually called
builder
) is an instance of a specific subclass ofBuilder
. Each builder class knows how to convert the parsed documents into an output format, or otherwise process them (e.g. check external links).If you have the application object, the builder is available as
app.builder
.- Config
The config object (usually called
config
) provides the values of configuration values set inconf.py
as attributes. It is an instance ofConfig
.The config is available as
app.config
orenv.config
.
Build Phases¶
One thing that is vital in order to understand extension mechanisms is the way in which a Sphinx project is built: this works in several phases.
Phase 0: Initialization
In this phase, almost nothing of interest to us happens. The source directory is searched for source files, and extensions are initialized. Should a stored build environment exist, it is loaded, otherwise a new one is created.
Phase 1: Reading
In Phase 1, all source files (and on subsequent builds, those that are new or changed) are read and parsed. This is the phase where directives and roles are encountered by docutils, and the corresponding code is executed. The output of this phase is a doctree for each source file; that is a tree of docutils nodes. For document elements that aren’t fully known until all existing files are read, temporary nodes are created.
There are nodes provided by docutils, which are documented in the docutils documentation. Additional nodes are provided by Sphinx and documented here.
During reading, the build environment is updated with all meta- and cross reference data of the read documents, such as labels, the names of headings, described Python objects and index entries. This will later be used to replace the temporary nodes.
The parsed doctrees are stored on the disk, because it is not possible to hold all of them in memory.
Phase 2: Consistency checks
Some checking is done to ensure no surprises in the built documents.
Phase 3: Resolving
Now that the metadata and cross-reference data of all existing documents is known, all temporary nodes are replaced by nodes that can be converted into output using components called tranform. For example, links are created for object references that exist, and simple literal nodes are created for those that don’t.
Phase 4: Writing
This phase converts the resolved doctrees to the desired output format, such as HTML or LaTeX. This happens via a so-called docutils writer that visits the individual nodes of each doctree and produces some output in the process.
Note
Some builders deviate from this general build plan, for example, the builder that checks external links does not need anything more than the parsed doctrees and therefore does not have phases 2–4.
Extension Design¶
We want the extension to add the following to Sphinx:
- A “todo” directive, containing some content that is marked with “TODO”, and only shown in the output if a new config value is set. (Todo entries should not be in the output by default.)
- A “todolist” directive that creates a list of all todo entries throughout the documentation.
For that, we will need to add the following elements to Sphinx:
- New directives, called
todo
andtodolist
. - New document tree nodes to represent these directives, conventionally also
called
todo
andtodolist
. We wouldn’t need new nodes if the new directives only produced some content representable by existing nodes. - A new config value
todo_include_todos
(config value names should start with the extension name, in order to stay unique) that controls whether todo entries make it into the output. - New event handlers: one for the :event:`doctree-resolved` event, to replace the todo and todolist nodes, and one for :event:`env-purge-doc` (the reason for that will be covered later).
The Setup Function¶
The new elements are added in the extension’s setup function. Let us create a
new Python module called todo.py
and add the setup function:
def setup(app):
app.add_config_value('todo_include_todos', False, 'html')
app.add_node(todolist)
app.add_node(todo,
html=(visit_todo_node, depart_todo_node),
latex=(visit_todo_node, depart_todo_node),
text=(visit_todo_node, depart_todo_node))
app.add_directive('todo', TodoDirective)
app.add_directive('todolist', TodolistDirective)
app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos)
return {'version': '0.1'} # identifies the version of our extension
The calls in this function refer to classes and functions not yet written. What the individual calls do is the following:
add_config_value()
lets Sphinx know that it should recognize the new config valuetodo_include_todos
, whose default value should beFalse
(this also tells Sphinx that it is a boolean value).If the third argument was
'html'
, HTML documents would be full rebuild if the config value changed its value. This is needed for config values that influence reading (build phase 1).add_node()
adds a new node class to the build system. It also can specify visitor functions for each supported output format. These visitor functions are needed when the new nodes stay until phase 4 – since thetodolist
node is always replaced in phase 3, it doesn’t need any.We need to create the two node classes
todo
andtodolist
later.add_directive()
adds a new directive, given by name and class.The handler functions are created later.
Finally,
connect()
adds an event handler to the event whose name is given by the first argument. The event handler function is called with several arguments which are documented with the event.
The Node Classes¶
Let’s start with the node classes:
from docutils import nodes
class todo(nodes.Admonition, nodes.Element):
pass
class todolist(nodes.General, nodes.Element):
pass
def visit_todo_node(self, node):
self.visit_admonition(node)
def depart_todo_node(self, node):
self.depart_admonition(node)
Node classes usually don’t have to do anything except inherit from the standard
docutils classes defined in docutils.nodes
. todo
inherits from
Admonition
because it should be handled like a note or warning, todolist
is just a “general” node.
The Directive Classes¶
A directive class is a class deriving usually from
docutils.parsers.rst.Directive
. The directive interface is also
covered in detail in the docutils documentation; the important thing is that
the class should have attributes that configure the allowed markup,
and a run
method that returns a list of nodes.
The todolist
directive is quite simple:
from docutils.parsers.rst import Directive
class TodolistDirective(Directive):
def run(self):
return [todolist('')]
An instance of our todolist
node class is created and returned. The
todolist directive has neither content nor arguments that need to be handled.
The todo
directive function looks like this:
from sphinx.locale import _
class TodoDirective(Directive):
# this enables content in the directive
has_content = True
def run(self):
env = self.state.document.settings.env
targetid = "todo-%d" % env.new_serialno('todo')
targetnode = nodes.target('', '', ids=[targetid])
todo_node = todo('\n'.join(self.content))
todo_node += nodes.title(_('Todo'), _('Todo'))
self.state.nested_parse(self.content, self.content_offset, todo_node)
if not hasattr(env, 'todo_all_todos'):
env.todo_all_todos = []
env.todo_all_todos.append({
'docname': env.docname,
'lineno': self.lineno,
'todo': todo_node.deepcopy(),
'target': targetnode,
})
return [targetnode, todo_node]
Several important things are covered here. First, as you can see, you can refer
to the build environment instance using self.state.document.settings.env
.
Then, to act as a link target (from the todolist), the todo directive needs to
return a target node in addition to the todo node. The target ID (in HTML, this
will be the anchor name) is generated by using env.new_serialno
which
returns a new unique integer on each call and therefore leads to unique target
names. The target node is instantiated without any text (the first two
arguments).
On creating admonition node, the content body of the directive are parsed using
self.state.nested_parse
. The first argument gives the content body, and
the second one gives content offset. The third argument gives the parent node
of parsed result, in our case the todo
node.
Then, the todo node is added to the environment. This is needed to be able to
create a list of all todo entries throughout the documentation, in the place
where the author puts a todolist
directive. For this case, the environment
attribute todo_all_todos
is used (again, the name should be unique, so it is
prefixed by the extension name). It does not exist when a new environment is
created, so the directive must check and create it if necessary. Various
information about the todo entry’s location are stored along with a copy of the
node.
In the last line, the nodes that should be put into the doctree are returned: the target node and the admonition node.
The node structure that the directive returns looks like this:
+--------------------+
| target node |
+--------------------+
+--------------------+
| todo node |
+--------------------+
\__+--------------------+
| admonition title |
+--------------------+
| paragraph |
+--------------------+
| ... |
+--------------------+
The Event Handlers¶
Finally, let’s look at the event handlers. First, the one for the :event:`env-purge-doc` event:
def purge_todos(app, env, docname):
if not hasattr(env, 'todo_all_todos'):
return
env.todo_all_todos = [todo for todo in env.todo_all_todos
if todo['docname'] != docname]
Since we store information from source files in the environment, which is
persistent, it may become out of date when the source file changes. Therefore,
before each source file is read, the environment’s records of it are cleared,
and the :event:`env-purge-doc` event gives extensions a chance to do the same.
Here we clear out all todos whose docname matches the given one from the
todo_all_todos
list. If there are todos left in the document, they will be
added again during parsing.
The other handler belongs to the :event:`doctree-resolved` event. This event is emitted at the end of phase 3 and allows custom resolving to be done:
def process_todo_nodes(app, doctree, fromdocname):
if not app.config.todo_include_todos:
for node in doctree.traverse(todo):
node.parent.remove(node)
# Replace all todolist nodes with a list of the collected todos.
# Augment each todo with a backlink to the original location.
env = app.builder.env
for node in doctree.traverse(todolist):
if not app.config.todo_include_todos:
node.replace_self([])
continue
content = []
for todo_info in env.todo_all_todos:
para = nodes.paragraph()
filename = env.doc2path(todo_info['docname'], base=None)
description = (
_('(The original entry is located in %s, line %d and can be found ') %
(filename, todo_info['lineno']))
para += nodes.Text(description, description)
# Create a reference
newnode = nodes.reference('', '')
innernode = nodes.emphasis(_('here'), _('here'))
newnode['refdocname'] = todo_info['docname']
newnode['refuri'] = app.builder.get_relative_uri(
fromdocname, todo_info['docname'])
newnode['refuri'] += '#' + todo_info['target']['refid']
newnode.append(innernode)
para += newnode
para += nodes.Text('.)', '.)')
# Insert into the todolist
content.append(todo_info['todo'])
content.append(para)
node.replace_self(content)
It is a bit more involved. If our new “todo_include_todos” config value is false, all todo and todolist nodes are removed from the documents.
If not, todo nodes just stay where and how they are. Todolist nodes are
replaced by a list of todo entries, complete with backlinks to the location
where they come from. The list items are composed of the nodes from the todo
entry and docutils nodes created on the fly: a paragraph for each entry,
containing text that gives the location, and a link (reference node containing
an italic node) with the backreference. The reference URI is built by
app.builder.get_relative_uri
which creates a suitable URI depending on the
used builder, and appending the todo node’s (the target’s) ID as the anchor
name.


Currently the parser is very simplistic (not so the lexical analyser): it only recognised rule sets and, from those rules, only display and position properties are syntactically checked and returned in a sort of simplified CSS Object Model.
However it should be able not only to read any other CSS rule, but also recover both for true CSS errors and for those other parts of the grammar that have not been implemented yet (for example, “import” rules).
The HTML files in this folder try to test only that thing: the parser, to check that errors do not force infinite loops and things like that.
This template is wrong.
So it should not be recognised.
But this is right.
And therefore it should be parsed and painted.


Project name
University Deadlines
Jobs & placements
F1 Visa Interviews
Heading for the website
Text about the website
View navbar docs »
College
Click here
Dropdown header
HTML
CSS
JavaScript
Name
Tutorials
Dropdown header
HTML
CSS
JavaScript
Department
Click here
Dropdown header
HTML
CSS
JavaScript
Year of placement
Tutorials
Dropdown header
HTML
CSS
JavaScript
Course
Click here
Dropdown header
HTML
CSS
JavaScript
package
Tutorials
Dropdown header
HTML
CSS
JavaScript
Company
Click here
Dropdown header
HTML
CSS
JavaScript
Upload university
Deadline
Upload a job &
placement Note
Upload a Visa
experience
N search results found
College
Department
Degree
Semester
Finacial
1,001
Lorem
ipsum
dolor
sit
1,002
amet
consectetur
adipiscing
elit
1,003
Integer
nec
odio
Praesent
1,003
libero
Sed
cursus
ante


Please enter all the requested information below to generate your new email signature!
Update all the data below to the values that corespond to you.
Drag and select the whole signature below and hit Ctrl + C.
Create a new signature in Outlook and name it what you like.
In the signature window's empty text field, hit Enter once and then hit Ctrl + V.
Set the new signature as default and hit OK.
You're done!
{{sigData.name}} |
|
{{sigData.title}} |
|
{{sigData.street}} | {{sigData.city}}, {{sigData.state}} {{sigData.zipCode}} |
|
Office {{sigData.officeNumber}} x{{sigData.extention}} | Cell {{sigData.cellNumber}} |
|


{% extends "layout.html" %} {% block page_title %} GOV.UK prototype kit {% endblock %} {% block content %} Choose a project Choose which project you would like to add the participant information to: Enter the name of your project or select from the dropdown categories below Project Name Choose project portfolio Immigration Borders OSCT Crime, Police and Fire HMPO Enablers {% endblock %}
Enter the name of your project or select from the dropdown categories below