A Nuke plugin that helps to visualize the application profiling information in a more convenient and user friendly manner.
The plugin is still in the stage of development so code is not yet documented as things could change or be moved/removed. Also readme is work in progress.
Save the plugin in your .nuke directory or in a custom directory and then import ProfileInspector
in your menu.py.
Remember: If you use a custom plugin path, add the path in your init.py: nuke.pluginAddPath('custom/path')
.
N.B. if your downloaded zip folder has a different name (ProfileInspector-master, ProfileInspector-0.0.2 etc.), then you need to rename it to just ProfileInspector.
Once done it can be found inside a panel -> Windows -> Custom -> ProfileInspector.
The plugin does not introduce new workflows in terms of how to use the Nuke profiling options, but to summarize:
Dag Inspector
XML Inspector
Each page offers a What's This? option. This will show some additional information on certain sections.
Profile Inspector offers mainly 2 modes:
It also offers a convenient way (Nuke Launcher) to launch a Nuke instance with the profiling listener activated so to generate the xml report file.
The dag inspector offers a table view for current dag nodes. When the profiling is activated, the table shows each node profiling timers: callCount, timeTakenCpu, timeTakenWall.
Some of the features are:
This section offers the ability to import the file that Nuke generates when launched with the -Pf
arguments.
Much like the DAG table, users can filter nodes, change the profiling timings, and so on.
The window can also be un-docked (see dock windows for more info).
This section offers a convenient way to launch a new Nuke instance with the profiler listener activated.
This will be the equivalent of launching Nuke via terminal with the nuke.exec -Pf file.xml project.nk
arguments.
Options available:
This option is labeled experimental because I am not entirely sure about its use cases.
Based on my experience with other softwares, when I work on a single frame, I use the profiling to understand how "heavy" the something is with the current parameters settings.
But Nuke doesn't really work in that way and it keeps accumulating the timings even if the settings are turn to 0, i.e., just by moving the knob parameters up and down, the timers will increment regardless if you are using 100% or 1% of a specific parameter.
So the idea behind the live update is that; at each node parameter parameter change, a callback will be triggered (via either updateUI
or knobChanged
) and the profiling timers will reset. This will (likely) give you a representation of what the node is actually "consuming" with the current parameters settings.
This can be used on a frame by frame basis to manually adjust the node knob parameters to adjust performance.
Again, this section needs more tests and understanding so please let me know if you have some insights.
This feature is a leftover of a prototype and will probably be removed in future updates.
Much like the floating panel in nuke, certain windows can be un docked for convenience.
To dock/un-dock simply double click on the window titlebar, drag the window or use the apposite buttons.
Nuke version: 11,12, 13.
Because Nuke 11 uses an early version of PySide2, future compatibility is not a guarantee.
While it should work the same on all platforms, it has been currently only tested on:


Fantasy Sports API is an easy, free-to-use API that allows developers and fantasy sports players to query up-to-date player and game data. The stats are returned in a JSON format for future processing and analysis, which can be easily built upon. A variety of queries are available to query NBA, NHL, and MLB stats.
Fantasy Sports API is currently the only free-to-use API available on the web. Whether you're a developer wanting to build applications on top of sports data easily and free of cost, or an active fantasy sports player looking to take the next step to ensure victory, Fantasy Sports API is for you.
1) Obtain user token.
Click on the above button to generate token to be able to access the queries. These tokens can be used forever once generated.
2) Submit custom SQL query, or use our built-in predefined queries via GET methods, with the definitions shown below.
In order to call our functions, Http Get/Post requests are needed to send/receive the data.
This tutorial will provide sample usage of our API in Java using the Jersey http client plugin to formulate the web requests.
Download Jersey from https://jersey.java.net/
The API is hosted at the following url http://<IP_ADDRESS>:8080/FantasySports/
{host}/query/getPlayerCurrentOverallStats/{playerName}/{league}/{token}
This query gets the player's overall stats for the entire season up until today's date. playerName is a player's full name, and league is an enum of {NBA, MLB, NHL}.
{host}/query/getPlayerDailyStats/{playerName}/{league}/{date}/{token}
This query gets the player's stats for a single date provided. playerName is a player's full name, league is an enum of {NBA, MLB, NHL}, and date is in a YYYY-MM-DD format.
The following is an example of how to write a query where we want to get Stephen Curry's stats for 2015-10-27.
private static void getPlayerDailyStats() throws Exception{
String baseURL = "http://<IP_ADDRESS>:8080/FantasySports/query/getPlayerDailyStats/";
String playerName = java.net.URLEncoder.encode("Stephen Curry", "UTF-8").replace("+", "%20");
String league = "NBA";
String date = "2015-10-27";
String token = "3a2993df-e8a2-11e5-9f31-0228a770e05b";
URL url = new URL(baseURL + playerName + "/" + league + "/" + date + "/" + token);
Client client = Client.create();
WebResource webResource = client
.resource(url.toString());
String response = webResource.accept("application/json")
.get(String.class);
JSONArray ja = new JSONArray(response);
String csv = CDL.toString(ja);
System.out.println(csv);
}
{host}/query/getPlayerPeriodicStats/{playerName}/{league}/{startDate}/{endDate}/{token}
This query gets the player's stats for the period provided, inclusive. playerName is a player's full name, league is an enum of {NBA, MLB, NHL}, startDate and endDate are in a YYYY-MM-DD format.
{host}/query/getTeamCurrentOverallStats/{teamName}/{league}/{token}
This query gets the team's overall stats for the entire season up until today's date. teamName is a team's full name, and league is an enum of {NBA, MLB, NHL}.
{host}/query/getTeamDailyStats/{teamName}/{league}/{date}/{token}
This query gets the team's stats for a single date provided. teamName is a team's full name, league is an enum of {NBA, MLB, NHL}, and date is in a YYYY-MM-DD format.
{host}/query/getTeamPeriodicStats/{teamName}/{league}/{startDate}/{endDate}/{token}
This query gets the team's stats for the period provided, inclusive. teamName is a player's full name, league is an enum of {NBA, MLB, NHL}, startDate and endDate are in a YYYY-MM-DD format.
{host}/query/getNBAAdvancedStats
This query allows the user to send a POST command with a JSON string as the argument, allowing more flexibility to the NBA results.
The following is an example of how to write a query where we want a list of games where Stephen Curry has at least 30 points and 5 assists.
private static void getNBAAdvancedStats() throws Exception {
Client client = Client.create();
WebResource webResource = client
.resource("http://<IP_ADDRESS>:8080/FantasySports/query/getNBAAdvancedStats");
String input = "{\"playerName\":\"Stephen Curry\", \"PTS\":\"30\", \"AST\":\"5\",\"token\":\"3a2993df-e8a2-11e5-9f31-0228a770e05b\"}";
String response = webResource.type("application/json")
.post(String.class, input);
JSONArray ja = new JSONArray(response);
String csv = CDL.toString(ja);
System.out.println(csv);
}
{host}/query/getNHLAdvancedStats
This query allows the user to send a POST command with a JSON string as the argument, allowing more flexibility to the NHL results. This POST request takes a json string as argument. The json string contains the stats desired for the query. The list of stats is available from the database schema provided.
The following is an example of how to write a query where we want a list of games where Sidney Crosby scores at least 2 goals.
private static void getNHLAdvancedStats() throws Exception {
Client client = Client.create();
WebResource webResource = client
.resource("http://<IP_ADDRESS>:8080/FantasySports/query/getNHLAdvancedStats");
String input = "{\"playerName\":\"Sidney Crosby\", \"G\":\"2\",\"token\":\"3a2993df-e8a2-11e5-9f31-0228a770e05b\"}";
String response = webResource.type("application/json")
.post(String.class, input);
JSONArray ja = new JSONArray(response);
String csv = CDL.toString(ja);
System.out.println(csv);
}
{host}/query/getCustomQuery
This query allows the user to send a POST command with a custom SQL string, allowing advanced user for utmost flexibility in what they want to retrieve. The database schema is provided below for reference. The SQL language used is MySQL. In order to submit a SQL string for the API to process, it must be in the following form
{query: SQL query, token: token}
This is the json format necessary to submit the SQL query for process.
The following is an example of how to write a custom query where we want a list of games where Stephen Curry hits at least ten 3 pointers in a game.
private static void query2() throws Exception{
Client client = Client.create();
WebResource webResource = client
.resource("http://<IP_ADDRESS>:8080/FantasySports/query/getCustomQuery");
String input = "{\"query\":\"Select * from NBAPlayerStats as a, NBAPlayer as b where playerName = 'Stephen Curry' and `3P` >= 10 and a.playerID = b.playerID\",\"token\":\"3a2993df-e8a2-11e5-9f31-0228a770e05b\"}";
String response = webResource.type("application/json")
.post(String.class, input);
JSONArray ja = new JSONArray(response);
String csv = CDL.toString(ja);
System.out.println(csv);
}


