Module: Concurrent::Edge
- Defined in:
- lib/concurrent/edge.rb,
lib/concurrent/edge/lock_free_linked_set.rb,
lib/concurrent/edge/atomic_markable_reference.rb,
lib/concurrent/edge/lock_free_linked_set/node.rb,
lib/concurrent/edge/lock_free_linked_set/window.rb
Overview
Edge Feature: Edge features are under active development and may change frequently. They are expected not to
keep backward compatibility (there may also lack tests and documentation). Semantic versions will
be obeyed though. Features developed in concurrent-ruby-edge
are expected to move
to concurrent-ruby
when final.
A submodule for unstable, highly experimental features that are likely to change often and which may never become part of the core gem. Also for new, experimental version of abstractions already in the core gem.
Most new features should start in this module, clearly indicating the
experimental and unstable nature of the feature. Once a feature becomes
more stable and is a candidate for inclusion in the core gem it should
be moved up to the Concurrent
module, where it would reside once merged
into the core gem.
The only exception to this is for features which replace features from the core gem in ways that are breaking and not backward compatible. These features should remain in this module until merged into the core gem. This will prevent namespace collisions.
Defined Under Namespace
Classes: AtomicMarkableReference, LockFreeLinkedSet


{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Security codes" %}{% endblock %} {% block content %} {% include "includes/flash_messages.html" %}
{% trans "Use these security codes to login to the portal. The code proves it’s you." %}
{% trans "You can use each code only once." %}
{% trans "Keep the codes on paper in a safe place. Do not save or store this screen, copy the codes to an electronic device, or share the codes with anyone else." %}
{% include "includes/codes.html" with codes=backup_code_list %}{% trans "When you get new codes, the last codes will no longer work, even if you have not used them yet." %}
{% endblock %}


| Application received | 10:05am on 5th of September 2017 |
| Application submitted | 10:03am on 5th of September 2017 |
Sign out {{/content}} {{/ layout}}
{{< layout}}
{{$pageTitle}}Track a passport application{{/pageTitle}}
{{$content}}
You need to ask someone to
confirm your identity
Your old passport is damaged. We can't print your new passport until your identity is confirmed.
Continue| Application received | 10:05am on 5th of September 2017 |
| Application submitted | 10:03am on 5th of September 2017 |


Loan Calculator
Loan amount
Loan term in
State
months
year
Interest rate per year
Initial payment amount
Type of payment
annuity
differentiated


Tidy Tuesday weekly data analysis projects
U.S. drought extent and severity (Week 30; July 20th , 2021)
Scooby Doo! (Week 29; July 13th , 2021)
Countries' independence days (Week 28; July 6th , 2021)
Animal rescues (Week 27; June 29th, 2021)
Public park access (Week 26; June 22nd, 2021)


Giving a very strict set of guidelines to the format of the report
for assignment 2 is difficult since the different projects are very
varied. However, to give you some general points to follow regarding the
type of information the report should contain, you can get an outline of
a sample project report for a fictional topic for assignment 2
here.
Note that in your case the emphasis may be different, for example:
| Length | Keep it concise, roughly speaking, about 2 pages per person in the group on average. Include a README file with the code so you don't have to put that type of information in the report. |
| Introduction | You must explain the problem you have tackled, the basic approach taken to solving it, and any important aspects of that approach in terms of machine learning. |
| Implementation | If your work was mostly implementation, focus on that. Otherwise briefly describe what you did. |
| Experimentation | All methods must be tested on some data, so these results should be included. Additionally, if this was a major focus, you will need to explain the work done and what was accomplished, for example on setting up the learning task, choice of evaluation, and so on. Detailed statistical analyses are probably outwith the scope of the project, so don't include these unless you are already very familiar with this kind of thing. |
| References | Should be there for algorithms used or other aspects of the work. |
| Appendix | Should be used if you have a lot of experimental results. However, consider plotting graphs or using other visualizations like histograms to summarize a lot of results concisely. |


Tools to visualize movement data (e.g. from GPS tracking) and temporal changes of environmental data (e.g. from remote sensing) by creating video animations.
| Version: | 0.9.9 |
| Depends: | R (≥ 2.10) |
| Imports: | maptools, ggplot2, grid, rasterVis, raster, sp, geosphere, rosm, utils, grDevices, methods, stats, move, gridExtra, graphics, simecol, plyr, zoo, lubridate, parallel, pbapply, RStoolbox |
| Suggests: | testthat |
| Published: | 2018-12-03 |
| Author: | Jakob Schwalb-Willmann [aut, cre] |
| Maintainer: | Jakob Schwalb-Willmann <movevis at schwalb-willmann.de> |
| BugReports: | http://www.github.com/16eagle/moveVis/issues |
| License: | GPL-3 |
| URL: | http://movevis.org |
| NeedsCompilation: | no |
| SystemRequirements: | convert from ImageMagick, ffmpeg from FFmpeg |
| Materials: | README NEWS |
| CRAN checks: | moveVis results |
| Reference manual: | moveVis.pdf |
| Package source: | moveVis_0.9.9.tar.gz |
| Windows binaries: | r-devel: moveVis_0.9.9.zip, r-release: moveVis_0.9.9.zip, r-oldrel: moveVis_0.9.9.zip |
| OS X binaries: | r-release: moveVis_0.9.9.tgz, r-oldrel: moveVis_0.9.9.tgz |
| Old sources: | moveVis archive |
Please use the canonical form https://CRAN.R-project.org/package=moveVis to link to this page.


In order to establish the connection between the application and remote data source you should first complete the authentication process and then click on "Connect to MySQL database" button.
In host name field you should provide the name of the host that will be place instead of "host name" in general JDBC URL connection line jdbc:mysql://"host name":"port"/"database"
In port field you should provide the number of the port that will be place instead of "port" in general JDBC URL connection line jdbc:mysql://"host name":"port"/"database"
In database field you should provide the name of the database that will be place instead of "database" in general JDBC URL connection line jdbc:mysql://"host name":"port"/"database"
When all fields are filled you should click on "Connect to MySQL database" button
If connection is successful you should see:
Example how to connect to MySQL database


Portable distribution of operating systems and tools
A computer is a programmed machine that runs through the sequence of its instruction set. If the instruction is to boot the machine turns on. If the instruction is to launch an application it launches an application. If the instruction is to learn the machine learns.
This instruction set, usual...
USB drives are not the only secondary storage medium in the market. Alternatives like secure disk cards are quite popular. If you use a smart phone you are probably already using a micro sd card. You’d also be using an SD card if you own let us say a digital camera or maybe a smart TV. Although sd...
As we saw in the last post the boot process is a series of steps that change the state of your computer from a system at rest to a running machine that can do real work.
Now one of the steps in this boot process is to find the actual boot device. To clarify the boot device is a storage medium o...
As we talked about in our last article booting a computer is a very straightforward process. So simple in-fact that most of the time you don’t even realize that its happening.
When you press that power button you set in motion a seri...
sparvk provides you with various tools to help you manage your photographs. At the file level it enables you to arrange all your photos in directories. By default sparvk comes with a Pictures directory. As the name suggests the Pictures directory is meant to function as your digital photo album. Her...


New Editor - Almost here!
Posted: Thu Jan 10, 2008 5:22 pm
The next version of the world editor is almost ready to be released! This will be one of the last major feature updates I do before getting back to cracking at the client. The "resource pack" functionality is almost done--adding new content to your map will now be a one-click process. These packs will add images, textures, meshes, skins, scenery and terrain to your world automatically.
All that's stopping me from releasing this thing today is that I want to get some content packs together for you to use. I'm going to organize, re-scale and set up scenery for all of the free content I've gathered from across the web, along with the content I've bought specifically for PV. Finally, I'm going to update the quick-start guide for the new editor and change some things in it based on feedback.
The new editor will not have rules implemented. However, it will have default texture ranges.
All that's stopping me from releasing this thing today is that I want to get some content packs together for you to use. I'm going to organize, re-scale and set up scenery for all of the free content I've gathered from across the web, along with the content I've bought specifically for PV. Finally, I'm going to update the quick-start guide for the new editor and change some things in it based on feedback.
The new editor will not have rules implemented. However, it will have default texture ranges.


Package template
source code
|
|
Templar
The main class for templating, with the main entry-point of
template().
|
|
|
display = Display()
|
|
|
NON_TEMPLATED_TYPES = ( <type 'bool'>, <class 'numbers.Number'>)
|
|
|
JINJA2_OVERRIDE = ' #jinja2: '
|
|
|
__package__ = None
hash(x)
|
Imports:
__metaclass__,
ast,
contextlib,
os,
re,
StringIO,
string_types,
text_type,
binary_type,
Environment,
FileSystemLoader,
TemplateSyntaxError,
UndefinedError,
j2_concat,
StrictUndefined,
C,
AnsibleError,
AnsibleFilterError,
AnsibleUndefinedVariable,
filter_loader,
lookup_loader,
test_loader,
safe_eval,
AnsibleJ2Template,
AnsibleJ2Vars,
to_unicode,
to_str,
sha1,
Number,
Display,
template,
vars
Double backslashes within jinja2 expressions
A user may enter something like this in a playbook::
debug:
msg: "Test Case 1\3; {{ test1_name | regex_replace('^(.*)_name$', '\1')}}"
The string inside of the {{ gets interpreted multiple times First by yaml.
Then by python. And finally by jinja2 as part of it's variable. Because
it is processed by both python and jinja2, the backslash escaped
characters get unescaped twice. This means that we'd normally have to use
four backslashes to escape that. This is painful for playbook authors as
they have to remember different rules for inside vs outside of a jinja2
expression (The backslashes outside of the "{{ }}" only get processed by
yaml and python. So they only need to be escaped once). The following
code fixes this by automatically performing the extra quoting of
backslashes inside of a jinja2 expression.
|
|
Counts the number of newlines at the end of a string. This is used
during the jinja2 templating to ensure the count matches the input, since
some newlines may be thrown away during the templating.
|


Statistical Calculator
Enter Array Here:
Submit
Reset
Min:
Max:
Sum:
Mean:
Median:
Mode:
Std Dev:
Variance:
ePortfolio


wish(1) Tk Applications wish(1) ________________________________________________________________________________ NAME wish - Simple windowing shell SYNOPSIS wish ?fileName arg arg ...? OPTIONS -colormap new Specifies that the window should have a new private colormap instead of using the default colormap for the screen. -display display Display (and screen) on which to display window. -geometry geometry Initial geometry to use for window. If this option is specified, its value is stored in the geometry global variable of the application's Tcl interpreter. -name name Use name as the title to be displayed in the window, and as the name of the interpreter for send commands. -sync Execute all X server commands synchronously, so that errors are reported immediately. This will result in much slower execution, but it is useful for debug‐ ging. -use id │ Specifies that the main window for the application is │ to be embedded in the window whose identifier is id, │ instead of being created as an independent toplevel │ window. Id must be specified in the same way as the │ value for the -use option for toplevel widgets (i.e. │ it has a form like that returned by the winfo id com‐ │ mand). -visual visual Specifies the visual to use for the window. Visual may have any of the forms supported by the Tk_GetVi‐ sual procedure. -- Pass all remaining arguments through to the script's argv variable without interpreting them. This pro‐ vides a mechanism for passing arguments such as -name to a script instead of having wish interpret them. _________________________________________________________________ DESCRIPTION Wish is a simple program consisting of the Tcl command language, the Tk toolkit, and a main program that reads commands from standard input or from a file. It creates a main window and then processes Tcl commands. If wish is invoked with no arguments, or with a first argument that starts with ``-'', then it reads Tcl commands interactively from standard input. It will continue processing commands until all windows have been deleted or until end-of-file is reached on standard input. If there exists a file .wishrc in the home directory of the user, wish evaluates the file as a Tcl script just before reading the first command from stan‐ dard input. If wish is invoked with an initial fileName argument, then fileName is treated as the name of a script file. Wish will evaluate the script in fileName (which presumably creates a user interface), then it will respond to events until all windows have been deleted. Commands will not be read from standard input. There is no automatic evaluation of .wishrc when the name of a script file is presented on the wish command line, but the script file can always source it if desired. OPTIONS Wish automatically processes all of the command-line options described in the OPTIONS summary above. Any other command-line arguments besides these are passed through to the application using the argc and argv vari‐ ables described later. APPLICATION NAME AND CLASS The name of the application, which is used for purposes such as send com‐ mands, is taken from the -name option, if it is specified; otherwise it is taken from fileName, if it is specified, or from the command name by which wish was invoked. In the last two cases, if the name contains a ``/'' character, then only the characters after the last slash are used as the application name. The class of the application, which is used for purposes such as specify‐ ing options with a RESOURCE_MANAGER property or .Xdefaults file, is the same as its name except that the first letter is capitalized. VARIABLES Wish sets the following Tcl variables: argc Contains a count of the number of arg arguments (0 if none), not including the options described above. argv Contains a Tcl list whose elements are the arg arguments that follow a -- option or don't match any of the options described in OPTIONS above, in order, or an empty string if there are no such arguments. argv0 Contains fileName if it was specified. Otherwise, con‐ tains the name by which wish was invoked. geometry If the -geometry option is specified, wish copies its value into this variable. If the variable still exists after fileName has been evaluated, wish uses the value of the variable in a wm geometry command to set the main win‐ dow's geometry. tcl_interactive Contains 1 if wish is reading commands interactively (fileName was not specified and standard input is a termi‐ nal-like device), 0 otherwise. SCRIPT FILES If you create a Tcl script in a file whose first line is #!/usr/local/bin/wish then you can invoke the script file directly from your shell if you mark it as executable. This assumes that wish has been installed in the default location in /usr/local/bin; if it's installed somewhere else then you'll have to modify the above line to match. Many UNIX systems do not allow the #! line to exceed about 30 characters in length, so be sure that the wish executable can be accessed with a short file name. An even better approach is to start your script files with the following three lines: #!/bin/sh # the next line restarts using wish \ exec wish "$0" "$@" This approach has three advantages over the approach in the previous paragraph. First, the location of the wish binary doesn't have to be hard-wired into the script: it can be anywhere in your shell search path. Second, it gets around the 30-character file name limit in the previous approach. Third, this approach will work even if wish is itself a shell script (this is done on some systems in order to handle multiple architectures or operating systems: the wish script selects one of sev‐ eral binaries to run). The three lines cause both sh and wish to process the script, but the exec is only executed by sh. sh processes the script first; it treats the second line as a comment and executes the third line. The exec statement cause the shell to stop processing and instead to start up wish to reprocess the entire script. When wish starts up, it treats all three lines as comments, since the backslash at the end of the second line causes the third line to be treated as part of the comment on the second line. The end of a script file may be marked either by the physical end of the │ medium, or by the character, '\032' ('\u001a', control-Z). If this char‐ │ acter is present in the file, the wish application will read text up to │ but not including the character. An application that requires this char‐ │ acter in the file may encode it as ``\032'', ``\x1a'', or ``\u001a''; or │ may generate it by use of commands such as format or binary. PROMPTS When wish is invoked interactively it normally prompts for each command with ``% ''. You can change the prompt by setting the variables tcl_prompt1 and tcl_prompt2. If variable tcl_prompt1 exists then it must consist of a Tcl script to output a prompt; instead of outputting a prompt wish will evaluate the script in tcl_prompt1. The variable tcl_prompt2 is used in a similar way when a newline is typed but the cur‐ rent command isn't yet complete; if tcl_prompt2 isn't set then no prompt is output for incomplete commands. KEYWORDS shell, toolkit Tk 8.0 wish(1)


Methods
(static) convert(body, encoding) → {String}
Convert string with `encoding`.
Parameters:
| Name | Type | Description |
|---|---|---|
body |
String | This is an original data. |
encoding |
String | This is an encoding. (Ex. Shift_JIS.) |
- Source:
Returns:
Converted value.
- Type
- String
(static) doParse(va_args) → {function}
Execute several parsers sequentially.
Parameters:
| Name | Type | Description |
|---|---|---|
va_args |
Any | Input pairs and an output function. The pair is an Array which consits of a variable name and a parser function (ex. ['x', parser]). The output function use the variables. |
- Source:
Returns:
- Return a monad that is identified in last of arguments.
- Type
- function
(static) get(url, encoding, This, This)
Call http get with `url`.
Parameters:
| Name | Type | Description |
|---|---|---|
url |
String | This is a url to get. |
encoding |
String | This is an encoding for the response body. (Ex. Shift_JIS.) |
This |
success | callback handles response when the status code is 200. The parameter is an encoded response body. |
This |
failure | callback handles failure case. It is called when the request failed or the response code is not 200. This has 2 parameters. One is a status code of response. And the other is a requested url. |
- Source:
(static) getChilds(node, localName) → {Array.<Node>}
Get nodes identified in `localName` from childNodes of `node`.
Parameters:
| Name | Type | Description |
|---|---|---|
node |
Node | This is a node as a basis. |
localName |
String | This is a local name to search |
- Source:
Returns:
Array of nodes
- Type
- Array.<Node>
(static) monad(f) → {function}
Get monad from Function `f`.
Parameters:
| Name | Type | Description |
|---|---|---|
f |
function | This is a function (ex. parser function) |
- Source:
- See:
-
- doParse
Returns:
- Return a monad value including f
- Type
- function
(static) searchSiblings(node, localName, This)
Search a node whose local name is `localName` in sliblings of `node`.
Parameters:
| Name | Type | Description |
|---|---|---|
node |
Node | This is a node as a basis. |
localName |
String | This is a local name to search |
This |
siblingsCallback | callback handles a sibling of `node`. This has a parameters which is the searched node. This returns boolean. If true, it continue to search. Otherwise, stop searching. |
- Source:
(static) serial(arr, func, last)
Loop array sequentially.
Parameters:
| Name | Type | Description |
|---|---|---|
arr |
Array | This is Array to apply `func`. |
func |
function | This is a loop body. This function is called with two argument. One is an element of `arr`. The other is "next function" which continues next loop. |
last |
function | This is called if all of elements of `arr` are applied. |
- Source:


aws route53
CLI for AWS Route53 - Route 53 is a highly available and scalable Domain Name System (DNS) web service.
More information: home page
- List all hosted zones, private and public:
aws route53 list-hosted-zones
- Show all records in a zone:
aws route53 list-resource-record-sets --hosted-zone-id zone_id
- Create a new, public zone using a request identifier to retry the operation safely:
aws route53 create-hosted-zone --name name --caller-reference request_identifier
- Delete a zone (if the zone has non-defaults SOA and NS records the command will fail):
aws route53 delete-hosted-zone --id zone_id
- Test DNS resolving by Amazon servers of a given zone:
aws route53 test-dns-answer --hosted-zone-id zone_id --record-name name --record-type type


{%include "head.html" %}
{# Comment: The extra styled div here below is to force footer to always be at the bottom even if content is not much. See https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ In addition, remember to put a section always for main contain between navigation and footer with flex: 1 #}


{% extends "www/bases/documentation.html" %}
{% block subtitle %}Changelog{% endblock subtitle %}
{% block content %}
Changelog
0.6.3
- Fix bug where model elements weren't getting updated values when an action was being called during the same component update.
- Fix bug where some action event listeners were duplicated.
0.6.2
- More robust fix for de-duping multiple actions.
- Fix bug where conditionally added actions didn't get an event listener.
0.6.1
- Fix model sync getting lost when there is an action (issue 39).
- Small fix for validations.
0.6.0
0.5.0
- Call component method from Javascript.
- Support classes, dictionaries, Django Models, (read-only) Django QuerySets properties on a component.
- Debounce modifier to change how fast changes are sent to the backend from
unicorn:model
.
- Lazy modifier to listen for
blur
instead of input
on unicorn:model
.
- Better support for
textarea
HTML element.
All changes since 0.4.0
0.4.0
- Set shortcut for setting properties.
- Listen for any valid event, not just
click
.
- Better handling for model updates when element ids aren't unique.
All changes since 0.3.0
0.3.0
- Add mount hook.
- Add reset action.
- Remove lag when typing fast in a text input and overall improved performance.
- Better error handling for exceptional cases.
All changes since 0.2.3
0.2.3
Fix for creating default folders when running `startunicorn`.
0.2.2
Set default template_name
if it's missing in component.
0.2.1
Fix startunicorn
Django management command.
0.2.0
Switch from Component
class to UnicornView
to follow the conventions of class-based views.
0.1.1
Fix package readme and repository link.
0.1.0
Initial version with basic functionality.
{% endblock content %}


We know the difference between true and false.
Trust the experts in the fakesecurity field.
OUR MISSION
Argo is leader in the verified information market. Thanks to our control software we won the battle against synthetic media. Through simplicity and clarity Argo offers certainty to its clients, they no longer have to worry about verifying the origin of the content they see. You only have to trust us.
WE ARE SPECIALIZED IN
IDENTITY PROTECTION
FAKE WEAPONS REAL FIGHTS
LEGAL DUBT
SYNTHETIC GAP


Crop Prediction
Ph level of Soil
Nitrogen Level
Phosphurus
Potassium
Depth
Rainfall
Temperature
The Predicted output is:
{{output}}


Love and Death on Long Island (1998)
Director: Richard Kwietniowski Cast: John Hurt, Jason Priestley, Fiona Loewi, Sheila Hancock, Maury Chaykin Screenplay: Richard Kwietniowski Producers: Steve Clark-Hall, Christopher Zimmer Runtime: 103 min. US Distribution: Cinepix Rated PG-13: brief strong language, sex, thematic elements
By Nathaniel R. Atcheson<EMAIL_ADDRESS>I think many will miss the point of Love and Death on Long Island. I do not say this condescendingly; I say this because I think that, in order to completely understand what the characters do in this film, you almost have to have been there yourself at some point in your life. And I'm not sure that everyone has the capacity to do what the main character, Giles De'Ath, does here. If you watch carefully, though, and digest all that the picture has to offer, perhaps you'll find yourself understanding something that you might not have even considered before.
Love and Death is a beautiful, touching film--intelligently funny, perfectly acted, and absolutely realistic in every sense of the word. It had me deeply interested from the very beginning, and it's the kind of film that manages to surprise you with realism and character development. This is also the kind of film that engages themes and ideas in such a complete way that you'll be discussing and thinking about the film long after it's over.
John Hurt, in what is perhaps the best performance of his lengthy and distinguished career, plays aging British writer Giles De'Ath. He's one of those detached artists who refuses to acknowledge anything that has to do with progress and technology; consequently, he doesn't know the difference between a microwave and a VCR. One day, after locking himself out of his house, Giles decides to take shelter in a movie theater, where he thinks he's going to see a film based on an E.M. Foster novel. He stumbles into the wrong theater, and is subjected to Hotpants College II, a puerile film that obviously doesn't interest him.
Just as he's getting up to leave, he sees an actor that catches his eye; his name is Ronnie Bostock (Jason Priestly). Giles instantly develops a fixation on the young man. He buys magazines intended for teenage girls to find pictures of and articles about him, which he organizes into a a scrapbook. He buys a television and a VCR just so he can rent all of Ronnie's films. Giles even dreams about him at night, fantasizing that he's a participant on a game show that asks questions specifically about Ronnie Bostock.
After he's had enough of this, Giles finally heads overseas to Long Island. Through a series of actions that come dangerously close to stalking, he finally meets Ronnie's fiancée, Audrey (Fiona Loewi). Audrey is fascinated with Giles, and invites him to meet Ronnie. When Giles and Ronnie finally meet, Giles explains his belief that Ronnie has rare talent, and that he has a screenplay in mind for which Ronnie would be perfect.
Even on the surface, there's nothing familiar or tired about Love and Death on Long Island. Written and directed by Richard Kwietniowski (based on the novel by Gilbert Adair), the film is packed with of details and intelligent subtleties. Kwietniowski is clearly a man who has been in a position similar to Giles', and his understanding of what Giles feels is key to the success of this film. At first, Giles understands his obsession is ridiculous: he's terribly concerned that people may see him pick up a copy of Sugar at the magazine rack; when he goes to see Ronnie's film over and over again, he can't even bring himself to say the name of the picture.
But Giles' burst of emotions near the end of the film is not the slightest bit difficult to accept or understand: here is a man who has been married for almost his entire life, and, suddenly, he has inexplicable feelings towards a man of less than half his age. Hurt's performance here is dignified and extremely moving; he brings grace and incredible comic timing to each of his scenes. He delivers his clever dialogue the way only a pro can manage. He ornaments the performance with physical and verbal nuances that help to create the round and fascinating character that Giles is.
Priestly also gives a great performance as the disgruntled actor; he manages to satirize his own previous Beverly Hills, 90210 image in playing a teen idol who stars in second-rate films, including Tex Mex and Skid Marks (which gets its title from this line of dialogue: "You're the skid marks on the underpants of life!").
The film is profoundly funny in its dry, British way. When a diner owner (Maury Chaykin) finds out that Giles is from London, he wonders if Giles has ever run into a guy named Stan Brickowski.  It takes clear insight into the minds of people to be able to make jokes out of this kind of material.
But what sends Love and Death beyond the threshold of greatness is its themes. This is a film that recognizes the true, uncontrollable chaos of love. It realizes that love makes no sense, and that it can occur between any two people. It ignores social trappings and gender stereotypes, and deals with Giles in such a way that we can understand him despite the uniqueness of his situation. This film is so deeply successful in illustrating its themes that it's impossible to walk away from the picture without carrying new insight into the varied dynamics that human relationships often have.
There are some standard genres of comedy into which Love and Death would easily fit -- the film is so potent and intelligent as a comedy that one could ignore its themes and enjoy it simply for the entertainment it provides. But this is a film that does so much more than entertains: it clearly illustrates a part of human nature that a vast majority of the world ignores entirely. It takes genius to realize such a theme and create a funny and moving film to put forth the ideas. Love and Death on Long Island is a wonderful film that everyone should see and take seriously down to its most subtle detail.
**** out of **** (9/10, A)
Visit FILM PSYCHOSIS at http://www.pyramid.net/natesmovies
Nathaniel R. Atcheson
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


|
CSCI441 Library
v1.7
Helper functions for CSCI441 Computer Graphics
|
This library is intended to be used with OpenGL for CSCI441 at the Colorado School of Mines.
When building, the library must be compiled and linked against OpenGL and glm. Headers thatend in *3.hpp are built for OpenGL 3.0+ and additionally depend upon GLEW.
Copyright (c) 2017 Dr. Jeffrey Paone
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
TODO Items
Handle vertex and face colors in OFF files
Revision History
v1.8 - 16 Nov 2017
Added support for MTL files for Phong Shading and diffuse maps
v1.7 - 16 Nov 2017
Added loadBMP() support to TextureUtils.hpp
Added support for ASCII STL files to modelLoader3.hpp
Added support for OFF files to modelLoader3.hpp
Fixed reallocation error if model did not load properly
Added support for ASCII PLY files to modelLoader3.hpp (as long as first three vertex properties are x/y/z location)
If PLY file does not contain normal information (we're currently not checking for it), can autogenerate vertex normals
If OFF file does not contain normal information, can autogenerate vertex normals
If OBJ file does not contain normal information, can autogenerate vertex normals
v1.6 - 15 Nov 2017
Added FramebufferUtils3.hpp to print Framebuffer info
Fixed off by 1 error for normals/texcoords in modelLoader3.hpp
Fixed overflow error for modelLoader3.hpp when reading in models with more than 65535 vertices
v1.5.1 - 10 Nov 2017
Fixed redefinition errors in teapot3.hpp and objects3.hpp
Fixed bug in ShaderUtils3.hpp to check if OpenGL is version 4.0+ before querying subroutine uniforms
v1.5 - 06 Nov 2017
Added loadTGA method to TextureUtils.hpp
Commenting added to TextureUtils.hpp
Converted OpenGLUtils from static non-implementable class to namespace
Added commenting to ShaderProgram3.hpp
v1.4.1 - 05 Nov 2017
Fixed bug in objects3.hpp of internally passing torus parameters in incorrect order
v1.4 - 03 Nov 2017
Created ShaderUtils3.hpp and ShaderProgram3.hpp to make working with Shaders easier
v.1.3.1 - 28 Oct 2017
Matched internal data types to prevent c++11 narrowing warnings on lab machines
v1.3 - 26 Oct 2017
Modified texture coordinates for cylinder to linear step from 0 to 1 in s instead of following cosine
Modified texture coordinates for sphere to linear step form 0 to 1 in s & t instead of following sine and cosine
Fixed bug when disk was not being displayed if consisting of 1 ring
Fixed bug with Partial Disk not starting at current angle
Fixed bug with normals on Sphere stacks
Added modelLoader3.hpp to handle loading and drawing OBJ files
Added objects3.hpp that allow for solid primitives to be drawn with OpenGL 3.0
Notes for teapot - the teapot cannot be textured and it is a pure teapot with no bottom
For a textured teapot, look into using an object model
v1.2 - 25 Sep 2017
Fixed error in draw*Disk not completing final slice step
Added TextureUtils to load in a PPM
Added MaterialStruct structure to group together Phong properties
Fixed error in drawSolidDisk() not allowing inner radius to be zero
v1.1.1 - 22 Sep 2017
Removed GL_MAX_COLOR_ATTACHMENTS to comply with lab machines
v1.1 - 21 Sep 2017
Added OpenGLUtils class to store commonly used helper functions
v1.0.1 - 19 Sep 2017
Added documentation
Added inline definition to functions to prevent duplicate linking errors
v1.0 - 01 Sep 2017
Initial release of all OpenGL 3D objects


SVL_QLOG
The SVL_QLOG view contains a log of all queries run against the database.
Amazon Redshift creates the SVL_QLOG view as a readable subset of information from the STL_QUERY table. Use this table to find the query ID for a recently run query or to see how long it took a query to complete.
SVL_QLOG is visible to all users. Superusers can see all rows; regular users can see only their own data. For more information, see Visibility of Data in System Tables and Views.
Table Columns
| Column Name | Data Type | Description |
|---|---|---|
| userid | integer | ID of the user who generated the entry. |
| query | integer | Query ID. You can use this ID to join various other system tables and views. |
| xid | bigint | Transaction ID. |
| pid | integer | Process ID associated with the query. |
| starttime | timestamp | Exact time when the statement started executing,
with six digits of precision for fractional seconds—for
example: 2009-06-12 11:29:19.131358
|
| endtime | timestamp | Exact time when the statement finished executing,
with six digits of precision for fractional seconds—for
example: 2009-06-12 11:29:19.193640
|
| elapsed | bigint | Length of time that it took the query to execute (in microseconds). |
| aborted | integer | If a query was aborted by the system or cancelled
by the user, this column contains 1 . If the
query ran to completion, this column contains
0 . Queries that are aborted for workload
management purposes and subsequently restarted also have a value of
1 in this column.
|
| label | character(30) | Either the name of the file used to run the query,
or a label defined with a SET QUERY_GROUP command. If the query is
not file-based or the QUERY_GROUP parameter is not set, this field
value is default .
|
| substring | character(60) | Truncated query text. |
| source_query | integer | If the query used result caching, the query ID of
the query that was the source of the cached results. If result
caching was not used, this field value is NULL .
|
| from_sp_call | integer | If the query was called from a stored procedure,
the query ID of the procedure call. If the query wasn't run as
part of a stored procedure, this field is NULL .
|
Sample Queries
The following example returns the query ID, execution time, and truncated query
text for the five most recent database queries executed by the user with
userid = 100
.
select query, pid, elapsed, substring from svl_qlog where userid = 100 order by starttime desc limit 5; query | pid | elapsed | substring --------+-------+----------+----------------------------------------------- 187752 | 18921 | 18465685 | select query, elapsed, substring from svl_... 204168 | 5117 | 59603 | insert into testtable values (100); 187561 | 17046 | 1003052 | select * from pg_table_def where tablename... 187549 | 17046 | 1108584 | select * from STV_WLM_SERVICE_CLASS_CONFIG 187468 | 17046 | 5670661 | select * from pg_table_def where schemaname... (5 rows)
The following example returns the SQL script name (LABEL column) and elapsed time
for a query that was cancelled (aborted=1
):
select query, elapsed, label from svl_qlog where aborted=1; query | elapsed | label -------+---------+-------------------------------- 16 | 6935292 | alltickittablesjoin.sql (1 row)


U.S. groups urge automakers to adopt common names for driver assistance technology
by Reuters(Reuters) - A group of stakeholders in the U.S. auto industry urged automakers to adopt standarized names for Advanced Driver Assistance System (ADAS) technology from a list they released on Wednesday, seeking to reduce confusion among consumers.
The list of names, drawn up by roadside assistance provider American Automobile Association (AAA), influential U.S. magazine Consumer Reports, auto industry consultant J.D. Power and the National Safety Council, also looks to ensure drivers are aware these systems are designed to assist and not replace an engaged driver.
It includes five categories — driving control assistance, collision warnings, collision intervention, parking assistance and other driver assistance systems — and will be updated when new systems come to the market.
The new names are not meant to replace automaker system names, but seek to provide consistent information on window stickers, owner manuals and marketing materials, the four organizations said in a joint statement.
Consumers are faced with as many as 20 names for a single ADAS feature as vehicle makers often prioritize marketing over clarity, an AAA research found earlier this year.


Equivalent Arch Clearance Calculator
Single Wheel Details
About the Equivalent Arch Clearance Calculator
The equivalent arch clearance calculator allows you to compare a specified wheel against other wheel sizes with the same arch clearance.
Once you have entered the whel specification into the form on the left, the calculator will display the equivalent offset of wheels in various widths.
For example, you can calculate that a 9.5J et12 wheel would have the same arch clearance as an 8J et-7 wheel.


Week #4: Cultural
Jobs in Web Development
Is it really as great as it seems or is this too good to be true?
I think writing code is important. I think it's something I can enjoy and something that I can be good at in time. But getting into web development was more of a means to an end than a passion. I had started another career years ago that didn't seem to be going anywhere. I needed to try something else and every other article I read points to learning how to write code. From what I could tell, there were all these great companies with all these great jobs and not enough people to fill them. I thought, "SIGN ME UP!"
So I um... signed up.
I'm excited about it. I tell people about it. I'm very optimistic about it, but others seem less convinced. It simply seems too good to be true. Is it?
The career of Web Developer is said to be the ninth best job in America just behind Physician. You know Physician?  So of course the next best job would be something you can get after only nine weeks of training. OK, yes, my "too good to be true" alarm is starting to go off. How can this be possible?
The Bureau of Labor Statistics projects 20% employment growth for Web Developers between 2012 and 2022. That's around 170,000 developer jobs in total. That's a lot of jobs and there simply aren't enough people with the skills to fill them.
And that's exactly why something like DBC can exist. Coding is often compared to learning a language so let's take the metaphor a little further. Let's say you need to hire a translator who speaks Spanish. Who would you rather hire - someone who grew up speaking English but then majored in Spanish at Harvard, or someone who is a first generation American who's been speaking Spanish their entire life? My point is that I wouldn't care where you learned the language. I just care that you can speak it and speak it well.
A few years ago I would have thought that the only way to learn to program would have been to go do a masters in Computer Science. That's not something that I would have been interested in. But spending a couple months completely immersed in the world of coding seems like a better approach. I'd even bet that the amount of time spent coding at DBC is comparable to a two year program.
I estimate that by the end of DBC I will have spent around 1,500 hours on this stuff once you factor in phase 0 and the prep time prior to that. If you subscribe to the Malcolm Gladwell theory of the 10,000 hour rule which says that at 10,000 hours you will be a world class master at your trade, then 1,500 hours sounds like it's at least enough to be as Shereef says, "a world class beginner." It has to at least be enough to get a job. Especially if that job is in an industry that appears to be scrambling to fill positions.


Sweet, sweet databases
This past week has been dedicated to learning some of the many wonders of databases and database management (SQL - Structured Query Language - in particular). I know I know, "databases" and "database management" are seminally unsexy terms, but give me a chance to explain why they're awesome.
Databases save your account information so that you can log in to Facebook. They store your online banking password. They contain your address, email, phone number, social security number, and a whole host of other personal information you probably want to be kept private. You can picture them as digital Excel spreadsheets, with information stored in cells that are organized in rows and columns. The good news about all of this stored info? Well-coded web applications will keep your information safe and protected. The bad news? Even well-coded web apps, and especially poorly coded ones, can be susceptible to an SQL injection (*cue ominous music*). Before I can say another word about this nasty guy, let's introduce ourselves to SQL.
What is SQL?
If databases store information, then SQL manages it. SQL can add a column for your date of birth. It can delete your social security number from the database. It can give us a list of every Facebook user whose first name is "Joseph" or even give us every piece of stored information for every Facebook user. SQL is both very powerful, and very easy to use. This bodes very well for me, a new programmer learning to work with databases, and very bad for those that want to protect them. After all, if it's easy to use, it's easy for everyone to use, including those that want to steal your information. And speaking of stealing information, I present to you our nemesis, SQL injection.
Now for the injection
If databases store information and SQL manages it, then an SQL injection is when a hacker takes advantage of improper coding to a web application and "injects" an SQL command into a form - let's say a Facebook login form - and gains access to your private data within the database. How does this happen?
Let's stick with our Facebook login form example. When legitimate users submit their email and password, an SQL query is generated from these details and submitted to the database for verification. If valid, these users are allowed access into their Facebook pages. However, non-legitimate users may use an SQL injection comprised of specifically crated SQL commands to bypass the login form barrier and access users' account information. So if a web application hasn't been coded properly, i.e. without security provisions in mind, it will certainly be more susceptible to injections.
While the example above focuses on a login page, SQL injections are not limited to just that type of application. Support and product request forms, feedback forms, search pages, and online shopping carts are all at risk because the fields available for user input allow SQL statements to pass through and query the database directly, just as web applications are supposed to do. So what can be done?
Potential solutions
Fortunately, there are a few techniques that can be implemented to reduce the risk of an SQL injection and they are as follows:
- Prepared Statements
- Stored Procedures
- Escaping All User Supplied Input
- Least Privilege
- White List Input Validation
For a new programmer like myself, prepared statements are the first and best line of defense for preventing SQL injections. Prepared statements, or parameterized queries, force the developer to first define all the SQL code and then pass in each parameter to the query later. This technique allows the database to distinguish between code and data, regardless of the user input. Such prepared statements ensure that a hacker is not able to change the intent of a query, even if SQL commands are inserted by a hacker
As I mentioned, coding your web applications with security in mind and using prepared statements is a plus, but certainly not a complete fix. Patching your servers, databases, programming language and operating systems is also critical but again, not a cure-all. After all, since your website needs to be public, security mechanisms will allow public web traffic to communicate with your databases servers through web applications, which is exactly what you want.


High-quality drone photography and videography shot by
professionals at your location. Book A ConsultationA New Perspective
Elevate the production of your next advertisement, trailer or real estate listing with professionally captured and edited ariel footage — Simply describe your concept and let our skilled team get the perfect shot.
Stack is a CASA registered organisation. All staff are highly trained in safely piloting aircraft in all conditions.
Building & Real Estate
From private residential home listings to construction timelapses — Stack has extensive experience delivering highly-quality property films.
Learn MoreTourism Trailers
Delight potential customers with a thrilling glimpse of your outdoor adventure experience. We go where no 'go-pro' could ever hope to go, yo.
Learn MoreSports Events
Rally your fans and relive the glory from a whole new perspective - Our sporting event films champion the highest quality production values around.
Learn MoreTake to the skies.
Get In Touch
Whether you’re building a welcome mat for your SaaS or a clean, corporate portfolio, Stack has your design needs covered.


During today's Team Time Trial Mixed Relay at the UCI Road World Championships in Flanders, he and Alex Dowsett were seen with something down the front of their jerseys, described by Michael Hutchinson as a "gigantic monoboob" in Eurosport commentary.
read moreColnago has announced a partnership with MyLime, a premium blockchain specialist, to provide official product validation on its future bikes. There's no denying that Colnago bikes are highly coveted and prized, many of which are considered some of the best road bikes
read moreThe Italian National Team will field a seven-rider team for the elite women's road race led by Elisa Balsamo, Elisa Longo Borghini, and former World Champion Marta Bastianelli.
read more


First, I believe that this nation should commit itself to achieving the goal, before this decade is out, of landing a man on the moon and returning him safely to the earth. No single space project in this period will be more impressive to mankind, or more important for the long-range exploration of space; and none will be so difficult or expensive to accomplish.
The Earth is a very small stage in a vast cosmic arena. Think of the rivers of blood spilled by all those generals and emperors so that, in glory and triumph, they could become the momentary masters of a fraction of a dot. Think of the endless cruelties visited by the inhabitants of one corner of this pixel on the scarcely distinguishable inhabitants of some other corner, how frequent their misunderstandings, how eager they are to kill one another, how fervent their hatreds.
I am a stranger. I come in peace.
Houston, that may have seemed like a very long final phase. The autotargeting was taking us right into a ... crater, with a large number of big boulders and rocks ... and it required ... flying manually over the rock field to find a reasonably good area.
From this day forward, Flight Control will be known by two words: 'Tough' and 'Competent.' Tough means we are forever accountable for what we do or what we fail to do. We will never again compromise our responsibilities. Every time we walk into Mission Control we will know what we stand for. Competent means we will never take anything for granted. We will never be found short in our knowledge and in our skills. Mission Control will be perfect. When you leave this meeting today you will go to your office and the first thing you will do there is to write 'Tough and Competent' on your blackboards. It will never be erased. Each day when you enter the room these words will remind you of the price paid by Grissom, White, and Chaffee. These words are the price of admission to the ranks of Mission Control.
We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.
The surface is fine and powdery. I can kick it up loosely with my toe. It does adhere in fine layers, like powdered charcoal, to the sole and sides of my boots. I only go in a small fraction of an inch, maybe an eighth of an inch, but I can see the footprints of my boots and the treads in the fine, sandy particles. There seems to be no difficult in moving around, as we suspected.
Look again at that dot. That's here. That's home. That's us.  The aggregate of our joy and suffering, thousands of confident religions, ideologies, and economic doctrines, every hunter and forager, every hero and coward, every creator and destroyer of civilization, every king and peasant, every young couple in love, every mother and father, hopeful child, inventor and explorer, every teacher of morals, every corrupt politician, every "superstar," every "supreme leader," every saint and sinner in the history of our species lived there--on a mote of dust suspended in a sunbeam.
I am a stranger. I come in peace.
Houston, that may have seemed like a very long final phase. The autotargeting was taking us right into a ... crater, with a large number of big boulders and rocks ... and it required ... flying manually over the rock field to find a reasonably good area.
From this day forward, Flight Control will be known by two words: 'Tough' and 'Competent.' Tough means we are forever accountable for what we do or what we fail to do. We will never again compromise our responsibilities. Every time we walk into Mission Control we will know what we stand for. Competent means we will never take anything for granted. We will never be found short in our knowledge and in our skills. Mission Control will be perfect. When you leave this meeting today you will go to your office and the first thing you will do there is to write 'Tough and Competent' on your blackboards. It will never be erased. Each day when you enter the room these words will remind you of the price paid by Grissom, White, and Chaffee. These words are the price of admission to the ranks of Mission Control.
We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.
The surface is fine and powdery. I can kick it up loosely with my toe. It does adhere in fine layers, like powdered charcoal, to the sole and sides of my boots. I only go in a small fraction of an inch, maybe an eighth of an inch, but I can see the footprints of my boots and the treads in the fine, sandy particles. There seems to be no difficult in moving around, as we suspected.
I am a stranger. I come in peace.
Houston, that may have seemed like a very long final phase. The autotargeting was taking us right into a ... crater, with a large number of big boulders and rocks ... and it required ... flying manually over the rock field to find a reasonably good area.
From this day forward, Flight Control will be known by two words: 'Tough' and 'Competent.' Tough means we are forever accountable for what we do or what we fail to do. We will never again compromise our responsibilities. Every time we walk into Mission Control we will know what we stand for. Competent means we will never take anything for granted. We will never be found short in our knowledge and in our skills. Mission Control will be perfect. When you leave this meeting today you will go to your office and the first thing you will do there is to write 'Tough and Competent' on your blackboards. It will never be erased. Each day when you enter the room these words will remind you of the price paid by Grissom, White, and Chaffee. These words are the price of admission to the ranks of Mission Control.
We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.
The surface is fine and powdery. I can kick it up loosely with my toe. It does adhere in fine layers, like powdered charcoal, to the sole and sides of my boots. I only go in a small fraction of an inch, maybe an eighth of an inch, but I can see the footprints of my boots and the treads in the fine, sandy particles. There seems to be no difficult in moving around, as we suspected.
Let's light this fire one more time, Mike, and witness this great nation at its best.
The Earth is the only world known so far to harbor life. There is nowhere else, at least in the near future, to which our species could migrate. Visit, yes. Settle, not yet. Like it or not, for the moment the Earth is where we make our stand.
Text thanks to: Space Ipsum


Why Promises
"Servers can easily use vastly more asynchronous code-paths than a typical client-side application. Between database interactions, file I/O, HTTP requests, child processes [...], and more, server-side JavaScript can quickly become an overwhelming web of callbacks if not approached properly. Promises are a powerful tool in dealing with the complexity of composing various asynchronous actions and managing them in a coherent and encapsulated way, with reasonable flow and error handling. Most client-side modules only begin to venture into the full experience of the complex combinations of serial and parallel actions that can be commonplace on a NodeJS server, and can be smoothly handled by promises.[...]"
How it works...
As Promise Pattern could be challenging to understand without seeing it in action : let's do this directly.
A promise is just a handler where you enqueue some functions that will be executed linearly (chained) :
// normally : you never create a promise as this. // Use Deferred or when(...) in place (see below). // It's just there to show you how it's managed // under scene. var promise = new deep.Promise(); promise .done(function(success){ return success + " world"; }) .fail(function(error){ deep.log("error : ", error); }) .done(function(success){ deep.log("success : ",success); });
If you try this : nothing happens.
That's normal. The promise hasn't launched the execution of its queue. It waits for something to start.
So let's take exactly the same example and add just a sentence :
// normally : you never create a promise as this. // Use Deferred or when(...) in place (see below). // It's just there to show you how it's managed // under the scene. var promise = new deep.Promise(); promise .done(function(success){ return success + " world"; }) .fail(function(error){ deep.log("error : ", error); }) .done(function(success){ deep.log("final success : ",success); }); // normally : you never launch by hand a promise. // use Deferred or when(...) in place (see below). // It's just there to show you how it's managed // under scene. promise.resolve("hello");
Blam... The queue has been executed !
So, what's happened ?
First, you could observe that both "done" have been fired. You could also observe that the value returned by the first done has been seen as success for second done. So callbacks are "wired".
Secondly : the "fail" callback hasn't been fired. It's because for the moment, the value passed through callbacks wasn't an error.
Let's try this :
var promise = new deep.Promise(); promise .done(function(success){ deep.log("success 1 : ", success); return success + " world"; }) .fail(function(error){ deep.log("error : ", error); }) .done(function(success){ deep.log("success 2 : ",success); }); promise.reject(new Error("oups! error!"));
There, only the "fail" has been fired, because the value passed through callbacks was an error.
That's it... You've almost all the painting. A promise is just a queue, where you store callbacks, called linearly and selectively when a success or an error is injected.
If you do so, either you're working on core tools, or you missed something. It was just to show you the class itself (you'll never see it again...;)) and the delayed execution.
In place, you'll use a deep.Deferred or deep.when(...).
deep.Deferred
When you need a Promise, you could first use a Promise Distributor called "Deferred". Let's introducing it with asynchrone example :
var def = deep.Deferred(); setTimeout(function(){ def.resolve("hello from deferred"); }, 1000); def.promise() .done(function(success){ deep.log("success : ", success); }) .fail(function(error){ deep.log("error : ", error); });
var def = deep.Deferred(); setTimeout(function(){ def.reject(new Error("hello from deferred")); }, 1000); def.promise() .done(function(success){ deep.log("success : ", success); }) .fail(function(error){ deep.log("error : ", error); });
Okay.. you got the point with deferred. A deferred is just a "promises distributor" that could be either resolved or rejected. When this arrive, it starts all previously distributed promises with its result as success or error. Nothing more.
deep.when
A second good way to obtain a Promise, is to use "when" function. This simple method takes something as argument and returns a promise :
deep.when("hello") .done(function(success){ deep.log("success : ", success); });
deep.when(new Error("oups!")) .fail(function(error){ deep.log("error : ", error); });
In both examples here, the "when" argument has been directly injected in the returned promise.
The interesting point here is that you could give a promise as "when" argument. (let's introduce a new method ".delay( ms )"" which delays the execution of callbacks after it.)
var promise = deep.when("hello delayed world").delay(500); // async simulation deep.when(promise) .done(function(success){ deep.log("success : ", success); });
There, the "when" function returns a second promise, that's waiting the resolution of the first one before executing its own queue.
The really interesting point here, is that "when" hides difference between sync and async programmation. Either you provide a "synced" value, and the returned promise is executed directly, either you provide a promise (synced or not) and the returned promise wait the first promise before start. In all cases, code still the same.
deep.all(obj1, obj2, ...)
How mentioning "deep.when( obj )" without mentioning its big brother : deep.all(obj1, obj2, ...).
var prom1 = deep.when("first").delay(100); var prom2 = deep.when("second").delay(200); deep.all(prom1, prom2, "third") .done(function(success){ deep.log(success); })
It returns you a single promise that waits for the resolution of all arguments passed. The success injected in returned promise is the array of resolved values. And as you could see, "immediate" values are also managed.
3 famillies and big APIs
Fondamentaly, there is three callback famillies. You already know the two first ones : "done" and "fail". Stills a third one : "always".
- done
- Runs only if current value(s) holded by the promise is not an Error.
- fail
- Runs only if current value(s) holded by the promise is an Error.
- always
- Always runs : the value(s) holded could be anything.
deep.when("hello promise") .always(function(s, e){ deep.log("always : s: ", s, " - e : ", e); }) .done(function(success){ deep.log("done : ", success); }) .fail(function(error){ deep.log("fail : ", error); });
deep.when(new Error("bye bye!")) .always(function(s, e){ deep.log("always : s: ", s, " - e : ", e); }) .done(function(success){ deep.log("done : ", success); }) .fail(function(error){ deep.log("fail : ", error); });
Why is this so important to know now ? Simply because the Promise API has been decorated with lot of methods, and Promise based chains also add their own methods. And the fact is that any method from any chain (Promise or others) belong to one of those famillies.
To explain that, let's introduce 3 logging methods : .log(), .slog(), .elog()
- .log()
- Always familly : will log current chain's success OR error.
- .slog()
- Done familly : will only log current success (if any).
- .elog()
- Fail familly : will only log current error (if any).
Let's take previous example and rewrite it with those new methods :
deep.when("hello promise").log("always : ").slog("done : ").elog("fail : ");
deep.when(new Error("bye bye!")).log("always : ").slog("done : ").elog("fail : ");
So when you'll use methods from any deepjs chain, you should always know its familly. To have an idea, lots are "done", few are "always", and really few are "fail".
The "callbacks return" rules
When you handle a success or an error in a callback (from any of the three famillies), the value returned by your callback is analysed and, depending on its nature, it will be seen as success or error for the next handlers.
It means, by example that you could handle an error in a "fail", return something else that will be seen as success, and then continue normally.
deep.when(new Error("oups!")) .fail(function(error){ return true; // we return something else than the error }) .slog(); // success log (a 'done')
In other words, you've recovered your error.
So, the "callbacks return rules" just say how values are seen depending on there nature.
Nothing (or undefined)
When your callbacks returns nothing (i.e. which is the same undefined), the current "state" of the promise (i.e. its succes or its error) isn't modified.
deep.when("hello") .done(function(s){ // doing nothing }) .log();
An error
When your callbacks returns an error, it become the error holded by the promise.
Remarque it's the same thing when you throw an error.
deep.when("hello") .done(function(s){ return new Error("oups!"); }) .log();
deep.when("hello") .done(function(s){ throw new Error("oups!"); }) .log();
A Promise
When your callbacks returns a promise, the main promise will wait the resolution of the returned one, and then forward its success or error.
deep.when("hello") .done(function(s){ return deep.when("world").delay(1000); }) .log();
A deep.Undefined
When you want to force undefined
injection as success, as by default undefined will be seen as nothing (see above), the way to force it is to return deep.Undefined
.
deep.when("hello") .done(function(s){ return deep.Undefined; }) .log();
Anything else...
Any other type : inject it as success in chain (so if the promise was in 'error' state : it's now in 'success' state)
When your callback returns anything else (any other type than those explained here), this value will be seen as "success".
deep.when("hello") .done(function(s){ return "world"; }) .log();


class: center, middle, inverse, title-slide # Data Science for Economists ## Lecture 1: Introduction ### Grant McDermott ### University of Oregon |
EC 607
---  # Table of contents 1. [Prologue](#prologue) 2. [Syllabus highlights](#syllabus) 3. [Getting started](#started) 4. [R for data science](#r4ds) 5. [Data visualization with ggplot2](#ggplot2) --- class: inverse, center, middle name: prologue # Prologue

 --- # Introductions ### Course <svg style="height:0.8em;top:.04em;position:relative;" viewBox="0 0 496 512"><path d="M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z"/></svg> https://github.com/uo-ec607 You'll soon receive access to a quarter-specific copy of this repo, where we submit assignments, upload presentations, etc. -- ### Me <svg style="height:0.8em;top:.04em;position:relative;" viewBox="0 0 448 512"><path d="M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-228-32c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H118.4C106 384 96 375.4 96 364.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2z"/></svg> [Grant McDermott](https://grantmcdermott.com/) <svg style="height:0.8em;top:.04em;position:relative;" viewBox="0 0 512 512"><path d="M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"/></svg> [grantmcd<EMAIL_ADDRESS><svg style="height:0.8em;top:.04em;position:relative;" viewBox="0 0 640 512"><path d="M622.34 153.2L343.4 67.5c-15.2-4.67-31.6-4.67-46.79 0L17.66 153.2c-23.54 7.23-23.54 38.36 0 45.59l48.63 14.94c-10.67 13.19-17.23 29.28-17.88 46.9C38.78 266.15 32 276.11 32 288c0 10.78 5.68 19.85 13.86 25.65L20.33 428.53C18.11 438.52 25.71 448 35.94 448h56.11c10.24 0 17.84-9.48 15.62-19.47L82.14 313.65C90.32 307.85 96 298.78 96 288c0-11.57-6.47-21.25-15.66-26.87.76-15.02 8.44-28.3 20.69-36.72L296.6 284.5c9.06 2.78 26.44 6.25 46.79 0l278.95-85.7c23.55-7.24 23.55-38.36 0-45.6zM352.79 315.09c-28.53 8.76-52.84 3.92-65.59 0l-145.02-44.55L128 384c0 35.35 85.96 64 192 64s192-28.65 192-64l-14.18-113.47-145.03 44.56z"/></svg> Assistant Professor (environmental economics and data science) -- ### You A quick roundtable of names, fields/interests, and coding background. --- class: inverse, center, middle name: syllabus # Syllabus highlights

 (Read the full document [here](https://github.com/uo-ec607/syllabus/blob/master/syllabus.pdf).) --- # Why this course? Fill in the gaps left by traditional econometrics and methods classes. - Practical skills that tools that will benefit your dissertation and future career. - Neglected skills like how to actually find datasets in the wild and clean them. Data science skills are largely distinct from (and complementary to) the core 'metrics oeuvre familiar to economists. - Data viz, cleaning and wrangling; programming; cloud computation; relational databases; machine learning; etc. -- > *"In short, we will cover things that I wish someone had taught me when I was starting out in graduate school."* --- # You, at the end of this course

 --- # Grading | Component | Weight | |:-|-:| | 4 × homework assignments (20% each) | 80% | | 2 × short presentations (5% each) | 10% | | 1 × OSS contribution | 10% | - You can swap out one homework assignment for an (approved) final presentation of your own research. - [Short presentations](https://github.com/uo-ec607/presentations) summarize either a key lecture reading, or an (approved) software package/platform. - We'll get to OSS contribution later in the course, but I particularly encourage contributions to [LOST](lost-stats.github.io/). --
 PS — I'll also award a class participation bonus (2.5%) at my discretion. --- # Lecture outline ### Data science basics - Introduction: Motivation, software installation, and data visualization - Version control with Git(Hub) - Learning to love the shell - R language basics - Data cleaning and wrangling: 1) tidyverse and 2) data.table - Webscraping: (1) Server-side and CSS - Webscraping: (2) Client-side and APIs ### Analysis and programming - Regression analysis in R - Spatial analysis in R - Functions in R: (1) Introductory concepts - Functions in R: (2) Advanced concepts - Parallel programming --- # Lecture outline (cont.) ### Scaling up: Big data and cloud computation - Docker - Cloud computing with Google Compute Engine - High performance computing (Talapas cluster) - Databases: SQL(ite) and BigQuery - Spark - **Options** - Project workflow and automation - Machine learning - Peer-review and student project presentations (demand dependent) --- class: inverse, center, middle name: started # Getting started

 --- # Software installation and registration 1. Download [R](https://www.r-project.org/). 2. Download [RStudio](https://www.rstudio.com/products/rstudio/download/preview/). 3. Download [Git](https://git-scm.com/downloads). 4. Create an account on [GitHub](https://github.com/) and register for a student/educator [discount](https://education.github.com/discount_requests/new). - You will soon receive an invitation to the quarter-specific course org. on GitHub, as well as [GitHub classroom](https://classroom.github.com), which is how we'll disseminate and submit assignments, receive feedback and grading, etc. -- If you had trouble completing any of these steps, please raise your hand. - My go-to place for installation guidance and troubleshooting is Jenny Bryan's http://happygitwithr.com. --- # Some OS-specific extras I'll detail further software requirements as and when the need arises. However, to help smooth some software installation issues further down the road, please also do the following (depending on your OS): - **Windows:** Install [Rtools](https://cran.r-project.org/bin/windows/Rtools/). I also recommend that you install [Chocolately](https://chocolatey.org/). - **Mac:** Install [Homebrew](https://brew.sh/). I also recommend that you configure/open your C++ toolchain (see [here](https://github.com/rmacoslib/r-macos-rtools#installer-package-for-macos-r-toolchain-).) - **Linux:** None (you should be good to go). --- # Checklist ☑ Do you have the most recent version of R? ```r version$version.string ``` ``` ## [1] "R version 4.0.4 (2021-02-15)" ``` ☑ Do you have the most recent version of RStudio? (The [preview version](https://www.rstudio.com/products/rstudio/download/preview/) is fine.) ```r RStudio.Version()$version ## Requires an interactive session but should return something like "[1] ‘1.4.1100’" ``` ☑ Have you updated all of your R packages? ```r update.packages(ask = FALSE, checkBuilt = TRUE) ``` --- # Checklist (cont.) Open up the [shell](http://happygitwithr.com/shell.html#shell). - Windows users, make sure that you installed a Bash-compatible version of the shell. If you installed [Git for Windows](https://gitforwindows.org), then you should be good to go. ☑ Which version of Git have you installed? ```bash git --version ``` ``` ## git version 2.30.1 ``` ☑ Did you introduce yourself to Git? (Substitute in your details.) ```bash git config --global user.name 'Grant McDermott' git config --global user.email<EMAIL_ADDRESS>git config --global --list ``` ☑ Did you register an account in GitHub? --- # Checklist (cont.) We will make sure that everything is working properly with your R and GitHub setup next lecture. For the rest of today's lecture, I want to go over some very basic R concepts. --
 PS — Just so you know where we're headed: We'll return to these R concepts (and delve much deeper) next week after a brief, but important detour to the lands of Git(Hub) and the shell. - Don't worry, it will all make sense. You'll see. --- class: inverse, center, middle name: r4ds # R for data science

 --- name: whyr # Why R and RStudio? (cont.)  --- # Why R and RStudio? (cont.) ### Data science positivism - Alongside Python, R has become the *de facto* language for data science. - See: [*The Impressive Growth of R*](https://stackoverflow.blog/2017/10/10/impressive-growth-r/), [*The Popularity of Data Science Software*](http://r4stats.com/articles/popularity/) - Open-source (free!) with a global user-base spanning academia and industry. - "Do you want to be a profit source or a cost center?" ### Bridge to applied economics and other tools - Already has all of the statistics and econometrics support, and is amazingly adaptable as a “glue” language to other programming languages and APIs. - The RStudio IDE and ecosystem allow for further, seemless integration. ### Path dependency - It's also the language that I know best. -- - (Learning multiple languages is a good idea, though.) --- # Some R basics 1. Everything is an object. 2. Everything has a name. 3. You do things using functions. 4. Functions come pre-written in packages (i.e. "libraries"), although you can — and should — write your own functions too. --
 Points 1. and 2. can be summarised as an [object-orientated programming](https://en.wikipedia.org/wiki/Object-oriented_programming) (OOP) approach. - This may sound super abstract now, but we'll see *lots* of examples over the coming weeks that will make things clear. --- # R vs Stata If you're coming from Stata, some additional things worth emphasizing: - Multiple objects (e.g. data frames) can exist happily in the same workspace. - No more `keep`, `preserve`, `restore` hackery. (Though, props to [Stata 16](https://www.stata.com/new-in-stata/multiple-datasets-in-memory/).) - This is a direct consequence of the OOP approach. - You will load packages at the start of every new R session. Make peace with this. - "Base" R comes with tons of useful in-built functions. It also provides all the tools necessary for you to write your own functions. - However, many of R's best data science functions and tools come from external packages written by other users. - R easily and infinitely parallelizes. For free. - Compare the cost of a [Stata/MP](https://www.stata.com/statamp/) license, nevermind the fact that you effectively pay per core... - You don't need to `tset or xtset` your data. (Although you can too.) --- # R code example (linear regression) ```r fit = lm(mpg ~ wt, data = mtcars) summary(fit) ``` ``` ## ## Call: ## lm(formula = mpg ~ wt, data = mtcars) ## ## Residuals: ## Min 1Q Median 3Q Max ## -4.5432 -2.3647 -0.1252 1.4096 6.8727 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 37.2851 1.8776 19.858 < 2e-16 *** ## wt -5.3445 0.5591 -9.559 1.29e-10 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 3.046 on 30 degrees of freedom ## Multiple R-squared: 0.7528, Adjusted R-squared: 0.7446 ## F-statistic: 91.38 on 1 and 30 DF, p-value: 1.294e-10 ``` --- # Base R plot ```r par(mar = c(4, 4, 1, .1)) ## Just for nice plot margins on this slide deck plot(mtcars$wt, mtcars$mpg) abline(fit, col = "red") ```  --- # ggplot2 ```r library(ggplot2) ggplot(data = mtcars, aes(x = wt, y = mpg)) + geom_smooth(method = "lm", col = "red") + geom_point() ```  --- class: inverse, center, middle name: ggplot2 # More ggplot2

 --- # Install and load Open up your laptops. For the remainder of this first lecture, we're going continue playing around with [ggplot2](https://ggplot2.tidyverse.org/) (i.e. livecoding). If you don't have them already, install the `ggplot2` and `gapminder` packages via either: - **Console:** Enter `install.packages(c("ggplot2", "gapminder"), dependencies=T)`. - **RStudio:** Click the "Packages" tab in the bottom-right window pane. Then click "Install" and search for these two packages. ![](pics/install.gif) --- # Install and load (cont.) Once the packages are installed, load them into your R session with the `library()` function. ```r library(ggplot2) library(gapminder) ## We're just using this package for the gapminder data ``` Notice too that you don't need quotes around the package names any more. Reason: R now recognises these packages as defined objects with given names. ("Everything in R is an object and everything has a name.") -- PS — A convenient way to combine the package installation and loading steps is with the [pacman package's](https://github.com/trinker/pacman) `p_load()` function. If you run `pacman::p_load(ggplot, gapminder)` it will first look to see whether it needs to install either package before loading them. Clever. - We'll get to this next week, but if you want to run a function from an (installed) package without loading it, you can use the `PACKAGE::package_function()` syntax. --- # Brief aside: The gapminder dataset Because we're going to be plotting the [gapminder](https://github.com/jennybc/gapminder) dataset, it is helpful to know that it contains panel data on life expectancy, population size, and GDP per capita for 142 countries since the 1950s. ```r gapminder ``` ``` ## # A tibble: 1,704 x 6 ## country continent year lifeExp pop gdpPercap ## <fct> <fct> <int> <dbl> <int> <dbl> ## 1 Afghanistan Asia 1952 28.8 8425333 779. ## 2 Afghanistan Asia 1957 30.3 9240934 821. ## 3 Afghanistan Asia 1962 32.0 10267083 853. ## 4 Afghanistan Asia 1967 34.0 11537966 836. ## 5 Afghanistan Asia 1972 36.1 13079460 740. ## 6 Afghanistan Asia 1977 38.4 14880372 786. ## 7 Afghanistan Asia 1982 39.9 12881816 978. ## 8 Afghanistan Asia 1987 40.8 13867957 852. ## 9 Afghanistan Asia 1992 41.7 16317921 649. ## 10 Afghanistan Asia 1997 41.8 22227415 635. ## # … with 1,694 more rows ``` --- # Elements of ggplot2 [Hadley Wickham's](http://hadley.nz/) ggplot2 is one of the most popular packages in the entire R canon. - It also happens to be built upon some deep visualization theory: i.e. Leland Wilkinson's [*The Grammar of Graphics*](https://www.amazon.com/Grammar-Graphics-Statistics-Computing/dp/0387245448). There's a lot to say about ggplot2's implementation of this "grammar of graphics" approach, but the three key elements are: 1. Your plot ("the visualization") is linked to your variables ("the data") through various **aesthetic mappings**. 2. Once the aesthetic mappings are defined, you can represent your data in different ways by choosing different **geoms** (i.e. "geometric objects" like points, lines or bars). 3. You build your plot in **layers**. --
 That's kind of abstract. Let's review each element in turn with some actual plots. --- # 1. Aesthetic mappings ```r ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) + geom_point() ```  --- # 1. Aesthetic mappings (cont.) ```r ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) + geom_point() ``` Focus on the top line, which contains the initialising `ggplot()` function call. This function accepts various arguments, including: - Where the data come from (i.e. `data = gapminder`). - What the aesthetic mappings are (i.e. `mapping = aes(x = gdpPercap, y = lifeExp)`). -- The aesthetic mappings here are pretty simple: They just define an x-axis (GDP per capita) and a y-axis (life expecancy). - To get a sense of the power and flexibility that comes with this approach, however, consider what happens if we add more aesthetics to the plot call... --- # 1. Aesthetic mappings (cont.) ```r ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp, size = pop, col = continent)) + geom_point(alpha = 0.3) ## "alpha" controls transparency. Takes a value between 0 and 1. ```  -- Note that I've dropped the "mapping =" part of the ggplot call. Most people just start with "aes(...)", since `ggplot2` knows the order of the arguments. --- # 1. Aesthetic mappings (cont.) We can specify aesthetic mappings in the geom layer too. ```r ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) + ## Applicable to all geoms geom_point(aes(size = pop, col = continent), alpha = 0.3) ## Applicable to this geom only ```  --- # 1. Aesthetic mappings (cont.) Oops. What went wrong here? ```r ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) + geom_point(aes(size = "big", col="black"), alpha = 0.3) ```  -- **Answer: **Aesthetics must be mapped to variables, not descriptions! --- # 1. Aesthetic mappings (cont.) At this point, instead of repeating the same ggplot2 call every time, it will prove convenient to define an intermediate plot object that we can re-use. ```r p = ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) p ```  --- # 2. Geoms Once your variable relationships have been defined by the aesthetic mappings, you can invoke and combine different geoms to generate different visulaizations. ```r p + geom_point(alpha = 0.3) + geom_smooth(method = "loess") ```  --- # 2. Geoms (cont.) Aesthetics can be applied differentially across geoms. ```r p + geom_point(aes(size = pop, col = continent), alpha = 0.3) + geom_smooth(method = "loess") ```  --- # 2. Geoms (cont.) The previous plot provides a good illustration of the power (or effect) that comes from assigning aesthetic mappings "globally" vs in the individual geom layers. - Compare: What happens if you run the below code chunk? ```r ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp, size = pop, col = continent)) + geom_point(alpha = 0.3) + geom_smooth(method = "loess") ``` --- # 2. Geoms (cont.) Similarly, note that some geoms only accept a subset of mappings. E.g. `geom_density()` doesn't know what to do with the "y" aesthetic mapping. ```r p + geom_density() ``` ``` ## Error: geom_density requires the following missing aesthetics: y ```  --- # 2. Geoms (cont.) We can fix that by being more careful about how we build the plot. ```r ggplot(data = gapminder) + ## i.e. No "global" aesthetic mappings" geom_density(aes(x = gdpPercap, fill = continent), alpha=0.3) ```  --- # 3. Build your plot in layers We've already seen how we can chain (or "layer") consecutive plot elements using the `+` connector. - The fact that we can create and then re-use an intermediate plot object (e.g. "p") is testament to this. But it bears repeating: You can build out some truly impressive complexity and transformation of your visualization through this simple layering process. - You don't have to transform your original data; ggplot2 takes care of all of that. - For example (see next slide for figure). ```r p2 = p + geom_point(aes(size = pop, col = continent), alpha = 0.3) + scale_color_brewer(name = "Continent", palette = "Set1") + ## Different colour scale scale_size(name = "Population", labels = scales::comma) + ## Different point (i.e. legend) scale scale_x_log10(labels = scales::dollar) + ## Switch to logarithmic scale on x-axis. Use dollar units. labs(x = "Log (GDP per capita)", y = "Life Expectancy") + ## Better axis titles theme_minimal() ## Try a minimal (b&w) plot theme ``` --- # 3. Build your plot in layers (cont.)  --- # What else? We have barely scratched the surface of ggplot2's functionality... let alone talked about the entire ecosystem of packages that has been built around it. - Here's are two quick additional examples to whet your appetite -- Note that you will need to install and load some additional packages if you want to recreate the next two figures on your own machine. A quick way to do this: ```r if (!require("pacman")) install.packages("pacman") pacman::p_load(hrbrthemes, gganimate) ``` --- # What else? (cont.) Simple extension: Use an external package theme. ```r # library(hrbrthemes) p2 + theme_modern_rc() + geom_point(aes(size = pop, col = continent), alpha = 0.2) ```  --- # What else? (cont.) Elaborate extension: Animation! (See the next slide for the resulting GIF.) ```r # library(gganimate) ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, colour = country)) + geom_point(alpha = 0.7, show.legend = FALSE) + scale_colour_manual(values = country_colors) + scale_size(range = c(2, 12)) + scale_x_log10() + facet_wrap(~continent) + # Here comes the gganimate specific bits labs(title = 'Year: {frame_time}', x = 'GDP per capita', y = 'life expectancy') + transition_time(year) + ease_aes('linear') ``` --- # What else? (cont.)  -- Note that this animated plot provides a much more intuitive understanding of the underlying data. Just as [Hans Rosling](https://www.ted.com/talks/hans_rosling_the_best_stats_you_ve_ever_seen) intended. --- # What else? (cont.) There's a lot more to say, but I think we'll stop now for today's lecture. We also haven't touched on ggplot2's relationship to "tidy" data. - It actually forms part of a suite of packages collectively known as the [tidyverse](https://www.tidyverse.org/). - We will get back to this in Lecture 5. Rest assured, you will be using ggplot2 throughout the rest of this course and developing your skills along the way. - Your very first assignment (coming up) is a chance specifically to hone some of those skills. In the meantime, I want you to do some reading and practice on your own. Pick either of the following (or choose among the litany of online resources) and work through their examples: - [Chapter 3](https://r4ds.had.co.nz/data-visualisation.html) of *R for Data Science* by Hadley Wickham and Garett Grolemund. - [*Data Visualization: A Practical Guide*](https://socviz.co/makeplot.html) by Kieran Healy. - [Designing ggplots](https://designing-ggplots.netlify.com) by Malcom Barrett. --- class: inverse, center, middle # Next lecture: Deep dive into Git(Hub).


GUIWidgets
GUIWidget is the base class for everything in bbq that has a visual representation and as such is a class that you will become well acquainted with.
A simple class that extends GUIWidget is shown below:
include(bbq.gui.GUIWidget);
com.myapp.gui.MyWidget = new Class.create(bbq.gui.GUIWidget, {
initialize: function($super) {
$super();
this.setRootNode("p");
this.addClass("MyWidget");
},
render: function($super) {
this.empty();
this.appendChild("hello world");
}
});
To add an instance of the class to a page, you'd do the following:
include(bbq.page.Page);
include(com.myapp.gui.MyWidget);
com.myapp.page.Home = new Class.create(bbq.page.Page, {
initialize: function($super) {
$super();
var widget = new com.myapp.gui.MyWidget();
widget.appendTo(document.body);
}
});
This results in the following being added to the body tag of the document:

hello world

Root node
Each GUIWidget has a root node. By default it's a div tag, but this behaviour can be overridden by calling the GUIWidget#setRootNode) method and passing in the name of the tag you'd like to have set:
include(bbq.gui.GUIWidget);
com.myapp.gui.MyWidget = new Class.create(bbq.gui.GUIWidget, {
initialize: function($super) {
$super();
// sets the root node to a paragraph tag
this.setRootNode("p");
// sets the root node to an article
this.setRootNode("article");
}
});
appendTo/appendChild
A GUIWidget is a JavaScript Object, whereas the output of document.createElement
is a Node. A very important distinction here is that the GUIWidget wraps a Node, so we can write code to add one GUIWidget to another, or even a Node to a GUIWidget, but we cannot add a GUIWidget to a node.
So, for example:
var widget = new com.myapp.gui.MyWidget();
var node = document.createElement("p");
// will not work
node.appendChild(widget);
Instead, we must use appendTo:
var widget = new com.myapp.gui.MyWidget();
var node = document.createElement("p");
// will work
widget.appendTo(node);
We can freely add objects of both types to widgets, however:
var parentWidget = new com.myapp.gui.MyWidget();
var childWidget = new com.myapp.gui.MyWidget();
var node = document.createElement("p");
// add a Node
parentWidget.appendChild(node);
// add a GUIWidget
parentWidget.appendChild(childWidget);
It would be nice if we could override Node#appendChild to detect GUIWidgets and act accordingly but the security model of most browsers prevents this.
Render
The render method is the point at which your GUIWidget should add and child widgets to it's root node. It's likely to get call several times during the life of the widget, so it's recommended to first call empty to insure you don't end up with more child nodes than you expected.
Render may be called before your GUIWidget has been added to the DOM so please do not assume the existence of anything else on the page, or even that your root node has a parentNode.
include(bbq.gui.GUIWidget);
include(bbq.gui.button.Button);
include(bbq.util.Log);
com.myapp.gui.MyWidget = new Class.create(bbq.gui.GUIWidget, {
initialize: function($super) {
$super();
},
render: function() {
// removes all existing child nodes
this.empty();
// Adds a paragraph tag with the text "Hello world!"
this.appendChild(DOMUtil.createElement("p", "Hello world!"));
// Adds a clickable button
this.appendChild(new bbq.gui.button.Button({
text: "Click me",
onClick: this._buttonClicked.bind(this)
}));
},
_buttonClicked: function() {
Log.info("The button was clicked!");
}
});
See the JSDocs for more information.
Root node manipulation
Several methods operate on the root node, some common ones are listed below, but for the full list, please see the JSDocs.
addClass
GUIWidget#addClass adds a CSS class to the root node:
var widget = new com.myapp.gui.MyWidget();
widget.addClass("foo");
This will result in the following HTML:

removeClass
GUIWidget#removeClass removes a CSS class to the root node:
var widget = new com.myapp.gui.MyWidget();
widget.addClass("foo");
widget.addClass("bar");
widget.removeClass("foo");
This will result in the following HTML:

hasClass
GUIWidget#hasClass returns true if the root node has the passed CSS class:
var widget = new com.myapp.gui.MyWidget();
widget.addClass("foo");
// false
widget.hasClass("bar");
// true
widget.hasClass("foo");
This will result in the following HTML:

setStyle/getStyle
GUIWidget#setStyle sets a CSS style on the root node and GUIWidget#getStyle) returns it:
var widget = new com.myapp.gui.MyWidget();
widget.setStyle("position", "absolute");
// returns "absolute"
widget.getStyle("position");
This will result in the following HTML:

To remove a class, pass in null:
var widget = new com.myapp.gui.MyWidget();
widget.setStyle("position", null);
// returns null
widget.getStyle("position");


Some Requirements Have Not Been Met.
{% if missing_batteries %}
The following batteries need to be completed before the current one may be attempted:
{% for battery in missing_batteries %}
-
{{ battery.name }}
{% endfor %}
{% endif %}
{% if blocking_batteries %}
The following batteries conflict with the current battery. Their completion is preventing the current battery from being attempted:
{% for battery in blocking_batteries %}
-
{{ battery.name }}
{% endfor %}
{% endif %}


#include "_doctype.html"
#define FLAWNAME libcurl cookie leak with IP address as domain
cURL - FLAWNAME
#include "css.t"
#include "manpage.t"
#define CURL_DOCS
#define CURL_URL docs/adv_20140326A.html
#include "_menu.html"
#include "setup.t"
WHERE3(Docs, "/docs/", Security, "/docs/security.html",
FLAWNAME)
TITLE(FLAWNAME)
#include "adv-related-box.inc"
#include "adv_20140910A.t"
#include "_footer.html"


FarmGuide overlayer of farm segments
Click to load Map
Add farm segements for 10 villages
Add farm information
Add legend for farm distribution


| Apache Struts 2 Documentation > Home > Guides > Plugin Developers Guide > Struts 1 Plugin |
The Struts 1 plugin allows you to use existing Struts 1 Actions and ActionForms in Struts 2 applications.
This plugin provides a generic Struts 2 Action class to wrap an existing Struts 1 Action, org.apache.struts2.s1.Struts1Action. The wrapper class provides the expected calls to the legacy Struts 1 Action and ActionForm, converting incoming and outgoing objects into the expected forms. It works by using the scoped model driven technique that uses a single Object as the model for every page, very similar to how the Struts 1 ActionForm works. The plugin also provides several interceptors to emulate Struts 1 logic:
To use existing Struts 1 Actions and ActionForms in a Struts 2 application, create a normal Struts 2 configuration package in struts.xml, but have it extend struts1-default. The struts1-default package contains several interceptors and a default interceptor stack that work the plugin into the Struts 2 request process.
In the most simple case, where you have a Struts 1 Action that you want to use in Struts 2, configure a Struts 2 action using the wrapper:
<action name="myAction" class="org.apache.struts2.s1.Struts1Action"> <param name="className">com.mycompany.myapp.MyAction</param> <result>myAction.jsp</result> </action>
Most likely, you will have an ActionForm that your Struts 1 Action expects. To use an ActionForm, the setup is a little more complicated because you'll need an interceptor that manages the creation and scope (to support request and session scoping like Struts 1) of the ActionForm.
<action name="myFormAction" class="org.apache.struts2.s1.Struts1Action"> <param name="className">com.mycompany.myapp.MyAction</param> <interceptor name="myForm" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"> <param name="className">com.mycompany.myapp.MyForm</param> <param name="name">gangsterForm</param> <param name="scope">session</param> </interceptor> <interceptor-ref name="struts1-default" /> <result>myAction.jsp</result> </action>
This example shows a few Struts 1 Actions, a session-scoped ActionForm, and validation that uses Commons Validator:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="integration" extends="struts1-default" namespace="/integration"> <interceptors> <interceptor name="gangsterForm" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"> <param name="className">org.apache.struts2.showcase.integration.GangsterForm</param> <param name="name">gangsterForm</param> </interceptor> <interceptor name="gangsterValidation" class="org.apache.struts2.s1.ActionFormValidationInterceptor"> <param name="pathnames">/org/apache/struts/validator/validator-rules.xml,/WEB-INF/validation.xml</param> </interceptor> <interceptor-stack name="integration"> <interceptor-ref name="static-params"/> <interceptor-ref name="gangsterForm"/> <interceptor-ref name="model-driven"/> <interceptor-ref name="actionForm-reset"/> <interceptor-ref name="basicStack"/> <interceptor-ref name="gangsterValidation"/> <interceptor-ref name="workflow"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="integration" /> <default-action-ref name="editGangster" /> <!-- Diplay entry page that uses Model-Driven technique --> <action name="editGangster" class="org.apache.struts2.s1.Struts1Action"> <param name="className">org.apache.struts2.showcase.integration.EditGangsterAction</param> <result>modelDriven.jsp</result> </action> <!-- Display the result page whose content is populated using the Model-Driven technique --> <action name="saveGangster" class="org.apache.struts2.s1.Struts1Action"> <param name="className">org.apache.struts2.showcase.integration.SaveGangsterAction</param> <param name="validate">true</param> <result name="input">modelDriven.jsp</result> <result>modelDrivenResult.jsp</result> </action> </package> </struts>
This plugin doesn't support any global settings.
This plugin can be installed by copying the plugin jar into your application's /WEB-INF/lib directory. It will need the Struts 1 jar in order to function correctly.