/* This file is part of Ext JS 4 Copyright (c) 2011 Sencha Inc Contact: http://www.sencha.com/contact Commercial Usage Licensees holding valid commercial licenses may use this file in accordance with the Commercial Software License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and Sencha. If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact. */ /** * @class Ext.ComponentLoader * @extends Ext.ElementLoader * * This class is used to load content via Ajax into a {@link Ext.Component}. In general * this class will not be instanced directly, rather a loader configuration will be passed to the * constructor of the {@link Ext.Component}. * * ## HTML Renderer * By default, the content loaded will be processed as raw html. The response text * from the request is taken and added to the component. This can be used in * conjunction with the {@link #scripts} option to execute any inline scripts in * the resulting content. Using this renderer has the same effect as passing the * {@link Ext.Component#html} configuration option. * * ## Data Renderer * This renderer allows content to be added by using JSON data and a {@link Ext.XTemplate}. * The content received from the response is passed to the {@link Ext.Component#update} method. * This content is run through the attached {@link Ext.Component#tpl} and the data is added to * the Component. Using this renderer has the same effect as using the {@link Ext.Component#data} * configuration in conjunction with a {@link Ext.Component#tpl}. * * ## Component Renderer * This renderer can only be used with a {@link Ext.container.Container} and subclasses. It allows for * Components to be loaded remotely into a Container. The response is expected to be a single/series of * {@link Ext.Component} configuration objects. When the response is received, the data is decoded * and then passed to {@link Ext.container.Container#add}. Using this renderer has the same effect as specifying * the {@link Ext.container.Container#items} configuration on a Container. * * ## Custom Renderer * A custom function can be passed to handle any other special case, see the {@link #renderer} option. * * ## Example Usage * new Ext.Component({ * tpl: '{firstName} - {lastName}', * loader: { * url: 'myPage.php', * renderer: 'data', * params: { * userId: 1 * } * } * }); */ Ext.define('Ext.ComponentLoader', { /* Begin Definitions */ extend: 'Ext.ElementLoader', statics: { Renderer: { Data: function(loader, response, active){ var success = true; try { loader.getTarget().update(Ext.decode(response.responseText)); } catch (e) { success = false; } return success; }, Component: function(loader, response, active){ var success = true, target = loader.getTarget(), items = []; //<debug> if (!target.isContainer) { Ext.Error.raise({ target: target, msg: 'Components can only be loaded into a container' }); } //</debug> try { items = Ext.decode(response.responseText); } catch (e) { success = false; } if (success) { if (active.removeAll) { target.removeAll(); } target.add(items); } return success; } } }, /* End Definitions */ /** * @cfg {Ext.Component/String} target The target {@link Ext.Component} for the loader. * If a string is passed it will be looked up via the id. */ target: null, /** * @cfg {Boolean/Object} loadMask True or a {@link Ext.LoadMask} configuration to enable masking during loading. */ loadMask: false, /** * @cfg {Boolean} scripts True to parse any inline script tags in the response. This only used when using the html * {@link #renderer}. */ /** * @cfg {String/Function} renderer The type of content that is to be loaded into, which can be one of 3 types: + **html** : Loads raw html content, see {@link Ext.Component#html} + **data** : Loads raw html content, see {@link Ext.Component#data} + **component** : Loads child {Ext.Component} instances. This option is only valid when used with a Container. Alternatively, you can pass a function which is called with the following parameters. + loader - Loader instance + response - The server response + active - The active request The function must return false is loading is not successful. Below is a sample of using a custom renderer: new Ext.Component({ loader: { url: 'myPage.php', renderer: function(loader, response, active) { var text = response.responseText; loader.getTarget().update('The response is ' + text); return true; } } }); */ renderer: 'html', /** * Set a {Ext.Component} as the target of this loader. Note that if the target is changed, * any active requests will be aborted. * @param {String/Ext.Component} target The component to be the target of this loader. If a string is passed * it will be looked up via its id. */ setTarget: function(target){ var me = this; if (Ext.isString(target)) { target = Ext.getCmp(target); } if (me.target && me.target != target) { me.abort(); } me.target = target; }, // inherit docs removeMask: function(){ this.target.setLoading(false); }, /** * Add the mask on the target * @private * @param {Boolean/Object} mask The mask configuration */ addMask: function(mask){ this.target.setLoading(mask); }, /** * Get the target of this loader. * @return {Ext.Component} target The target, null if none exists. */ setOptions: function(active, options){ active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll; }, /** * Gets the renderer to use * @private * @param {String/Function} renderer The renderer to use * @return {Function} A rendering function to use. */ getRenderer: function(renderer){ if (Ext.isFunction(renderer)) { return renderer; } var renderers = this.statics().Renderer; switch (renderer) { case 'component': return renderers.Component; case 'data': return renderers.Data; default: return Ext.ElementLoader.Renderer.Html; } } });


Table of Contents
The Common Object Services (COS) Name Server is the name server for storing Common Object Request Broker Architecture (CORBA) object references. It can be accessed from CORBA applications by using the COS Naming package (org.omg.CORBA.CosNaming).
The JNDI/COS naming service provider implements the javax.naming.Context interface on top of the COS Naming package in order to allow applications to use JNDI to access the COS Name Server. JNDI can also be used to access other naming and directory services, in addition to the COS Name Server, thereby offering the CORBA application one interface for accessing different naming and directory services.
This document describes the features of the COS naming service provider and contains details of how JNDI is mapped to the COS naming package.
The COS naming service provider for JNDI uses Java IDL, the Java programming language mapping to the industry standard Object Management Group Interface Definition Language (OMG IDL). In particular, it uses the COS Naming Service.
The complete specification for COS Naming can be obtained from OMG.
The syntax of names conforms to the Interoperable Naming Service (INS) specification (99-12-03), with backward compatibility support for the previous version of INS, OMG TC Document orbos/98-10-11. This is described in Names and URLs.
The following JNDI environment properties are relevant for the COS naming service provider. See the JNDI documentation for a description of how properties are initialized using the environment properties, system properties, applet parameters, and resource files.
java.naming.factory.initial
This property is used to select the COS naming service provider; it's not actually used by the provider itself. It specifies the class name of the initial context factory for the provider.
For example:
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.cosnaming.CNCtxFactory");
This property must be set if you are using the COS naming service as the initial context. The only exception is if you supply only URLs to the initial context, in which case, you don't need to specify this property. See Names and URLs for details.
java.naming.provider.url
This property is used to configure the root naming context and/or the Object Request Broker (ORB). Its value is the string representation of a URL.
If this property is not specified, then the ORB is initialized using the java.naming.corba.orb property, the java.naming.applet property, or other ORB initialization properties. The root naming context is obtained by invoking
orb.resolve_initial_references("NameService");
If the URL scheme is one of "IOR", "corbaname", or "corbaloc", as specified in the INS specification (99-12-03), then the root naming context is that named by the URL. The ORB is initialized using the java.naming.corba.orb property, the java.naming.applet property, or other ORB initialization properties.
If the URL scheme is either "iiop" or "iiopname", then the host and port fields of the URL are used to initialize the ORB. An "iiopname" URL must conform to the now obsolete INS specification (98-10-11). It has the form:
iiopname://[<addr_list>][/<cosnaming_name>]
The "iiop" URL scheme is supported for backward compatibility with an older version of the INS specification. It has the form:
iiop://[<host>[:<port>]][/<cosnaming_name>]
For both "iiop" and "iiopname" URLs, if <host> is not specified, then it defaults to "localhost" for an application and the applet's host for an applet. If <port> is not specified, then it defaults to 9999 for "iiopname", and 900 for "iiop". The root naming context is obtained by invoking the following method on the ORB:
orb.resolve_initial_references("NameService");
If <cosnaming_name> is nonempty, then the root naming context is the naming context named by cosnaming_name.
If the URL scheme is not one of "iiop", "iiopname", "IOR", "corbaname", or "corbaloc", then the URL must name a location that contains the stringified IOR of the root naming context. For example, if the property contains "file:/nsdir/ior", then the file /nsdir/ior must contain a stringified IOR. The URL scheme can be any for which there is a corresponding URL protocol handler ( java.net.URLStreamHandler). See the java.net.URL class for details. The stringified IOR is read from the data stream corresponding to the URL by using a character encoding of ISO Latin-1. The stringified IOR is the first line in the stream that contains the prefix "IOR:". For example, if the URL scheme is "http", then the headers in the stream are skipped and the first line that contains the prefix "IOR:" is returned as the IOR.
When the property specifies a stringified IOR or the location of one, the root naming context is that named by the stringified IOR. The ORB is initialized using the java.naming.corba.orb property, the java.naming.applet property, or other ORB initialization properties.
java.naming.corba.orb
This property specifies the ORB that the program is using. When the JNDI COS naming service provider needs to use an ORB, for example, to look up the "NameService" initial reference or to turn a stringified IOR into an object reference, it will use this ORB.
In an application you can set this property as follows:
ORB orb = ORB.init(args, null); Hashtable env = new Hashtable(5, 0.75f); env.put("java.naming.corba.orb", orb); ...In an applet, you can set it as follows:
public class MyApplet extends Applet { public someInitMethod() { ORB orb = ORB.init(this, null); Hashtable env = new Hashtable(5, 0.75f); env.put("java.naming.corba.orb", orb); ... } ... }
If this property is not set, then the java.naming.provider.url property, the java.naming.applet property, or the ORB initialization properties are used to initialize the ORB.
java.naming.applet
This property specifies the applet that the program is using. It is used to initialize the ORB to be used by the COS naming service provider. Its parameters are used for setting JNDI-related properties; see the JNDI documentation for details.
public class MyApplet extends Applet { public someInitMethod() { Hashtable env = new Hashtable(5, 0.75f); env.put("java.naming.applet", this); ... } ... }
java.naming.factory.state
A colon-separated list of the fully qualified class names of state factory classes used to get an object's state for storing given the object itself. You can use this mechanism to transform an object into forms that can be stored into a COS name server. The COS name server supports storing CORBA objects.
A state factory that transforms a java.rmi.Remote into a CORBA object is supplied by default. This factory is useful for applications that use RMI-IIOP. You can supply other factories to affect the transformation of other objects into CORBA objects for storing. See javax.naming.spi.NamingManager.getStateToBind() for details.
java.naming.factory.object
A colon-separated list of the fully qualified class names of object factory classes for transforming a CORBA object. You can use this mechanism to transform an object into forms expected by the application. For example, a specialized object factory could do the appropriate narrowing to return an object of the expected type. See javax.naming.spi.NamingManager.getObjectInstance() for details.
java.naming.batchsize
Specifies the batch size to use in CosNaming::BindingIterator.next_n when getting the results of a list()/listBindings(). The default is "100." For example, the following sets the batch size to be 24.
env.put(Context.BATCHSIZE, "24");ORB initialization properties
You can specify CORBA related properties such as those with the "org.omg.CORBA." prefix as properties. Properties of type String are used to initialize the ORB.
The properties that affect which ORB is used and how the ORB is initialized are:
java.naming.corba.orb
java.naming.applet
java.naming.provider.url
If the properties employed in steps (a), (b) and (c) contain no relevant information for initializing the ORB, then the Java IDL implementation's defaults are used. Typically that means port 900 on the local host for an application, and port 900 on the applet host for an applet are used. Note that when the ORB is initialized using ORB.init(), its arguments are checked in the following order: (from org.omg.CORBA.ORB javadoc)
The root naming context is initialized either using the java.naming.provider.url property or by a resolve_initial_references() call on the ORB. If the java.naming.provider.url property is set but contains neither an "iiop" or "iiopname" URL, then it is assumed to contain a stringified IOR, a "corbaname" or "corbaloc" URL of an IOR, or a URL containing the location of a stringified IOR. The IOR is used to obtain the root naming context and must be that of a CORBA object of type CosNaming::NamingContext.
If the java.naming.provider.url has not been set, then the root naming context is obtained by invoking the following method on the ORB:
orb.resolve_initial_references("NameService");
String Names
String names accepted by the java.naming.Context methods are JNDI composite names in which each component is the stringified form of a CosNaming::NameComponent.
A CosNaming::Name contains a sequence of CosNaming::NameComponent. The stringified form of a component is the concatenation of the component's id, the kind separator character ('.'), and the component's kind. The occurrence of any meta characters ('.', '/', or '\') in either the id or kind is escaped using the escape character ('\'). The stringified form of a CosNaming::Name is defined in Section 3.5 of the INS specification (99-12-03).
The JNDI composite name syntax is very similar to, but not identical to, the INS syntax. There are minor differences with respect to the treatment of escape and quote characters. If you want to use names with the precise INS syntax, then you should use the overloads that accept a Name argument instead of a String argument. The Name argument should be a value returned by nameParser.parse(), where nameParser is a value obtained from the COS naming service provider. See the Name Parsing section.
URL String Names
The URL form of a CosNaming::Name is defined in the INS specification.
corbaname:<corbaloc_obj>["#" <cosnaming_name>]
where <corbaloc_obj> is<corbaloc_obj> = <obj_addr_list> ["/" <key_string>]
and <obj_addr_list> is a list of addresses as defined in a "corbaloc" URL and <key_string> is a key string as defined in a "corbaloc" URL. <cosnaming_name> is the stringified form of an INS name (see Name Parsing).For backward compatibility with older versions of the INS, the following URL schemes are also supported.
iiopname://[<addr_list>][/<cosnaming_name>]where <addr_list> specifies a list of host/port pairs. If <port> is not specified, then it defaults to 9999. <cosnaming_name> is the stringified form of an INS name.
iiop://<host>[:<port>][/<cosnaming_name>]
If <port> is not supplied, then it defaults to 900. <cosnaming_name> is the stringified form of an INS name.
When you supply an "iiop" or "iiopname" URL to the initial context in this way, the ORB supplied to the initial context is used if its string_to_object() method supports the 99-12-03 INS specification. Otherwise, the ORB is ignored and the server and port designations in the URL are used to create an ORB. The value of the java.naming.factory.initial property is ignored for the purposes of resolving the URL.
Note that this rule is not used when you supply a "corbaname" URL to the initial context. For a "corbaname" URL, the ORB supplied to the initial context is used because the ORB is needed to resolve the "corbaname" URL. Name Objects
The Name argument to a Context method is treated as a sequence of strings, each representing a stringified CosNaming::NameComponent.
The COS naming service provider supports names in the syntax specified in the INS specification. In short, the syntax is that components are left-to-right slash ('/') separated and case-sensitive. The id and kind of each component are separated by the period character ('.').
Here is a code fragment that uses the name parser from the COS naming service provider to eventually do a lookup using an INS name.
String insName = ...; InitialContext ctx = new InitialContext(env); // env contains init properties NameParser parser = ctx.getNameParser(""); // parser for INS names Name name = parser.parse(insName); // get parsed INS name Object obj = ctx.lookup(name); // do lookup
The COS name server supports only naming operations. The COS naming service provider maps the javax.naming.Context methods to use the appropriate COS Naming calls.
addToEnvironment()
Records change to environment property but does not reinitialize ORB.
bind()
Binds an object to the specified name.
If the object being bound is an org.omg.CosNaming.NamingContext, then CosNaming::NamingContext.bind_context is used. If it is an org.omg.CORBA.Object, then CosNaming::NamingContext.bind is used. The binding of any other type of object is not supported unless the object can be converted into an org.omg.CORBA.Object using the state factory mechanism described next.
Before the bind is performed on the naming server, the COS naming service provider uses javax.naming.spi.NamingManager.getStateToBind() to allow the object to be transformed into a org.omg.CORBA.Object. The getStateToBind() method uses the state factories available to the COS naming service provider. If the state factory accepts a java.rmi.Remote object, then it is responsible for obtaining the object's RMI-IIOP stub and connecting it to the ORB associated with the context. The connected stub is the object that will be bound in the naming server.
By default, the COS naming service provider supplies and uses a state factory that transforms an object implementing the java.rmi.Remote interface to an org.omg.CORBA.Object following the requirements described above. This factory uses the utilities in the javax.rmi.CORBA package. You can supply additional state factories to transform objects into CORBA objects.
close()
Releases any internal data structures used.
composeName()
Concatenates the supplied name to the prefix.
createSubcontext()
Uses CosNaming::NamingContext.bind_new_context to create and bind a new context.
destroySubcontext()
Uses CosNaming::NamingContext.destroy to destroy the named context. Then uses CosNaming::NamingContext.unbind to remove the binding.
getEnvironment()
Returns the environment of this context.
getNameInNamespace()
Returns the INS name of this context relative to the root of the Cos Naming namespace.
getNameParser()
Returns a name parser for parsing INS names.
lookup() lookupLink()
Uses CosNaming::NamingContext.resolve to lookup the name. It returns a CORBA object reference except when the reference is that of a CosNaming::NamingContext, in which case a Context object is returned instead. NamingManager.getObjectInstance() is called before the object is returned in case the application or user has supplied object factories.
list() listBindings()
Uses CosNaming::NamingContext.resolve to get the object reference for the context, and then uses CosNaming::BindingIterator and helper classes to iterate through the context. The objects bound to the names are obtained by calling CosNaming::NamingContext.resolve on them. NamingManager.getObjectInstance() is called before the object is returned in case the application or user has supplied object factories.
removeFromEnvironment()
Removes the specified property from the environment but does not otherwise update the context.
rebind()
If the object being bound is an org.omg.CosNaming.NamingContext, then CosNaming::NamingContext.rebind_context is used. If it is an org.omg.CORBA.Object, then CosNaming::NamingContext.rebind is used. See bind() for details on the use of state factories to transform the argument into an org.omg.CORBA.Object.
rename()
This method is implemented using bind() followed by unbind(). It is not atomic.
unbind()
Uses CosNaming::NamingContext.unbind to unbind the object.
This section explains how to modify your Java IDL program to use JNDI. The explanation uses the Java IDL sample programs helloClient.java and helloServer.java.
# idltojava -fclient -fserver hello.idl
This creates the client (helloClient.java) and server (helloServer.java) skeletons, and a directory containing common code (e.g. HelloApp/*.java).
Delete:
import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*;Add:
import javax.naming.*;
Delete:
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef);
Add:
Hashtable env = new Hashtable(5, 0.75f); env.put("java.naming.corba.orb", orb); Context ic = new InitialContext(env);
Delete:
// resolve the Object Reference in Naming NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; hello helloRef = helloHelper.narrow(ncRef.resolve(path));Add:
// resolve the Object Reference using JNDI hello helloRef = helloHelper.narrow((org.omg.CORBA.Object)ic.lookup("Hello"));
When a security manager has been installed, you must grant to the application using JNDI and the COS naming service provider the following permissions:
permission java.net.SocketPermission "host[:port]", "connect";
For each host/port identified in the java.naming.factory.initial property, in URL string names supplied to context methods, in ORB initialization parameters and properties, and in object references.


15 Tips and Tricks
This section will be populated with tips to help with a general comparative research project. Some will be quite specific solutions to problems that have popped up but don’t quite fit into one of the previous chapters. Others will be much more generic and can be applied in many different situations.
15.1 Literature searching with Connected Papers
Seraching through the literature can be a daunting task. The volume of information available can be overwhelming. A rcently developed tool could make this task a little easier. Connected Papers is an online tool that allows you to visualise how a paper fits into the wider body of the literature.
The tool is connected to Semantic Scholar, an online repository of scientific papers. To use the tool, simply enter the title of a paper (or URL/doi) into the search bar on the home page.
Once the search function has located the corrected paper, select Build Graph and the tool will build a network-style graph of papers that are similar to the one you have chosen.
Interpreting this graph is very useful. Papers are arranged by similarity meaning that the bibliographies of each paper are compared looking for overlapping bilbliographies. This means that this is not just a map of papers that cite each other (although many are likely to cite each other). It is a map of papers that write about similar things and therefore cite similar sources.
Clusters of papers are more similar. In the graph above you can see three clusters of papers. One is very tightly clustered indicating strong overlap in bibliography whereas the others are slightly more diffuse. You can also call up Prior works and Derivative works allowing you to investigate papers that cite and are cited by the papers in the graph.
This can be a really useful way to approach a literature search. Often it can be easy to find a paper that is relevant to your topic and not search too much further. This means you can miss the broader context of the paper and may mean you end up citing one paper without citing others that might be more up-to-date, contradictory or otherwise relevant.
15.2 Extracting data from a PDF using Excel
Microsoft Excel is either a really useful programme or a frustrating mess depending on who you ask and possibly how long it’s been since their last coffee. Whatever you think of the programme, it’s quite likely that you’ll be using it to edit/store your data.
Many authors make their data available as .csv files (comma separated values) which are easily readable by Excel (amongst others). However, sometimes this is not the case. Data are sometimes presented in neatly formatted tables in a PDF.
Quite recently, Microsoft have introduced a feature to Excel that some project students have found useful in the past. If you navigate to the Insert tab you will see the option to insert Data from picture.
This option allows you to upload a picture (such as a screenshot of a pdf or page from a book) into Excel. Once you’ve selected the picture, Excel will use its AI to process the image and convert it into a table. Once complete, Excel will present a draft of the table to insert for you to check manually. It is very important to check this for missing decimal points, misspellings and similar mistakes that the AI may have made.
If you can’t get hold of data any other way, this is a great timesaver that will prevent you typing it all out by hand!
15.3 DataEditR
Traditionally, if you find an error in your data there are a couple of ways to solve the problem. You could use the tidyverse suite of packages, within which there are many functions for manipulating data. Alternatively, you could go to Excel (or wherever your data is stored) and edit the source file before reloading it into R. Which method you choose is probably dependent on your experience and comfort with R.
A third option is to use the package DataEditR (Hammill 2020). This package opens up a dataset in an interactive viewer which the user can then edit manually as they would when using Excel. It’s a really useful add-on package to R and it has a truly excellent associated Github site here which takes you through the key features and how to use them.
Bibliography
Hammill, D. (2020) DataEditR: An Interactive Editor for Viewing, Entering and Editing Data [online] available from <https://CRAN.R-project.org/package=DataEditR>


The other day a friend of mine A, his roomate T, his roomate's girlfriend J, a friend of the girlfriend L, and I all went out driving to smoke. J was driving. I hadn't smoked in 5 years, and back then nothing really happened. So I decided to give it another try.
As we drove, When it was my turn to hit, I took huge drags off of the pipe and held my breath for as long as I could, with the hope that I'd feel something this time. After about 3 times around, each time taking as much as possible I started to feel it. This was after probably about 15-20 minutes. I noticed that everything seemed to become extremely slow. Like time had slowed down, but not really. When I moved my head, my hair would move and it would move with normal speed, but when looking at things not directly in my face, things seemed ultra slow.
I asked my friend A if he was feeling anything, since it was his first time too. He said not really. I noticed when I talked to him that my voice seemed an octive lower than usual. My mouth tasted/felt extremely sticky and dry; I needed a drink. A wanted to stop by his brother's anyway so when we got there I got out with him so I could get some water. On the way into his brother's I found I could barely walk straight. Things looked very strange.  It looked kind of like a pop-up book, with each object being a card on a surface, not 3 dimensional like usual.
When we got inside, I grabbed a small glass of water and drank it. The water instantly cleared up my cottonmouth and I felt much better. I wasn't feeling paranoid and I didn't feel like laughing. I just felt like exploring the intensity of the experience. After stopping at his brother's, A and I went back to the car and J started to drive back to the dorm. We passed the pipe around more until our stash was gone.
When we got back (about 45 min in), we all got out and I wondered if I really was moving as slowly as I thought. I assumed no since no one said anything and started to walk towards the doors. Before we made it to the steps up to the building, some friends of ours who were smoking cigs on the smoking island called us over to talk for a few. Me and A went over there to talk to them. One of my friends was talking to me, telling me something, but I couldn't focus at all on what he said. I just replied with 'yeah' and 'cool.' As I was standing there, I notice that when I moved my head it seemed that I was turning the background of everything with me, as If I was looking at a wall, and when I turned, the wall was still flat in front of me. Eventually we got out of there and I noticed that A was acting completely normal. I don't think he was anywhere near where I was, I could barely put a thought together, much less sing songs and talk fast like him.
We went in and I wondered how bloodshot my eyes were and if people would notice. I wasn't worried, just curious. When we got up to the floor we were staying on, I stopped at the mirror and noticed that my eyes were very very red, but doubted people would notice. We grabbed a movie, 'Rounders' and put it in. I was sitting on the chair in front of the TV. As I was watching, I noticed that I could only see things at one depth in front of me, like if there was a pop can 4 feet away and a bottle 5 feet, I could only see one at a time. Once I found this out, I noticed something very strange, when I looked from one thing to another at different lengths away in a line going up I could like 'overload' my head.
I looked at the controller on the floor and from that to the desk, then to the TV, then the clock on the TV, then to the ceiling, and when I did that my head would 'overload' and I would trip out for a second and my head would go back to the beginning. I found that if I did that multiple times in a row quickly I could get my head majorly overloaded. It wasn't a bad thing, just weird. Kind of like I was dizzy, but not being at a disadvantage. I wondered if the people in the room noticed my head rolling all over the place, but no one said anything, so I assumed they didn't. Time seemed to be going by very very slow.
It started getting late, so I rode my bike back to my real dorm which was across campus. I had no problem operating it. The cold air bothered me. I got back to my place, did a little more 'overloading' and then tried to sleep. I was unable to though and ended up getting no sleep at all, I just couldn't fall asleep. The next day after I gave up on sleeping and took a shower and ate breakfast I still noticed that I was slightly light headed and had a bad headache (easily cured with liquid Advil tabs).
None of the other people who smoked had anything similar to the experience I had. I'm glad that I was able to experience this 'brain overload' but hope that someone else will eventually be able to understand what I am talking about.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Ireland Set To Face Slovakia Away In Euro 2020 Playoff
by Oisin McQueirnsIreland look set for an away trip to Slovakia in their first Euro 2020 playoff after Wales defeated Hungry to qualify automatically for the tournament.
UEFA may change Ireland into Path A from Path B if they wish to, however it is thought that they will keep the four teams in Path B as they currently are.
That means that Slovakia look like Ireland’s opponents in either Bratislava or Trnava on March 26th next year, with the winners facing whichever nation is victorious when Northern Ireland take on Bosnia what is set to be the other semi-final.
The game has a 50/50 chance of being in Dublin according to The Irish Times, with UEFA set to conduct a draw on Friday to determine the potential location for the final which will be played on March 31st.
Slovakia away will no doubt represent a tricky task for McCarthy’s side, with Ireland’s potential opponents finishing third in their group behind Wales and Croatia and winning their final game against Azerbaijan.
They won four group games, drawing one and losing three scoring 13 goals in the process while conceding 11.
Ireland were denied an automatic spot in Euro 2020 when they drew with Denmark at the Aviva Stadium on Monday night meaning it was the Danes along with Switzerland who qualified from the group.


The AFE driver provides the interface to configure and use the AFE peripheral.
More...
The AFE driver provides the interface to configure and use the AFE peripheral.
It converts the analog input to digital format. The converted result could be 12bit or 10bit. The AFE supports up to 16 analog lines.
To Enable a AFE conversion,the user has to follow these few steps:
-
Select an appropriate reference voltage on ADVREF
-
Configure the AFE according to its requirements and special needs,which could be broken down into several parts:
- Select the resolution by setting or clearing AFEC_MR_LOWRES bit in AFEC_MR (Mode Register)
- Set AFE clock by setting AFEC_MR_PRESCAL bits in AFEC_MR, the clock is calculated with AFEClock = MCK / ((PRESCAL+1) * 2)
- Set Startup Time,Tracking Clock cycles and Transfer Clock respectively in AFEC_MR.
-
Start conversion by setting AFEC_CR_START in AFEC_CR.
For more accurate information, please look at the AFE section of the Datasheet.
Related files :
afec.c
afec.h
afe_dma.c
afe_dma.h


Migrating from Extjs to React gradually
Migrating from Extjs to React gradually
26 January 2016 | 27 April 2018
javascript extjs reactWe were looking for a few alternatives to our big ExtJS 4 application. Since it’s not that easy to completely migrate from one front-end framework to the next, a possible solution would be to start developing new parts in another framework. There’s a lot of domain logic spread in Ext views and controllers - which shouldn’t be there, we are well aware of that. Let’s call it “legacy” :-)
The application right now uses Extjs as UI and C# as backend, and lets ext do the loading of the views/controllers (living in app.js like most ext applications). There’s no ecosystem set up like modern javascript applications - build systems like Grunt, Gulp, node package managers, Browserify, … are all not used. We do use sencha command to minify stuff. To be able to develop new modules without having to worry about extjs, one of the possibilities would be to use iframes. That enables us to (scenario) test the module using it’s own routing. It’s wrapped inside an Extjs view with an iframe:
Ext.define('App.view.utilities.desktop.ReactWindow', {
extend: 'Ext.form.Panel',
alias: 'widget.App_view_utilities_desktop_ReactWindow',
bodyPadding: 5,
width: 600,
layout: {
type: 'vbox',
align: 'stretch'
},
initComponent: function() {
var me = this;
var dynamicPanel = new Ext.Component({
autoEl: {
tag: 'iframe',
style: 'border: none',
src: me.url
},
flex: 1
});
Ext.apply(me, {
title: 'React',
defaults: {
labelWidth: 120
},
items: [dynamicPanel]
});
me.callParent();
}
});
When the module is triggered in the main app, we simply add the panel to the desktop:
this.addPanel(Ext.create('App.view.utilities.desktop.ReactWindow', {
url: 'react/mod/someurl/'
}));
Our app structure in the GUI folder would be something like this:
[GUI]
* global.asax
* default.aspx
**** [app] -> extjs
**** [react] -> reactjs
That’s simple enough. But how would one be able to open new Ext panels from within the React sub-application? That would be done via custom events thrown to the parent window. Catching these is just a matter of adding this to some controller in Extjs:
window.addEventListener('react', function(e) {
me.onReactEvent(e.detail, e);
});
The detail
property is part of a custom event, thrown in a react component. This below might be some cell component, taken from the fixed-data-table example:
class MyLinkCell extends React.Component {
clicked(e) {
const el = e.target;
const eventObj = {
'detail': {
'type': 'downloadlink',
'url': 'react/some/detail/url'
}
};
console.log('clicked - "react" event thrown:');
console.dir(eventObj);
if(window.parent) {
window.parent.dispatchEvent(new CustomEvent('react', eventObj));
}
}
render() {
const {rowIndex, field, data} = this.props;
const link = data[rowIndex][field];
return (
<Cell>
{link}
</Cell>
);
}
}
Of course this is more or less the same when for instance using Angular2 instead of React, the custom event is part of the JS standard, see Creating and triggering events from MDN.
To be able to use source maps in conjunction with Browserify/Watchify, I had to tweak some parameters in package.json:
`watchify index.js --verbose -d -t babelify --sourceMapRelative . --outfile=bundle.js`
Things we still need to research:
- How well does React compare to Angular2 in terms of components? For instance react doesn’t include routing by default. We’ll need to rewrite some already-extjs-custom components in the target framework.
- How should we include the build ecosystem (npm, gulp/grunt/browserify, …) into our C# build solution and Teamcity build? Will http://reactjs.net/ help for instance?
- Can we use http://reactjs.net/ to render serverside components?
- Which build tool should we use? We’re being overwhelmed by choice: bower/npm as package manager, I’ve seen stuff like Webpack in conjunction with React, … The list is huge if you’ve not kept up with the JS technology news.
One of the things we liked a lot was typescript or ES6 and the ability to use => ()
and promises. Enabling this requires a transpiler or a polyfill like Babel JS, but maybe this as a build step in sencha command will also ease some pain we’re having with the current Ext code.


111_mictw.py
class Solution:
def maxProfit(self, inventory: List[int], orders: int) -> int:
MOD = 1_000_000_007
# sell each colored balls until each has #keep balls left
def sell(keep: int) -> int:
values, count = 0, 0
for c in inventory:
num = max(0, c - keep)
if num:
count += num
values += ((c + keep+1) * num) // 2
return count, values
low, hi = 0, max(inventory)
while low < hi:
mid = (low+hi)//2
count, money = sell(mid)
if count <= orders:
hi = mid
else:
low = mid+1
sell_out, money = sell(hi)
return (money + (orders - sell_out)*hi) % MOD


Pricing Table Mega 3
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged
Pay Monthly
-
Credit Card Requirement
-
Diskspace
-
Subdomains
General
-
Email Addresses
-
Online Payment
-
Online Security
-
MySQL Databases
-
Multiple Device Control
-
Google AdWords Credits
-
Remote Desktop Widge
Support
-
24 Hours Online Chat Support
-
Scheduled Lock Screen
-
Customisable Toolbar
-
Ports Controls
-
Premium DNS
-
SSL Certificate
-
Worldwide Phone Support
Begginer Nam libero tempore
$9.49
Per Month
-
Credit Card Requirement
-
5 GBDiskspace
-
10Subdomains
Free 14 Day Trial
General
-
10Email Addresses
-
Email Addresses
-
10Subdomains
-
Email Addresses
-
MySQL Databases
-
$50Google AdWords Credits
-
Remote Desktop Widge
Support
-
Customisable Toolbar
-
Scheduled Lock Screen
-
Customisable Toolbar
-
Ports Controls
-
Premium DNS
-
SSL Certificate
-
Worldwide Phone Support
Unify Pro Nam libero tempore
$29.95
Per Month
-
Credit Card Requirement
-
15 GBDiskspace
-
50Subdomains
Free 14 Day Trial
General
-
10Email Addresses
-
Email Addresses
-
10Subdomains
-
Email Addresses
-
MySQL Databases
-
$50Google AdWords Credits
-
Remote Desktop Widge
Support
-
Customisable Toolbar
-
Scheduled Lock Screen
-
Customisable Toolbar
-
Ports Controls
-
Premium DNS
-
SSL Certificate
-
Worldwide Phone Support
Premium
Nam libero tempore
$69.99
Per Month
-
Credit Card Requirement
-
50 GBDiskspace
-
150Subdomains
Free 14 Day Trial
General
-
10Email Addresses
-
Email Addresses
-
10Subdomains
-
Email Addresses
-
MySQL Databases
-
$50Google AdWords Credits
-
Remote Desktop Widge
Support
-
Customisable Toolbar
-
Scheduled Lock Screen
-
Customisable Toolbar
-
Ports Controls
-
Premium DNS
-
SSL Certificate
-
Worldwide Phone Support
Elite Nam libero tempore
$99.00
Per Month
-
Credit Card Requirement
-
UnlimitedDiskspace
-
2000Subdomains
Free 14 Day Trial
General
-
10Email Addresses
-
Email Addresses
-
10Subdomains
-
Email Addresses
-
MySQL Databases
-
$50Google AdWords Credits
-
Remote Desktop Widge
Support
-
Customisable Toolbar
-
Scheduled Lock Screen
-
Customisable Toolbar
-
Ports Controls
-
Premium DNS
-
SSL Certificate
-
Worldwide Phone Support


---
layout: default
---
{{page.title}}
{{page.intro_paragraph}}
{% include team-section.html team=site.team %}
{% include full-width-with-button.html text="Love what you see? maybe you could join us." image="our-building.jpg" button-text="Work for FireBrand" button-link="/recruit" button-icon="ti-mouse-alt" %}


{{ message }}
{% endfor %}
{% endif %}
{% endwith %}
{# All other page content starts here #}
{% block content %}{% endblock %}
{# All other page content ends here #}
{# Required meta tags #} {# Bootstrap CSS #} {# Our CSS #} {# Quicksand Font #} {# Chart.js script #} {# Favicon #} {# If a title has been provided by the render_template function, it is appended to Overseed. Otherwise, we just use Overseed on its own. #} {% if title %}


--- title: Low Level Parent Phase Reconstruction sidebar: documentation_sidebar permalink: LowLevelParentGrainReconstruction.html folder: documentation toc: false ---
In this section we discuss parent grain reconstruction at the example of a titanium alloy. Lets start by importing a sample data set
{% highlight matlab %} mtexdata alphaBetaTitanium % the phase names for the alpha and beta phases alphaName = 'Ti (alpha)'; betaName = 'Ti (Beta)'; % and plot the alpha phase as an inverse pole figure map plot(ebsd(alphaName),ebsd(alphaName).orientations,'figSize','large') {% endhighlight %} {% highlight plaintext %} saving data to /home/hielscher/mtex/master/data/alphabetatitanium.mat ebsd = EBSD Phase Orientations Mineral Color Symmetry Crystal reference frame 0 10449 (5.3%) notIndexed 1 437 (0.22%) Ti (BETA) LightSkyBlue 432 2 185722 (94%) Ti (alpha) DarkSeaGreen 622 X||a*, Y||b, Z||c* Properties: bands, bc, bs, error, mad, reliabilityindex, x, y Scan unit : um {% endhighlight %}The data set contains 99.8 percent alpha titanium and 0.2 percent beta titanium. Our goal is to reconstuct the original beta phase. The original grain structure appears almost visible for human eyes. Our computations will be based on the Burgers orientation relationship
{% highlight matlab %} beta2alpha = orientation.Burgers(ebsd(betaName).CS,ebsd(alphaName).CS) {% endhighlight %} {% highlight plaintext %} beta2alpha = misorientation (Ti (BETA) → Ti (alpha)) (110) || (0001) [1-11] || [-2110] {% endhighlight %}that alligns (110) plane of the beta phase with the (0001) plane of the alpha phase and the [1-11] direction of the beta phase with the [2110] direction of the alpha phase.
Note that all MTEX functions for parent grain reconstruction expect the orientation relationship as parent to child and not as child to parent.
In a first step we want to identify triple junctions that have misorientations that are compatible with a common parent orientations. To this end we first compute alpha grains using the option removeQuadruplePoints
which turn all quadruple junctions into 2 triple junctions. Furthermore, we choose a very small threshold of 1.5 degree for the identification of grain boundaries to avoid alpha orientations that belong to different beta grains get merged into the same alpha grain.
Above we have plotted only a very small subregion of the original data set to make the seperation of the qudruple junctions better visible.
Next we extract all alpha - alpha - alpha triple junctions and use the command calcParent
to find for each of these triple junctions the best fitting parent orientations.
The command calcParent
returns for each child orientation a parentId
which allows us later to compute the parent orientation from the child orientation. Furthermore, the command return for each triple junction the misfit between the adjecent parent orientations in radiant. Finally, the option 'numFit',2
causes calcParent
to return not only the best fit but also the second best fit. This will be used later. First we simple colorize the triple junctions according to the best fit.
Next we select those triple junctions as reliable that have a fit less than 2.5 degree and second best fit that is larger than 2.5 degree
{% highlight matlab %} consistenTP = fit(:,1) < 2.5*degree & fit(:,2) > 2.5*degree; % marke these triple points by a red cicle hold on plot(tP(consistenTP),'MarkerEdgecolor','r','MarkerSize',10,... 'MarkerFaceColor','none','linewidth',2,'region',region) hold off {% endhighlight %}We observe that despite the quite sharp threshold we have many consistent triple points. In the next step we check wether all consistent triple junctions of a grain vote for the same parent orientation. Such a check for consistent votes can be computed by the command majorityVote
using the option strict
.
The command majorityVote
returns for each grain with consistent parentId votes this unique parentId and for all other grains NaN
. The second output argument gives the number of these votes
For all grains with at least 3 unique vote we now use the command variants
to compute the parent orientation corresponding to the parentId
. This parent orientations we assign as new meanOrientation
to our grains.
Lets plot map of these reconstructed beta grains
{% highlight matlab %} % define a color key ipfKey = ipfColorKey(ebsd(betaName)); ipfKey.inversePoleFigureDirection = vector3d.Y; % and plot plot(parentGrains(betaName), ... ipfKey.orientation2color(parentGrains(betaName).meanOrientation),'figSize','large') {% endhighlight %}We observe that this first step already results in very many Beta grains. However, the grain boundaries are still the boundaries of the original alpha grains. To overcome this, we merge all Beta grains that have a misorientation angle smaller then 2.5 degree.
As an additional consistency check we verify that each parent grain has been reconstructed from at least 2 child grains. To this end we first make a testrun the merge operation and then revert all parent grains that that have less then two childs. This step may not nessesary in many case.
{% highlight matlab %} % test run of the merge operation [~,parentId] = merge(parentGrains,'threshold',2.5*degree,'testRun'); % count the number of neighbouring child that would get merged with each child counts = accumarray(parentId,1); % revert all beta grains back to alpha grains if they would get merged with % less then 1 other child grains setBack = counts(parentId) < 2 & grains.phaseId == grains.name2id(alphaName); parentGrains(setBack).meanOrientation = grains(setBack).meanOrientation; parentGrains = parentGrains.update; {% endhighlight %}Now we perform the actual merge and the reconstruction of the parent grain boundaries.
{% highlight matlab %} % merge beta grains [parentGrains,parentId] = merge(parentGrains,'threshold',2.5*degree); % set up a EBSD map for the parent phase parentEBSD = ebsd; % and store there the grainIds of the parent grains parentEBSD('indexed').grainId = parentId(ebsd('indexed').grainId); plot(parentGrains(betaName), ... ipfKey.orientation2color(parentGrains(betaName).meanOrientation),'figSize','large') {% endhighlight %}After the first two steps we have quite some alpha grains have not yet transformed into beta grains. In order to merge those left over alpha grains we check whether their misorientation with one of the neighbouring beta grains coincides with the parent to grain orientation relationship and if yes merge them evantually with the already reconstructed beta grains.
First extract a list of all neighbouring alpha - beta grains
{% highlight matlab %} % all neighbouring alpha - beta grains grainPairs = neighbors(parentGrains(alphaName), parentGrains(betaName)); {% endhighlight %}and check how well they fit to a common parent orientation
{% highlight matlab %} % extract the corresponding meanorientations oriAlpha = parentGrains( grainPairs(:,1) ).meanOrientation; oriBeta = parentGrains( grainPairs(:,2) ).meanOrientation; % compute for each alpha / beta pair of grains the best fitting parentId [parentId, fit] = calcParent(oriAlpha,oriBeta,beta2alpha,'numFit',2,'id'); {% endhighlight %}Similarly, as in the first step the command calcParent
returns a list of parentId
that allows the convert the child orientations into parent orientations using the command variants
and the fitting to the given parent orientation. Similarly, as for the triple point we select only those alpha beta pairs such that the fit is below the threshold of 2.5 degree and at the same time the second best fit is above 2.5 degree.
Next we compute for all alpha grains the majority vote of the surounding beta grains and change their orientation from alpha to beta
{% highlight matlab %} parentId = majorityVote( grainPairs(consistenPairs,1), ... parentId(consistenPairs,1), max(parentGrains.id)); % change grains from child to parent hasVote = ~isnan(parentId); parentGrains(hasVote).meanOrientation = ... variants(beta2alpha, parentGrains(hasVote).meanOrientation, parentId(hasVote)); % update grain boundaries parentGrains = parentGrains.update; % merge new beta grains into the old beta grains [parentGrains,parentId] = merge(parentGrains,'threshold',5*degree); % update grainId in the ebsd map parentEBSD('indexed').grainId = parentId(parentEBSD('indexed').grainId); % plot the result color = ipfKey.orientation2color(parentGrains(betaName).meanOrientation); plot(parentGrains(betaName),color,'linewidth',2) {% endhighlight %}The above step has merged
{% highlight matlab %} sum(hasVote) {% endhighlight %} {% highlight plaintext %} ans = 15631 {% endhighlight %}alpha grains into the already reconstructed beta grain. This reduces the amount of grains not yet reconstructed to
{% highlight matlab %} sum(parentGrains('Ti (alpha').grainSize) ./ sum(parentGrains.grainSize)*100 {% endhighlight %} {% highlight plaintext %} ans = 1.1453 {% endhighlight %}percent. One way to proceed would be to repeat the steps of this section multiple time, maybe with increasing threshold, until the percentage of reconstructed beta grains is sufficiently high. Another approach in to consider the left over alpha grains as noise and use denoising techniques to replace them with beta orientations. This will be done in the last section.
Until now we have only recovered the beta orientations as the mean orientations of the beta grains. In this section we want to set up the EBSD variable parentEBSD
to contain for each pixel a reconstruction of the parent phase orientation.
Therefore, we first identify all pixels that previously have been alpha titanium but now belong to a beta grain.
{% highlight matlab %} % consider only original alpha pixels that now belong to beta grains isNowBeta = parentGrains.phaseId(max(1,parentEBSD.grainId)) == ebsd.name2id(betaName) &... parentEBSD.phaseId == ebsd.name2id(alphaName); {% endhighlight %}Next we can use once again the function calcParent
to recover the original beta orientation from the measured alpha orientation giving the mean beta orientation of the grain.
We obtain even a measure fit
for the corespondence between the beta orientation reconstructed for a single pixel and the beta orientation of the grain. Lets visualize this measure of fit
Lets finaly plot the reconstructed beta phase
{% highlight matlab %} plot(parentEBSD(betaName),ipfKey.orientation2color(parentEBSD(betaName).orientations),'figSize','large') {% endhighlight %}As promised we end our discussion by applying denoising techniques to fill the remaining holes of alpha grains. To this end we first reconstruct grains from the parent orientations and throw away all small grains
{% highlight matlab %} [parentGrains,parentEBSD.grainId] = calcGrains(parentEBSD('indexed'),'angle',5*degree); % remove all the small grains parentEBSD = parentEBSD(parentGrains(parentGrains.grainSize > 15)); % redo grain reconstruction [parentGrains,parentEBSD.grainId] = calcGrains(parentEBSD('indexed'),'angle',5*degree); % smooth the grains a bit parentGrains = smooth(parentGrains,5); {% endhighlight %}Finally, we denoise the remaining beta orientations and at the same time fill the empty holes. We choose a very small smoothing parameter alpha
to keep as many details as possible.
For comparison the map with original alpha phase and on top the recovered beta grain boundaries
{% highlight matlab %} plot(ebsd(alphaName),ebsd(alphaName).orientations,'figSize','large') hold on plot(parentGrains.boundary,'lineWidth',3) hold off {% endhighlight %}In parent grain reconstruction several parameters are involve are decicive for the success of the reconstruction
Visualize the misorientation to the mean reveals quite some fine structure in the reconstructed parent orientations.
{% highlight matlab %} cKey = axisAngleColorKey; color = cKey.orientation2color(parentEBSD(betaName).orientations, parentGrains(parentEBSD(betaName).grainId).meanOrientation); plot(parentEBSD(betaName),color) hold on plot(parentGrains.boundary,'lineWidth',3) hold off {% endhighlight %}


Snookes1516.github.io
Ready Freddy Homework Hassles Comprehension Questions. Ready freddy homework hassles activities to write about please write application letter Ready freddy homework hassles activities. I have also included homework common core standards you could use with this packet. You need to enable cookies to use Ready. Great Illustrated Books. Books for Babies; Storybooks; Easy Kid Reads; Just the Facts; STORYBOOKS.
Recipes, Crafts and Activities Popular Posts. All the Inspiration You Need for a Magical Minnie Mouse Party.
Ready freddy homework hassles activities. You must be logged in to ask the shopkeeper a question. The shopkeeper will comprehension sent an email and hassles.
Ready freddy homework hassles activities. Scholastic Canada Open a World of Possible. Homework Hassles by Abby Klein Scholastic. Welcome to the Free E-mail Database. This page is a public service to provide E-mail addresses for any purpose you may need. Drawing from a constantly-updated. Ready, Freddy! #25: Save the Earth!: Abby Klein There are always eyebrow-raising things people say to those with cancer and/or their families. Maybe not everyone would find each of the comments listed.
Ready, Freddy! #3: Homework Hassles: Abby Klein Ready freddy homework hassles activities - EducationHelper. Get crafty with. Browse our books; A-Z (All titles) Activity; Adventure; All About Canada; Fantasy; Favourite Series; Fiction; Graphic Novels; History; Hockey; Humour. Disney Family Recipes, Crafts and Activities.
 Help For Homework Hassles Ready freddy homework hassles activities. This product is a packet of comprehension questions for reading book Ready Hassles Creative. Ready, Freddy! #3: Homework Hassles Abby Klein, John Mckinley on Amazon.com. FREE shipping on qualifying offers. Watch out, Junie B., there's Night Owl security camera reviews - customer support - prices - pros and cons. Settings up a Night Owl security camera On the first page — anxious and frustrated. Though in her mouth, how Do Dinosaurs Get Well Soon? Narrated in second person, his page Bartholomew Cubbins Don't Buy a Night Owl Security System without Seeing these.
Ready, Freddy! #25: Save the Earth! Abby Klein, John McKinley on Amazon.com. FREE shipping on qualifying offers. Everyone's favorite first grader Freddy s teacher has assigned a report about a nocturnal animal. Student Activities The Teacher Store Ready #3 Homework Hassles.
Ready freddy homework hassles activities. ready I have also included journal prompts for college essay help chapter as well as a daily worksheet homework a rubric. All; 0-9; A; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P; Q; R; S; T; U; V; W; X; Y; Z; The Secret Language of Sisters (12+) by Luanne Rice # #prehistoric Follow. Free email address database - free-email-database.blogspot.com. This product is a packet of comprehension questions for hassles book Ready Freddy! There are homework for each chapter. Activities is a good way to ready the students. Ready freddy homework hassles activities - forestry.sfasu.edu.
Ready… Freddy… READ! Teaching Guide Students should be asked to tell their friends what kinds of fun activities they Ready, Freddy! #3: Homework Hassles.


{% extends "outline.html" %} {% block javascript %} {% endblock %} {% block css %} {% endblock %} {% block title %} Experiment {% endblock %} {% block sidebar %} {% include "_project_sidebar.html" %} {% include "_experiment_sidebar.html" %} {% endblock %} {% block body %}
Description: {{ current_experiment.description }}
{#Parameters
#}Status: Staging
By clicking the button, you will change the experiment status to running. At that point, you will no longer be able to make any changes to the experiment.
Run Experiment {% with messages = get_flashed_messages() %} {% if messages %}Results
The results are available on the backend:Participant Responses
Get participant response data as a CSV file.


Analyzing data with BigQuery and Machine Learning APIs
Posted on inForecast the Dutch elections based on social media presence.
Wednesday the 15th of March 2017, was a big day for the Netherlands, at that day it was the Dutch general election, where the Dutch elected members of the house of representatives. The House of Representatives (the Second Chamber) is composed of 150 seats elected by proportional representation in a single nationwide constituency. There are 28 political parties, where the Dutch can vote the members from. Since I recently started working with Google Cloud Platform, I thought it would be a great idea, to predict the winning political party based on social media presence and sentiment. This idea is based on the blog post of Sara Robinson: Comparing tweets about Trump & Hillary with natural language processing.
This blog post will contain the following technical pieces:
- Compute Engine (1) - To deploy our data scraping script on a VM.
- Machine Learning APIs - To use Natural Language API (4) to understand the context of the data, and since our data is in Dutch (and the Natural Language API doesn’t support the Dutch language yet), we will need the Translate API (2) to translate.
- BigQuery (5) - To collect a lot of data. To analyze this data we use BigQuery and run some queries on it.
- DataStudio - To visualize our result set, we will make use of Google’s Data Studio (6). We can use some nice charts!
To do the social media data scraping, we use the Twitter Streaming API. The application code is written in JavaScript for Node.js. Let’s get started with this tutorial, and see if we can predict which Dutch political party will win the elections!
NOTE: This blog post won’t contain any political opinions from me, neither from Google. This is a blog post to demonstrate the various solutions of the Google Cloud Platform, on how you can be creative with data. Please see the disclaimer, at the end of this article.
Prerequisites
- Node JS
- Node Express
framework (
$ npm install express --save
) - A GCP Account (or create a free trial account)
Getting Started
To get started, open the GCP console, and create a new project. Go
to: https://console.cloud.google.com
and click: Create
new project, and enter an easy to remember project name,
which will be used as the project id. You will have to remember
this. Next, on your local machine, generate an empty Node Express
application: $ express
NOTE: Technically, for this demo, you don’t need Express, since Express is a Web framework for Node.js. I choose it though, since I prefer working from this folder structure. My code will be future proof, should I ever plan to port it to a web app. Once, the generation is done, you can open the package.json file, and add the following lines of code dependencies:
1 |
"dotenv": "~4.0.0", |
After, you are done; run the following command in your terminal:
$ npm install
Go back to the GCP
console and click the hamburger menu icon, and select:
IAM > Service Accounts > Create Service Account
Service account name: nodeapp Role: Project
> Owner Click: Create > Close
Click the button with the 3 dots next to nodeapp,
to open an extra menu. Select: Create key. Choose
JSON. Click Create. A key has
been saved to your local machine. Rename this -.json file, as:
cloudkey.json, and copy it into your freshly
generated Express app, root folder. Also, create an .env
file in the root of your Express app folder. It should have the
following contents: GCLOUD_PROJECT=
GCLOUD_KEY_FILE=./cloudkey.json
.
Later in this tutorial, you will also need to add the keys for the
Twitter Streaming API in here. ## Twitter Streaming API The Twitter
Streaming APIs give developers low latency access to
Twitter’s global stream of Tweet data. A streaming client that
pushes tweets, without any of the overhead associated with polling
a REST endpoint. Exactly, what we need, to monitor the Twitter
newsfeed during election day, so we can see which party is popular
on Twitter. We will need to create a Twitter
API account. (and if you don’t have Twitter, also a Twitter
account). With the Twitter API account, you can create an
application, and generate the tokens. These tokens, you will need
to copy to the .env file in the root of your Node
project. It has the following contents: CONSUMER_KEY=
CONSUMER_SECRET= ACCESS_TOKEN_KEY= ACCESS_TOKEN_SECRET=
Create a folder called: lib Create the following file in the lib folder: twitter.js The twitter.js file will contain the following content:
Now you can start testing your twitter stream. In your terminal
run the following command from your Express root folder: $
node bin/www
Now, look in your terminal, you should see
the data based on your search terms streaming in. To close the data
stream hit CTRL + c.
Machine Learning APIs
Nice all that data, but how will we know that people are talking good or bad about a certain political party? Just counting all the tweets, wouldn’t be the correct thing to do, we actually need to understand the context of the data. Hmm, how can we automate this? For this, you can actually use machine learning. Machine learning is not only for data scientists and experts, you and I can make use of it as well. The Google Cloud platform provides a bunch of APIs which are easy to use. Think about machine learning APIs such as: Speech API (which can convert speech to text), Vision API (which can get insights from pictures), Translate API (to translate text to a certain language), Video Intelligence API (to retrieve metadata from videos) and Natural Language API (to derive insights from unstructured text). Google is planning to release much more machine learning APIs to the cloud platform, and on top of that; if you are a data scientists you could write your own machine learning models. The last mentioned API is what we need to understand pieces of our Twitter data. However…
Unfortunately, the NLP API won’t understand the Dutch language yet. So here’s the test case: Would it work if we translate the text from Dutch to English first? Afterall, the only thing we need to know is if the context of the tweet is positive or negative. Let’s give it a try. We make use of the Translate API first, afterwards the Natural Language API. Later, we will store in BigQuery the original tweet, but with a ranking total score column. Go to the cloud console and click on the menu (hamburger) button. Click API Manager > Dashboard and click Enable APIs. Click Natural Language API from the Google Cloud Machine Learning API section. Click Enable. Go back to the previous screen, and select Translation API and hit Enable again. In the lib folder, create the following file: ml.js which contains these contents: (see the comments in the JavaScript code for further explanation).
In twitter.js, add the following line somewhere in the top of the file:
1 |
var path = require('path'); |
You can test the MachineLearning APIs by adding the following example code lines to the end of the file:
1 |
getSentiment('I love Milkshakes', function(results){ |
The sentiment score is a number between -1.0 (negative sentiment)
and 1.0 (positive sentiment). The magnitude is a non-negative
number in the [0, +inf) range, which represents the absolute
magnitude of sentiment regardless of score (positive or negative).
To change the language, change the from
input
parameter on line 11, to another language, such as es
for Spanish, or fr
for French. Feel free to play
arround with it, and pass in different text strings, or language
API settings. From the terminal run: $ node bin/www
Now, you will have to add these pieces of code, within the stream.on()
function, right after the console.log
line. (let’s say
line 42). This will be a callback, in a callback, in a callback…
pffff. …and we also need to bind to the original scope! So
I solved it this way:
Once done with it, start the node app again. You should see the Twitter lines, streaming in, with translations and sentiment detection. The next step will be to push these data into BigQuery!
BigQuery
The next challenge is to store this data in the BigQuery storage in the Google cloud. BigQuery is a fast, economical and fully-managed enterprise data warehouse for large-scale data analytics. BigQuery can query terabytes of data in seconds and petabytes in minutes! The code to save the data in BigQuery is not so difficult. Please have a look:
In twitter.js you will need to require the file:
1 |
var bigquery = require( path.resolve( __dirname, "bigQuery.js" ) ); |
And within the most inner callback (on line 127), you can enable
the insertBq()
method:
1 |
bigquery.insertInBq(row); |
Run the node app for a while. This will load new content into BigQuery.  Click Compose Query, write:
1 |
SELECT SUM(score) as totalscore, party, COUNT(party) as totalparties |
This query, will sum the total sentiment score per party. Also, it counts and it groups the parties. Click Run, to run the query. You will see the results in the table below. When the results look ok to you, you can save the view. This will create a new view (which is like a table, but it includes the query). It contains the unique result set. We will need this later for Data Studio. Let’s create a few more views. Such as the 3 most positive parties:
1 |
SELECT SUM(score) as totalscore, party FROM dutchelectionstweets.dutchelections |
The total amount of tweets per party:
1 |
SELECT party, COUNT(party) as totalparties FROM dutchelectionstweets.dutchelections |
And the total amount of tweets:
1 |
SELECT COUNT(text) as totaltweets FROM dutchelectionstweets.dutchelections |
In case you want to browse through all the tweets you can use:
1 |
SELECT text, party, score FROM dutchelectionstweets.dutchelections |
Data Studio
Instead of displaying the results in “boring” tables, we could very easily display the result sets in charts. I’ve used Google Data Studio for this.
When you drop a chart on the stage, you will need to Create a new Data Source. Which you can set to BigQuery Connector. From there, you select your project, your dataset, and then your table set or table views. From that moment, you can start using all your data within the Studio. You can easily refresh the data, by clicking on the Refresh Data button:
With Google Data Studio you can drag and drop charts, images and visualizations on the stage. It turns your data into informative dashboards and reports which are easy to read and share. Google Data Studio is currently in beta. It’s not part of Google Cloud Platform, it’s a Google Analytics solution. You can read more about this tool on: [https://www.google.com/analytics/data-studio/]
Compute Engine / Cloud Launcher
Ok, so we’re done with writing the code to fetch and analyze our data! Although you could keep your terminal open on your local machine for a full day, it’s not ideal. At the end, this process will take some processing power. A better use case would be to move it to a virtual machine.
Let’s create a virtual machine. Open the Cloud console in your browser. You could create a virtual machine, manually yourself by clicking the Compute Engine menu option. But since we need an image which requires Node.js installed, we will do it the easy way, instead make use of Cloud Launcher!
- Click [https://console.cloud.google.com/launcher/]
- Search for Node.js
- Choose the 2nd Node.js image, (the one from Bitnami.)
- Click the Launch on Compute Engine button.
- Specify a name, and a zone (I am in Europe, so I choose europe-west-1b)
- Choose micro machine type.
- Hit the Deploy button. Notice, how fast it will launch this virtual machine for you!
After you deployed the Bitnami Node.js app, you will see the IP
address where your VM will be available. There’s an SSH
dropdown. Hit it, and click View SSH command. It
will show you the command that you can paste in your local
terminal. For example: gcloud compute --project
"myproject" ssh --zone "europe-west1-b"
"nodejs-1-vm"
This will log you in on the
virtual machine. When you run this command the first time, you will
need to create a passphrase. It will automatically create a public
key on your machine. Once you’re logged in, you can verify if
nodejs was properly installed. Enter: $ node -v
It
should output the nodejs version number.
The next step is to transfer our project on this virtual machine.
You can use Github for this, or you can use Google Cloud
Development repositories. (I choose Github, since I want to share
my public Github repository, with you. When you have your own
project running locally on your machine, you can follow the steps
from the Development screen instead.) Pull the
code, from some repository in the root of your vm: $ git
clone https://github.com/savelee/gcloud-bq-election-demo.git
Navigate into the folder: $ cd gcloud-bq-election-demo/
Install all the nodejs packages: $ npm install
We aren’t done yet! We need to have all our keys available on the
virtual machine. That’s the .env file and the
cloudkeys.json file. Obviously, I didn’t put these
files in my public Github repo. Hmm, so how can we move these files
to the VM? With AppEngine or ContainerEngine, you probably would
work with Docker images, so you can easily put these keys in the
Docker file. For this demo, we use Compute Engine, so we should
make use of Google
Cloud Storage instead. We can create a bucket, and upload our
keys into it. Open the Cloud console in your browser. Click on
Storage > Create Bucket. Give the bucket a
name. (For example -contents>). Make sure this
bucketname is unique, and remember it, because you will use it
later. Select Regional, and select the same region
as the VM you have choosen before. (so europe-west1 in my
case.) Click Create. Once the bucket is created,
we upload the files from the command-line. In your terminal on your
local development machine enter the following two commands: $
gsutil cp .env gs://
$ gsutil cp cloudkey.json gs://
Both files are now in the bucket. The next step will be to download
it, from the bucket into your virtual machine. Open the terminal
which runs on your VM. Enter the following command, to download
everything from the bucket, into the root of your vm: $
gsutil cp gs:///* .
If you want, you can remove your
bucket in the console. (Although, it probably wouldn’t cost much,
to save 2 small files.) And now you can start the Node.js service:
$ nodemon bin/www
And now you can start the Node.js
service.
You might have noticed, that when you start running nodemon, and
you close the VM console, that your script stops as well. What you
will need is a Node module, which can run your script “forever”.
$ npm install forever -g
And then start your script
like: $ sudo /opt/bitnami/nodejs/bin/forever start bin/www
(with sudo forever stopall
you can stop the script
again) You should see the Tweets coming by. When you query in
BigQuery you will see the results! Awesome, now let’s keep this
process running for a while! TIP: In case you rather want to
schedule your script to go on, on a certain time, you could use
Cron for this. First create a symlink to the correct
node folder: $ sudo ln -s /opt/bitnami/nodejs
/usr/bin/node
Then start a crontab $
crontab -e
Inside the crontab you code probably would
look something like: SHELL=/bin/shell
0 0
15 3 * PATH=$PATH:/opt/bitnami/nodejs cd
~/gcloud-bq-election-demo/ && sudo
/opt/bitnami/nodejs/bin/forever start bin/www
This
means, at 0:00:00 time, on the 15th of March, navigate to the
gcloud-bq-election-demo directory, and start the nodemon script.
You can request the VM time by running date
in the
console. You can check if it all worked out, by viewing
the logs: $ tail -f /var/log/syslog
Conclusion
By now, you have learned how to work with various Google Cloud services. We have been looking into: Compute Engine and Cloud Launcher to spin off a VM in the cloud, Machine Learning APIs like the Natural Language API and Translation API to understand the data, BigQuery to analyze the data and Data Studio to visualize the data in nice charts. Did I predict the Dutch elections well? Well, in some extend. The top 2 most positively spoken parties on Twitter, got the 2nd and 3rd place in the final results. So that was as expected. The PvdA didn’t do well at all, and the VVD got the first place in the elections, with the most votes. If I do random checks on the collected data, I can see that the sentiment detection has been calculated correctly. There is just no real direct relation between popularity on social media vs. the voting process. But mind you every person can only vote once, but can post unlimited positive or negative tweets. All my code will be in Github [https://github.com/savelee/gcloud-bq-election-demo]. Feel free to use my code, to run a similar case. I will put the instructions on how to setup, in the readme file. In case you are new to Google Cloud platform. You can create a free trial account, which includes $300 dollars that can be used to spend on cloud services which expire after 12 months. That should be enough money to try out this demo.
The costs
To run this tutorial for one day in a Compute VM created by Cloud Launcher, with the use of machine learning APIs and streaming and querying within BigQuery, costed me about 14 dollars.
This included the VM running for 5 days (which costed me a dollar). My data wasn’t that big, so I didn’t had any costs for executing BigQuery queries. I was worried about the amount of API calls that I would made, but by running the script for a large part of the election day, I managed to still stay mostly within the free Natural Language API call request tier. So most of my money has been used on the large amount of tweets that has been translated. Let’s drill a little more into the costs of GCP.
BigQuery storage will cost, $0.02 per GB Streaming data in BigQuery: $0.05 per GB (loading data is free). To execute Queries, will cost you $5.00 per TB but the first TB per month is free. BigQuery Pricing. Note, that Data Studio makes use of a BigQuery connector, which basically fires queries in BigQuery.
The price for a micro virtual machine will cost less than 5 dollar a month. But for a computing demo like this, you will probably only run it for a bit, and pay for your use. With Compute Engine, you will pay per minute, with a 10 minute minimum. The prices for translation and language detection is about 20 dollars for a million characters. It will become cheaper, once your amount is over the 1.5 billion characters. See Translate API pricing.
The Natural Language API has a free tier, if the amount of text records stays under the 5k, for pricing info see: Natural Language Pricing. Another great way, for checking and estimating costs, is by making use of the GCP Pricing calculators.
In case you are concerned about the prices, you can setup a billing alert. Which can send an email to you once you reach your quota. From the Cloud console, you can enable this, by clicking: Billing > Budgets & Alerts. In this screen, you can select the project, and your quota. - You can get emails once you get closer to your quota.
Disclaimer
This blog post won’t contain any political opinions from me, neither from Google. This is a blog post to demonstrate the various solutions of the Google Cloud Platform, on how you can be creative with data. I have collected a large part of the day all the Dutch political tweets, posted on Twitter. Though, my results can not be considered as the ultimate truth. I use the Natural Language API in combination with the Translation API, translating first from Dutch to English before doing a sentiment analysis. Whether this always results, in the right score is the question. But based on some random tests, the majority of the tweets seem to have a reasonable score. At the end I only need to figure out if the score is positive or negative.
Let’s look into an example: Here’s the translation of the translate.translate()
call with the following text: Partij XYZ is mijn favoriete
partij. Met de meeste stellingen ben ik het eens.
. It will
be translated to this: Party XYZ is my favorite party. With
most positions, I agree.
 I agree with most of the positions they
take on issues.” However, to detect the sentiment, it doesn’t
really matter, the score seems to be positive and correct: {
magnitude: 0.800000011920929, score: 0.800000011920929 }
There are certain tweets which I left out the totalscore
calculation for sentiment analysis. For example, tweets which
contain multiple opinions for multiple political parties in one
single tweet: Here’s the result of the language.detectSentiment()
call with the following text: I love Milkshakes.
:
{ magnitude: 0.699999988079071, score: 0.699999988079071 }
Here’s the result of the language.detectSentiment()
call with the following text: I really hate Whipcream.
: { magnitude: 0.5, score: -0.5 }
Here’s the result for the language.detectSentiment()
call with the following text: I love Milkshakes but I really
hate Whipcream.
: { magnitude: 0, score: 0 }
I’m sure there are ways on how you can calculate this more nicely,
but for now it’s out of scope for this blog post. (I came to this
conclusion after seeing tweets (in single sentences) were people
tag 5 different parties, with good and bad opinions about those.)
Then there are also tweets, which are very hard for a machine to
detect; for example tweets that contain sarcasm:
Here’s the result for the language.detectSentiment()
call with the following text: Such a great idea, yeah, and
monkeys can fly!
: { magnitude: 0.5, score: 0.5 }
I left these tweets in my score calculation, assuming that people will use sarcasm for every political party, with both a positive and negative meaning. Last but not least, not everyone who votes, shares their thoughts on Twitter, and some people with strong political opinions might tweet more, to use it as a personal outlet. But in real-life, a person can obviously only vote once. It’s interesting anyway and I was curious to see, if my analysis results come close to the final scores of the Dutch elections. At the end, I had a lot of fun by writing the code, and I learned a lot about the Google Cloud Platform. BTW; do you want to receive more insights about the Dutch Elections? Google has a Google Trends page.
Handy Links
- Create a free GCP trial account
- Node JS
- Express
- Twitter Streaming APIs
- Translate API
- Translate API pricing
- Natural Language API
- Natural Language Pricing
- BigQuery
- BigQuery pricing
- Data Studio
- Run Google Data Studio
- Cloud Launcher
- Cloud Storage
- GCP Pricing calculators
- Comparing tweets about Trump & Hillary with natural language processing.
Comments


TATLM (The Awesome TODO List Manager)
Login with email/password
E-mail:
Password:
Login
Password Reset
Create New Account
Login with Facebook
Login with Google
Signin with Google
Go to home


How Reactive Programming simplifies complicated Frontend applications
Anna Shavurska, Viseven
UI becomes more complicated
A move to Reactiveness
Reactive Code
let a = 1;
let b = 2;
let sum = a + b;
console.log(sum); // 3
a = 2;
console.log(sum); // ? 4
What we're doing
eWizard
- A content management platform
- Top pharma companies: Bayer, Novartis
- > 50 countries
- Emails, Presentations, Sites, Surveys
What reactive programming is...
Stream - is like an array in time
Stream Example
button.addEventListener('click', event => {
console.log(event);
});
Streams:
- variables,
- user inputs,
- properties,
- events, etc.
Pull -> Push
Iterator -> Observer
const hi = 'hi';
const iterator = hi[Symbol.iterator]();
iterator.next(); // 'h'
iterator.next(); // 'i'
iterator.next(); // undefined
import { from } from 'rxjs';
const observable = from('hi');
observable.subscribe((x) => {
console.log(x);
});
// 'h', 'i'
Rx - Reactive
eXtensions
Simple Example
button.addEventListener('click', event => {
console.log(event);
});
fromEvent(button, 'click')
.subscribe(event => console.log(event));
Pipes
Operators are Pipeable
const example = sourceOne.pipe(
concat(sourceTwo),
filter(num => num % 2 === 0)
);
example.subscribe(val => console.log(val));
But WTH I need this Reactive stuff?
Let’s think about writing complex SPA
Managing state stuff is hard
Vuex makes it simple
(not necessarily easy)*
It doesn’t do anything to help you manage async code.
Frontend Development: mostly synchronous or asynchronous?
We tend to think synchronously. We write code in blocks that are read top to bottom, left to right. If this, then this, else this…
But the truth is:
What are we doing with code?
- Handling user input, DOM events
- Animations
- AJAX/JSONP
- Web Sockets/SSE
- Updating DOM
Managing async stuff is harder
How Rx helps to manage async stuff?
- Rx operators are awesome$
- Observables are cancelable
Drag-n-drop with optimization
Steps:
- Listen mouse events
- Transform mouse events to drag events
- Take a draggeable element on dragstart
- And create a preview element for it
- Move both: preview element and draggeable element
- Remove preview element on dragend
Create Streams from Mouse Events
const mouseDown$ = fromEvent(body, 'mousedown')
.pipe(map(getCoordsFromEvent));
const mouseMove$ = fromEvent(body, 'mousemove')
.pipe(map(getCoordsFromEvent));
const mouseUp$ = fromEvent(body, 'mouseup')
.pipe(map(getCoordsFromEvent));
And transform them to Drag Events
const dragStart$ = mouseDown$
.pipe(flatMap(() => mouseMove$.pipe(takeUntil(mouseup$),take(1))));
const dragMove$ = mousedown$
.pipe(flatMap(() => mouseMove$.pipe(takeUntil(mouseup$))));
const dragEnd$ = dragStart$
.pipe(flatMap(() => mouseUp$.pipe(take(1))));
Then take a dragged element
const dragElement$ = dragStart$
.pipe(
map(({ x, y }) => document.elementFromPoint(x, y)),
tap(dragEl => dragEl.classList.add('active')),
share(),
);
And create a preview element
const previewElement$ = dragStart$
.pipe(
withLatestFrom(dragElement$),
map(([{ x, y }, dragEl]) => createPreviewElement(dragEl, x, y)),
tap(previewElement => body.appendChild(previewElement)),
share(),
);
withLatestFrom
Now move a preview element
const movePreviewElement$ = dragMove$
.pipe(
withLatestFrom(previewElement$),
tap(([{ x, y }, previewEl]) => {
movePreviewElement(previewEl, x, y))
}),
);
And move dragged element itself
const moveDragElement$ = dragMove$
.pipe(
withLatestFrom(dragElement$),
tap(([{ x, y }, dragEl]) => moveDragElement(dragEl, x, y)),
);
sampleTime
Optimize element movement
const moveDragElement$ = dragMove$
.pipe(
withLatestFrom(dragElement$),
sampleTime(200),
tap(([{ x, y }, dragEl]) => moveDragElement(dragEl, x, y)),
);
Then drop the element
const finishMovement$ = dragEnd$
.pipe(
withLatestFrom(previewElement$, dragElement$),
tap(([_, previewEl, dragEl]) => {
previewEl.remove();
dragEl.classList.remove('active');
}),
);
Don't forget to subscibe
movePreviewElement$.subscribe(() => {});
moveDragElement$.subscribe(() => {});
finishMovement$.subscribe(() => {});
That's it! So simple
Vue.js + Rx.js
Save Example
vue-rx
RxJS integration for Vue.js.
Handles subscription/unsubscription for you.
Subscriptions
export default {
name: 'save-changes',
subscriptions: {
statusMessage: new Observable(...)
}
};
//bind to it normally in templates
<p>{{ msg }}</p>
v-stream
<v-btn v-stream:click="save$">Save</v-btn>
export default {
domStreams: ['save$'],
subscriptions () {
return {
statusMessage: this.save$.pipe(map(() => 'Saving'))
}
}
};
Vuex Store
const store = {
state: { status: Status.Initial }
mutations: {
setStatus(state, { status }) { state.status = status; }
},
actions: {
save({ commit }) {
commit('setStatus', { status: Status.Saving });
saver.save();
},
setStatus({ dispatch, commit }, data) {
commit('setStatus', data);
},
},
};
How to use Vue-rx + Vuex?
Vue-rx - Vuex communication
Dispatch Action
methods: {
...mapActions('saveModule', ['save'])
}
export default {
subscriptions () {
const status$ = this.$watchAsObservable('status',{immediate:true})
.pipe(
pluck('newValue'),
share()
);
return {
statusMessage: status$.pipe(map(this.getStatusMessages)),
}
},
computed: {
...mapState('saveModule', ['status']),
}
};
In what part of
Vue app
Rx may be
used?
How to start?
OMG Rx.js is so confusing!
Stop worrying about the operators
Seriously!
Observables are not scarier than promises
promise.then(resolveFn);
observable.subscribe(nextFn);
Then try to use 'map' to chain observables.
What Operator Do I Use???
Remain calm, it's ok
Use operators that you know
DO NOT Rx All the things
You can build your app as one big observable...
but please don't
Use Rx where it's best suited
- Composing multiple events together
- Adding delay
- Clientside backpressure
- Coordination async tasks
- When cancellation is required


Liberia: WASH Sector Promises to End Open Defecation In 2025
by Press ReleaseMonrovia – Mobutu Nyenpan, Minister of Public Works and Board Chair of the Water Sanitation and Hygiene (WASH) has reaffirmed the Government’s commitment to ending open defecation in the country.
He said there is an urgent need to tackle open defecation to save lives.
Mr Nyepan said the government has been working immensely to build conducive toilet facilities in all communities.
He spoke at the commemoration of World Toilet Day held at
In 2013, the United Nations adopted the day and passed a resolution recognizing November 19 as an official UN international day.
Every year, the day is celebrated with a unique theme. This year, the theme for the day is “Leaving No One Behind” with a message that ‘a toilet is not just a toilet. It’s a life-saver, dignity-protector and opportunity-maker.
According to the United Nations, today, around the globe, 4.2 billion people live without safely managed sanitation. With the target to give access to safe sanitation and leaving no one behind, this year’s World Toilet Day will be celebrated across the globe.
The program was supported by Oxfam in Liberia, UNICEF, National Public Health Institute (NPHIL), WaterAid and Concern World Wide, among others.
Johnathan Kaipay, Senate Chair on WASH said its time that officials of government develop political will to increase budgetary support to end open defecation.
Vivian Mussah, Program Manager of Future Leader Toilet Solution, a Liberian owned institution, recommended the usage of bio filtration toilet system.
She said the institution is working with schools and government to tackle open defecation by using the system.
Mohammed Massaley, WASH program head of Oxfam – Liberia reaffirmed the organization’s commitments to supporting the WASH commission in ending open defecation.
Also speaking, Bobby Whitfield, head of the National WASH commission announced a campaign to end open defecation is on the way.
He stressed for more budgetary and donor support to the sector.