He cannot see beyond his own nose. Even the fingers he out-stretches from it to the world are (as I shall suggest) often invisible to him.
— Max Beerbohm (1872–1956), of George Bernard Shaw
Time to say what “in scope” means. This definition is one of the most important rules of play, because it decides what the player is allowed to refer to. You can investigate this experimentally by compiling any game with the debugging suite of verbs included (see §7) and typing “scope” in interesting places. “In scope” roughly means “the compass directions, what you're carrying and what you can see”. It exactly means this:
thedark
(by default there are no such contents, but
some designers have been known to move objects into thedark
:
see ‘Ruins’);container
, then that
container;with the proviso that the InScope
entry
point (see below) can add to or replace these rules, if you write one.
It's significant that rule (3) doesn't just say “whatever is in the current location”. For instance, if the player is in a closed cupboard in the Stores Room, then rule (3) means that the contents of the cupboard are in scope, but other items in the Stores Room are not.
Even in darkness the player's possessions are in scope, so the player can still turn on a lamp being carried. On the other hand, a player who puts the lamp on the ground and turns it off then loses the ability to turn it back on again, because it is out of scope. This can be changed; see below.
▲ Compass directions make sense as things as well as directions, and they respond to names like “the south wall” and “the floor” as well as “south” and “down”.
▲
The concealed
attribute only hides objects from room
descriptions, and doesn't remove them from scope. If you want things
to be unreferrable-to, put them somewhere else!
▲
The small print: 1. For “player”, read “actor”.
Thus “dwarf, drop sword” will be accepted if the dwarf can
see the sword even if the player can't. 2. Scope varies depending on
the token being parsed: for the multi-
tokens, compass directions are not in scope; for
multiexcept
the other
object isn't in scope; for multiinside
only the contents of the other object are in scope.
· · · · ·
Two library routines enable you to see what's in scope
and what isn't. The first, TestScope(obj, actor)
, simply
returns true
or false
according to whether
or not obj
is in scope. The second is
LoopOverScope(routine, actor)
and calls the given routine
for each object in scope. In each case the actor
given
is optional, and if it's omitted, scope is worked out for the player
as usual.
•
EXERCISE 97
Implement the debugging suite's “scope” verb, which lists
all the objects currently in scope.
•
EXERCISE 98
Write a “megalook” verb, which looks around and examines
everything in scope except the walls, floor and ceiling.
· · · · ·
Formally, scope determines what you can talk about,
which usually means what you can see or hear. But what can you touch?
Suppose a locked chest is inside a sealed glass cabinet. The Inform parser
will allow the command “unlock chest with key” and generate
the appropriate action, <Unlock chest key>
,
because the chest is in scope, so the command at least makes sense.
But it's impossible to carry out, because the player
can't reach through the solid glass. So the library's routine for handling
the Unlock
action needs to enforce this. The library does
this using a stricter rule called “touchability”. The
rule is that you can touch anything in scope unless there's a closed
container
between you and it. This applies either if
you're in the container, or if it is.
Some purely visual actions, such as Examine
or LookUnder
, don't require touchability. But most actions
are tactile, and so are many actions created by designers. If you
want to make your own action routines enforce touchability, you can
call the library routine ObjectIsUntouchable(obj)
. This
either returns false
and prints nothing if there's no
problem in touching obj
, or
returns true
and
prints a suitable message, such as “The solid glass cabinet is
in the way.” Thus, the first line of many of the library's
action routines is:
if (ObjectIsUntouchable(noun)) return;
You can also call ObjectIsUntouchable(obj, true)
to simply return true
or false
, printing nothing,
if you'd rather provide your own failure message.
· · · · ·
The rest of this section is about how to change the scope rules. As usual with Inform, you can change them globally, but it's more efficient and safer to work locally. To take a typical example: how do we allow the player to ask questions like the traditional “what is a grue”? The “grue” part ought to be parsed as if it were a noun, so that we could distinguish between, say, a “garden grue” and a “wild grue”. So it isn't good enough to look only at a single word. Here is one solution:
[ QuerySub; noun.description(); return; ]; [ QueryTopic; switch (scope_stage) { 1: rfalse; 2: ScopeWithin(questions); rtrue; 3: "At the moment, even the simplest questions confuse you."; } ]; Object questions;
where the actual questions at any time are the current
children of the questions
object, like so:
Object -> "long count" with name 'long' 'count', description "The Long Count is the great Mayan cycle of time, which began in 3114 BC and will finish with the world's end in 2012 AD.";
(which might be helpful in ‘Ruins’) and we also have a grammar line:
Verb 'what' * 'is'/'was' scope=QueryTopic -> Query;
The individual questions have short names so that
the parser might be able to say “Which do you mean, the long count
or the short count?” if the player asked “what is the
count”. (As it stands this won't recognise “what is the
count?”. Conventionally players are supposed not to type question
marks or quotes in their commands. To allow this one could always add
'count?'
as one of the names above.)
· · · · ·
Here is the specification. When the parser reaches
scope=Whatever
, it
calls the Whatever
routine with the variable scope_stage
set to 1. The routine should return true
if it is prepared
to allow multiple objects to be accepted here, and false
otherwise. (In the example, as we don't want “what is
everything” to list all the questions and answers in the game,
we return false
.)
A little later the parser calls Whatever
again with scope_stage
now set to 2. Whatever
is then obliged to tell the parser which objects are to be in scope.
It can call two parser routines to do this:
ScopeWithin(obj)
which puts everything inside obj
, but
not obj
itself, into scope, and then works through rules
(6) and (7) above, so that it may continue to add the contents of
the contents, and so on; and
PlaceInScope(obj)
which puts just obj
into scope. It is
perfectly legal to declare something in scope that “would have been
in scope anyway”: or something which is in a different room
altogether from the actor concerned, say at the other end of a
telephone line. The scope routine Whatever
should then
return false
if the nominated items are additional to the
usual scope, or true
if they are the only items in scope.
(In the example, QueryTopic
returns true
because
it wants the only items in scope to be its question topics, not the
usual miscellany near the player.)
This is fine if the token is correctly parsed. If
not, the parser may choose to ask the token routine to print a suitable
error message, by calling Whatever
with scope_stage
set to 3. (In the example, this will happen if the player types
“what is the lgon count”, and QueryTopic
replies “At the moment, even the simplest questions confuse you.”,
because it comes from a faintly dream-like game called ‘Balances’.)
•
EXERCISE 99
Write a token which puts everything in scope, so that you could have
a debugging “purloin” which could take anything, regardless
of where it was and the rules applying to it.
· · · · ·
▲
The global scope rules can be tampered with by providing an entry
point routine called InScope(actor)
, where actor
is the actor whose scope is worked out. In effect, this defines
the “ordinary” scope by making calls to ScopeWithin
and PlaceInScope
, then returning true
or
false
, exactly as if it were a scope token at stage 2.
For instance, here as promised is how to change the rule that “things
you've just dropped disappear in the dark”:
[ InScope person i; if (person == player && location == thedark) objectloop (i in parent(player)) if (i has moved) PlaceInScope(i); rfalse; ];
With this routine added, objects near the player in a dark room are in scope only if they have moved (that is, have been held by the player in the past), and even then are in scope only to the player, not to anyone else.
▲
The token scope=
‹Routine›
takes precedence over InScope
, which will only be reached
if the routine returns false
to signify “carry on”.
▲▲
There are seven reasons why InScope
might be being called;
the scope_reason
variable is set to the current one:
PARSING_REASON
action_to_be
holds
NULL
in the early stages (before the verb has been decided)
and later on the action which would result from a successful match.TALKING_REASON
EACHTURN_REASON
each_turn
routines for anything nearby,
at the end of each turn.REACT_BEFORE_REASON
react_before
.REACT_AFTER_REASON
react_after
.TESTSCOPE_REASON
TestScope
.LOOPOVERSCOPE_REASON
LoopOverScope
.•▲▲
EXERCISE 100
Construct a long room divided by a glass window. Room descriptions on
either side should describe what's in view on the other; the window
should be possible to look through; objects on the far side should
be in scope, but not manipulable.
•▲▲
EXERCISE 101
Code the following puzzle. In an initially dark room there is a light
switch. Provided you've seen the switch at some time in the past, you
can turn it on and off – but before you've ever seen it, you
can't. Inside the room is nothing you can see, but you can hear the
distinctive sound of a dwarf breathing. If you tell this dwarf to turn
the light on, he will.
· · · · ·
Each object has the ability to drag other objects into
scope whenever it is in scope. This is especially useful for giving
objects component parts: e.g., giving a washing-machine a temperature
dial. (The dial can't be a child object because that would throw it
in with the clothes: and it ought to be attached to the machine
in case the machine is moved from place to place.) For this purpose,
the property add_to_scope
may contain a list of objects
to add.
▲
Alternatively, it may contain a routine. This routine can then call
AddToScope(x)
to add any object x
to scope.
It may not, however, call ScopeWithin
or any other scoping
routines.
▲▲
Scope addition does not occur for an object moved into scope
by an explicit call to PlaceInScope
, since this must
allow complete freedom in scope selections. But it does happen when
objects are moved in scope by calls to ScopeWithin(domain)
.
•
EXERCISE 102
(From the tiny example game ‘A Nasal Twinge’.) Give the
player a nose, which is always in scope and can be held, reducing
the player's carrying capacity.
•
EXERCISE 103
(Likewise.) Create a portable sterilising machine, with a “go”
button, a top which things can be put on and an inside to hold objects
for sterilisation. Thus it is a container, a supporter and a possessor
of sub-objects all at once.
•▲▲
EXERCISE 104
Create a red sticky label which the player can affix to any object in
the game. (Hint: use InScope
, not add_to_scope
.)
•
REFERENCES
‘Balances’ uses scope =
‹routine›
tokens for legible spells and memorised spells.
•Jesse Burneko's library extension
"Info.h" is a helpful model to follow: using a
simple scope token, it allows for “consult” and “ask”
commands to access topics which are provided as objects.
•See also the exercises at the
end of §18 for further scope trickery.
•Similarly, L. Ross Raszewski's
"whatis.h" (adapted to Inform 6 by Andrew C. Murie)
and David Cornelson's "whowhat.h" field questions
such as “what is…” and “who is…”.


You should send these to team@
hope you feel better!
Morning!
I'm coughing up a post-pneumonia storm this morning, going to see if I can get a doctor's appt. in the AM and then potentially come in after lunch. My body might just need a day of rest after all that travel.
Not sure if WFH is a message to email team@ or post on slack in 'general' - lmk what works best.
Andrea


Exercises
Remark
You will able to prove formally your programs are correct soon.
For now, it could be useful to write some tests for each function you define.
You may use the command Compute:
Compute fact 5.
(** expected result :
= 120 : Z
*)
Another possibility is to include some lemmas of the following form:
Example test_fact : fact 5 = 120.
Proof. reflexivity. Qed.
If your function is buggy and does not return the expected result, the compilation of your file will fail.
Errata
- Page 24: section <IP_ADDRESS>:
In the sentence "In the second example, the function Zplus expects an integer..." the word Zplus should be replaced by Zmult.
- Page 42:
The two occurrences of Z_fun_to_nat_fun must be replaced by
nat_fun_to_Z_fun


Court verdict exposes Khawaja Asif's lie in NA: Fawad Chaudhry
by https://www.facebook.com/dunyanewsISLAMABAD (Dunya News) – Federal Minister for Science and Technology Fawad Chaudhry has on Friday said paragraph number two of the court order exposes Pakistan Muslim League-Nawaz (PML-N) leader Khawaja Asif’s lie that he told in the National Assembly.
Fawad Chaudhry took to Twitter and maintained that Khawaja Asif Thursday said on the floor of the House that law officer remarked let him (Nawaz Sharif) die. The federal minister was surprised that how people blatantly lie in the NA.
The Pakistan Tehreek-e-Insaf (PTI) leader also shared paragraph number two of the court order which states:
“We are also satisfied after hearing the nominated representatives of the Chief Minister, Punjab and the Prime Minister of Pakistan that they also have no objection if interim bail till 29-10-2019, is granted.”


Galaxie is not like any other game server rental service - it's built around the user's needs. With built-in integration to many popular services like Twitch and Discord, this software help you setup your own server with many tools for your setup.
No knowledge of setting up a service is required. The software will guide you through every step, with optional advanced settings for experienced users.
Open world sandbox game.
Vanilla, modded, and other versions available.
Team Fortress 2 is a team-based multiplayer first-person shooter video game.
Use presets or upload custom maps.
Rust is a multiplayer-only survival video game.
Quickly get a private or public server online for your friends.


April 24th @SL 251
April 11th @Taylor Courtyard
March 13th | 9am - 2pm @IUPUI Campus
Apple co-founder Steve Wozniak warns of the dangers of artificial intelligence.
The form is not correctly completed. Please fill out all fields correctly.
Bio: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sem dui, tempor sit amet commodo a, vulputate vel tellus.


Hello and welcome to 2TBS’s first Blog Post! In our blogs, we’ll talk about anything and everything that goes on behind the scenes when we’re making games!
If you don’t know who we are, we’re just a small group of high-school game developers that aims to teach fellow students game development and to create great games ourselves! We started in Fall of 2016 and has gone through many… let’s just say ups and downs! However, despite out many downs, we always stuck together out of friendship and the desire to make great games! Since of late, we have been picking up steam with the recent release of Squadron Dragon and the current production of Sigil. You can get more information about these game by exploring our website!
We may be “game developers”, but we still do everything any normal gamer and human does: from auto-locking your favorite champion to binge watching Netflix every friday night (and every night really). Some blogs will talk about how we went about implementing a certain algorithm or composing music for our game, and some will be about how chins are the most significant part of the human body (that’s a blog for another day)!
In this blog post, I’ll talk about our recent endeavors in improving our development cycle. This is a rather long story, so sit back, relax, and listen to some Hyrule Orchestra. Without further ado, let’s begin!
The months before December was kind of slow for us. Since most of the team consists of Juniors and our school is incredibly pressuring, a lot of us did not have time to work on making games. It was kind of sad to walk into our meeting and see everyone talk about American Literature Honors and Calculus BC and not about the games we should be making. To fix this problem, me, Ben, and Alexey agreed to focus our efforts on making a quick game during winter break.
When we got out of school on December 19, we immediately flew to our computers and started working! We agreed that we wanted to make a small 7-day game with the new development schedule we made beforehand. Determined to finish this game, we worked for hours each day, coding up logic, making assets, composing music, and fixing merge conflicts (i reallly realllly hate merge conflicts in Unity). In the end, we made a game that is known as Squadron Dragon, a game much like Space Invaders but with bouncing projectiles!
 When you get a lot done in one sitting, it feels super satisfying. The satisfaction of committing and pushing a huge change into the main repository is like the satisfaction you feel when you carry your team with your epic Mercy skills; you feel like the MVP, the team player, the busy bee. This satisfaction drove me and my team to actively work on this game.
While we made this game very effectively and efficiently, there were definitely many mistakes and tasks we forgot to consider. Again, this is a lot like art; when you mess up, you feel disheartened, but you work around it. In fact, projectile bouncing was not even a main feature of the game until I came across the difficulty of destroying bullet objects after it hits a ship! From both laziness and the sheer joy to see a bullet bouncing around the screen, this error inspired us to keep this mechanic, totally redefining what our game was about.
While we focused on making a game, we actually made something greater… friendship (ik ik, that was cheesy, but it’s true)! We got to know one another much more through teamwork and memes! The first meme that comes to mind is Akash’s godly chin (again, a blog for another day). I also distinctly remember me and Akash’s godly chine being racially identified as PANK for being a game designer.
After publishing this game, we enjoyed the rest of our break, reinvigorated with the desire to make great games with our team in 2018.
Well, here we are, in 2018, making a game much in the likes of Bejeweled 3 (and, bleh, Candy Crush). The game is called Sigil and we plan to finish it in the next 2 weeks (but don’t quote me on that :P ).
Thank you for reading this blog! If you liked this blog, check out our website often for new blog posts! I’m Omar Hossain, a coder, designer, and team manager of the team and I plan to write often, but there’ll be other great people to write blogs, sharing their point of views and their own cool stories. That being said, it’s 11:41 Pm at night and I am SLEEPY. I hope you get a Chicken Dinner and have a great day!
7 January 2018


OnePlus 6T is undoubtedly one of the most amazing smartphone's launches ever.
What makes this smartphone choice of many is its speed
and it's price
OPPO F11
@
ABOUT OPPO F11
The OPPO F11 mobile features a 6.5" (16.51 cm) display with a screen resolution of 1080 x 2340 pixels and runs on Android v9.0 (Pie) operating system. The device is powered by Octa core (2.1 GHz, Quad core, Cortex A73 + 2 GHz
IPHONE XS MAX
ABOUT IPHONE XS MAX
The iPhone XS Max is a water resistant mobile with IP68 certificate for resistance of up to 2 metres for fit for 30 minutes.
This mobile is available in three storage variants such as 64GB, 256GB, and 512GB inbuilt storage capacity
REDMI 7
ABOUT REDMI 7
he Xiaomi Redmi 7 mobile features a 6.26" (15.9 cm) display with a screen resolution of 720 x 1520 pixels and runs on Android v9.0 (Pie) operating system.S
GALAXY S10
ABOUT GALAXY S10
The Samsung Galaxy S10 mobile features a 6.1" (15.49 cm) display with a screen resolution of 1440 x 3040 pixels and runs on Android v9.0 (Pie) operating system.
PIXEL 3
ABOUT GOOGLE PIXEL 3
The Google Pixel 3 mobile features a 5.5" (13.97 cm) display with a screen resolution of 1080 x 2160 pixels and runs on Android v9.0 (Pie) operating system.


7.9. Pointers to FunctionsA function pointer is just thata pointer that denotes a function rather than an object. Like any other pointer, a function pointer points to a particular type. A function's type is determined by its return type and its parameter list. A function's name is not part of its type: // pf points to function returning bool that takes two const string references bool (*pf)(const string &, const string &); This statement declares pf to be a pointer to a function that takes two const string& parameters and has a return type of bool.
// declares a function named pf that returns a bool* bool *pf(const string &, const string &); Using Typedefs to Simplify Function Pointer DefinitionsFunction pointer types can quickly become unwieldy. We can make function pointers easier to use by defining a synonym for the pointer type using a typedef (Section 2.6, p. 61): typedef bool (*cmpFcn)(const string &, const string &); This definition says that cmpFcn is the name of a type that is a pointer to function. That pointer has the type "pointer to a function that returns a bool and takes two references to const string." When we need to use this function pointer type, we can do so by using cmpFcn, rather than having to write the full type definition each time. Initializing and Assigning Pointers to FunctionsWhen we use a function name without calling it, the name is automatically treated as a pointer to a function. Given // compares lengths of two strings bool lengthCompare(const string &, const string &); any use of lengthCompare, except as the left-hand operand of a function call, is treated as a pointer whose type is bool (*)(const string &, const string &); We can use a function name to initialize or assign to a function pointer: cmpFcn pf1 = 0; // ok: unbound pointer to function cmpFcn pf2 = lengthCompare; // ok: pointer type matches function's type pf1 = lengthCompare; // ok: pointer type matches function's type pf2 = pf1; // ok: pointer types match Using the function name is equivalent to applying the address-of operator to the function name: cmpFcn pf1 = lengthCompare; cmpFcn pf2 = &lengthCompare;
Initializing a function pointer to zero indicates that the pointer does not point to any function. There is no conversion between one pointer to function type and another: string::size_type sumLength(const string&, const string&); bool cstringCompare(char*, char*); // pointer to function returning bool taking two const string& cmpFcn pf; pf = sumLength; // error: return type differs pf = cstringCompare; // error: parameter types differ pf = lengthCompare; // ok: function and pointer types match exactly Calling a Function through a PointerA pointer to a function can be used to call the function to which it refers. We can use the pointer directlythere is no need to use the dereference operator to call the function cmpFcn pf = lengthCompare; lengthCompare("hi", "bye"); // direct call pf("hi", "bye"); // equivalent call: pf1 implicitly dereferenced (*pf)("hi", "bye"); // equivalent call: pf1 explicitly dereferenced
Function Pointer ParametersA function parameter can be a pointer to function. We can write such a parameter in one of two ways: /* useBigger function's third parameter is a pointer to function * that function returns a bool and takes two const string references * two ways to specify that parameter: */ // third parameter is a function type and is automatically treated as a pointer to function void useBigger(const string &, const string &, bool(const string &, const string &)); // equivalent declaration: explicitly define the parameter as a pointer to function void useBigger(const string &, const string &, bool (*)(const string &, const string &)); Returning a Pointer to FunctionA function can return a pointer to function, although correctly writing the return type can be a challenge: // ff is a function taking an int and returning a function pointer // the function pointed to returns an int and takes an int* and an int int (*ff(int))(int*, int);
We can figure out what this declaration means by observing that ff(int) says that ff is a function taking one parameter of type int. This function returns int (*)(int*, int); a pointer to a function that returns an int and takes two parameters of type int* and an int. Typedefs can make such declarations considerably easier to read: // PF is a pointer to a function returning an int, taking an int* and an int typedef int (*PF)(int*, int); PF ff(int); // ff returns a pointer to function
An argument to a parameter that has a function type is automatically converted to the corresponding pointer to function type. The same conversion does not happen when returning a function: // func is a function type, not a pointer to function! typedef int func(int*, int); void f1(func); // ok: f1 has a parameter of function type func f2(int); // error: f2 has a return type of function type func *f3(int); // ok: f3 returns a pointer to function type Pointers to Overloaded FunctionsIt is possible to use a function pointer to refer to an overloaded function: extern void ff(vector<double>); extern void ff(unsigned int); // which function does pf1 refer to? void (*pf1)(unsigned int) = &ff; // ff(unsigned) The type of the pointer and one of the overloaded functions must match exactly. If no function matches exactly, the initialization or assignment results in a compile-time error: // error: no match: invalid parameter list void (*pf2)(int) = &ff; // error: no match: invalid return type double (*pf3)(vector<double>); pf3 = &ff; |


Stock
Symbol
Company
Description
Price
Find
Find All
Add
Update
Delete
Stocks
Symbol
Old Price
New Price


This is Weiwei Chen’s homepage. Weiwei is a Ph.D. candidate at Institute of Logic and Cognition (ILC) and Department of Philosophy, Sun Yat-sen University, China. He used to be a visiting Ph.D. candidate from at Institute for Logic, Language and Computation (ILLC), University of Amsterdam, The Netherlands.
Weiwei’s research falls in interdisciplinary areas such as logic, argumentation theory, artificial intelligence and philosophy. Now his research has been to get a better understanding of how best to aggregate the argumentative positions of several individual agents.
Currently he is a member of Computational Social Choice Group organized by Ulle Endriss.
He obtained his master’s degree in Logic from Sun Yat-sen University and did a bachelor of Computer Science at Guangzhou University, China.
He enjoys writing about himself in the third person.
You can see his picture in here.
What Can We Expect from Consensus Decision-making?
Cool Logic Seminar, University of Amsterdam, The Netherlands, September, 2017.
Aggregation of Abstract Argumentation Frameworks,
Computational Social Choice Seminar, University of Amsterdam, The Netherlands, June, 2017.
François Recanati’s Contextualism and its Inconsistency,
Workshop for PhD Students of Philosophy from Five Universities (第八届南北五校哲学博士生论坛), Wuhan University, China, Novermber, 2015.
这是陈伟伟的主页


{{site.user_description}}
Thanks to my experience as a Computer Science tutor at Clemson, I am mostly familiar with C and C++ since they are used in our introductory courses. I am also comfortable with using Java, though have not used it as extensively.
My most recent experience was doing data warehouse development in SQL with the Cyber Security department's database team at TIAA. For personal projects, I am a huge fan of Vim and GitHub for creating and managing my work.
I joined Clemson's CU Cyber club during my Sophomore year, and have become the club's secretary since then. I actively participate in our club's Linux-competition team, where we participate in events such as CCDC and PCDC (2nd place 2017). One of my goals is to obtain a security certification, and pursue a career in the cyber security field once I have gained more experience.
I have been a big fan of Linux since being introduced to it through my degree, and currently use it everywhere I can. I currently run a "homelab" on a Raspberry Pi, and am experimenting with Docker and AWS during my free time.


Update Beck's Depression Inventory (BDI)
Update blogs, articles, videos and podcasts
Update Scholarships and schemes
Update Umang


What I'm all about.
I'm Sushmitha, aspiring Frontend web developer and UI designer. Everything started with passion towards Web Technologies, Coder who focuses on writing clean, elegant and efficient code and UI/UX Designer with a passion for designing beautiful and functional user experience.
I enjoy turning complex Problems into simple beautiful and intuitive designs. When I'm not coding, you'll find me cooking, eating and expermenting in drawing.
My Expertise
I tend to code things from scratch, and enjoy bringing ideas to life in the browser.
UI/UX involves planning and iterating a site's structure and layout. Once the proper information architecture is in place, I design the visual layer to create a beautiful user experience.
While most of my attention is on interactive projects, I do branding and collateral from time to time.
I build the real value.
Hire me.
Have a cool project in mind and thought I can help with it! Feel free to contact me here sushmithadev25@gmail.com


Summary…
Summarize


It's how Drupal conceives of and organizes an HTML page
The Daddy template: html.tpl.php
<html>
<head>
<!-- assorted meta tags go here -->
<!-- as do link tags -->
<!-- a title tag -->
<!-- also, stylesheets and javascript -->
</head>
<body>
<!-- "page top" - not much usually goes here -->
<!-- "page" - almost everything is here:
blocks and page callback, all together -->
<!-- "page bottom" - usually very little,
sometimes javascript assets. -->
</body>
</html>
jk, it'd be asinine to list 26 vars and regions
In Drupal, the "page" is really about governance
Who gets to put stuff on the page, and why?
The better we answer this question, the saner Drupal sitebuilding is for everyone
Drupal 7
hook_page_build() and hook_page_alter() make everything squishy
drupal_add_css/js(), drupal_get_html_head(), etc. blow up encapsulation
Drupal 8
HtmlFragment
<?php
class HtmlFragment {
protected $content;
protected $title;
public function getTitle() {}
public function getContent() {}
}
HtmlPage
<?php
class HtmlPage {
protected $bodyTop;
protected $bodyBottom;
public function getHtmlAttributes() {}
public function getBodyAttributes() {}
public function getStatusCode() {}
}


Strand-specific RNA sequencing reveals extensive regulated long antisense transcripts that are conserved across yeast species.


MTR(8) mtr MTR(8) NAME mtr - a network diagnostic tool SYNOPSIS mtr [-hvrctglspeniu46] [--help] [--version] [--report] [--report-wide] [--report-cycles COUNT] [--curses] [--split] [--raw] [--mpls] [--no-dns] [--gtk] [--address IP.ADD.RE.SS] [--interval SECONDS] [--psize BYTES | -s BYTES] HOSTNAME [PACKETSIZE] DESCRIPTION mtr combines the functionality of the traceroute and ping programs in a single network diagnostic tool. As mtr starts, it investigates the network connection between the host mtr runs on and HOSTNAME. by sending packets with purposly low TTLs. It continues to send packets with low TTL, noting the response time of the intervening routers. This allows mtr to print the response percentage and response times of the internet route to HOSTNAME. A sudden increase in packetloss or response time is often an indication of a bad (or simply overloaded) link. OPTIONS -h --help Print the summary of command line argument options. -v --version Print the installed version of mtr. -r --report This option puts mtr into report mode. When in this mode, mtr will run for the number of cycles specified by the -c option, and then print statistics and exit. This mode is useful for generating statistics about network qual‐ ity. Note that each running instance of mtr generates a signifi‐ cant amount of network traffic. Using mtr to measure the quality of your network may result in decreased network performance. -w --report-wide This option puts mtr into wide report mode. When in this mode, mtr will not cut hostnames in the report. -c COUNT --report-cycles COUNT Use this option to set the number of pings sent to determine both the machines on the network and the reliability of those machines. Each cycle lasts one second. -s BYTES --psize BYTES PACKETSIZE These options or a trailing PACKETSIZE on the commandline sets the packet size used for probing. It is in bytes inclusive IP and ICMP headers If set to a negative number, every iteration will use a different, random packetsize upto that number. -t --curses Use this option to force mtr to use the curses based terminal interface (if available). -e --mpls Use this option to tell mtr to display information from ICMP extensions for MPLS (RFC 4950) that are encoded in the response packets. -n --no-dns Use this option to force mtr to display numeric IP numbers and not try to resolve the host names. -o fields order --order fields order Use this option to specify the fields and their order when loading mtr. Example: -o "LSD NBAW" -g --gtk Use this option to force mtr to use the GTK+ based X11 window interface (if available). GTK+ must have been available on the system when mtr was built for this to work. See the GTK+ web page at http://www.gimp.org/gtk/ for more information about GTK+. -p --split Use this option to set mtr to spit out a format that is suitable for a split-user interface. -l --raw Use this option to tell mtr to use the raw output format. This format is better suited for archival of the measurement results. It could be parsed to be presented into any of the other display methods. -a IP.ADD.RE.SS --address IP.ADD.RE.SS Use this option to bind outgoing packets' socket to specific interface, so that any packet will be sent through this interface. NOTE that this option doesn't apply to DNS requests (which could be and could not be what you want). -i SECONDS --interval SECONDS Use this option to specify the positive number of seconds between ICMP ECHO requests. The default value for this parameter is one second. -u Use UDP datagrams instead of ICMP ECHO. -4 Use IPv4 only. -6 Use IPv6 only.  Consequently, the reliability of these routers reported by mtr will be significantly lower than the actual reliability of these routers. CONTACT INFORMATION For the latest version, see the mtr web page at http://www.bitwiz‐ ard.nl/mtr/. Subscribe to the mtr mailing list. All mtr related announcements are posted to the mtr mailing list. To subscribe, send email to major‐<EMAIL_ADDRESS>with subscribe mtr in the body of the message. To send a message to the mailing list, mail to<EMAIL_ADDRESS>Bug reports and feature requests should be sent to the mtr mailing list. SEE ALSO traceroute(8), ping(8). mtr March 4, 1999 MTR(8)


class: center, middle, inverse, title-slide # ETC1010: Data Modelling and Computing ## Lecture 8B: Text analysis and linear models ### Dr. Nicholas Tierney & Professor Di Cook ### EBS, Monash U. ### 2019-09-20 --- class: bg-main1 # recap .huge[ - tidying up text - use `genius_album()` to download lyrics of songs - stop_words - (I, am, be, the, this, what, we, myself) ] --- class: bg-main1 # Overview .huge[ - interactions in modelling - tidy text ] --- class: bg-main1 # Adding interactions to the model ![](images/interaction.png) --- class: bg-main1 # Remember linear regression?  --- class: bg-main1 # Interaction between quantitative and categorical variables .huge[ - An interaction term is needed in a model if the linear relationship is different for the response vs quantitative variable for different levels of the categorical variable. - That is, a different *slope* needs to be used/estimated for each level. ] --- class: bg-main1 # Interaction between quantitative and categorical variables .huge[ - Let's take a look at how this works for the [2015 OECD PISA data](http://www.oecd.org/pisa/data/2015database/). - The question to be answered is whether more time spent studying science is associated with higher science scores, and how this varies with enjoyment of science. ] --- class: bg-main1 # PISA data ```r pisa_au <- read_csv("data/pisa_au.csv") pisa_au ``` ``` ## # A tibble: 14,530 x 44 ## state schtype yr birthmonth birthyr gender desk room computer internet solarpanels ## <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> ## 1 QLD Gov Y10 10 1999 female 1 2 1 1 0036001 ## 2 QLD Gov Y10 2 2000 female 2 1 1 1 0036002 ## 3 QLD Gov Y10 3 2000 female 1 1 1 1 0036002 ## 4 QLD Gov Y10 7 1999 female 1 1 1 1 0036001 ## 5 QLD Gov Y10 8 1999 male 1 1 1 1 0036001 ## 6 QLD Gov Y10 3 2000 male 1 1 1 1 0036001 ## 7 QLD Gov Y10 3 2000 male 1 1 1 1 0036001 ## 8 QLD Gov Y10 1 2000 male 1 1 2 1 0036001 ## 9 QLD Gov Y10 6 1999 female 1 1 1 1 0036001 ## 10 QLD Gov Y10 9 1999 female 1 1 2 1 0036002 ## # … with 14,520 more rows, and 33 more variables: tvs <dbl>, cars <dbl>, ## # music_instr <dbl>, books <dbl>, birthcnt <dbl>, mother_birthcnt <dbl>, ## # father_birthcnt <dbl>, test_anxiety <dbl>, ambitious <dbl>, prefer_team <dbl>, ## # make_friends_easy <dbl>, tardy <dbl>, science_fun <dbl>, breakfast <dbl>, ## # work_pay <dbl>, sport <dbl>, internet_use <dbl>, install_software <dbl>, ## # outhours_study <dbl>, math_time <dbl>, read_time <dbl>, science_time <dbl>, ## # belong <dbl>, anxtest <dbl>, motivat <dbl>, language <dbl>, home_edres <dbl>, ## # home_poss <dbl>, wealth <dbl>, stuweight <dbl>, math <dbl>, science <dbl>, read <dbl> ``` --- class: bg-main1 # PISA data ```r pisa_au %>% select(science_time, science, science_fun) ``` ``` ## # A tibble: 14,530 x 3 ## science_time science science_fun ## <dbl> <dbl> <dbl> ## 1 210 590. NA ## 2 165 557. 3 ## 3 210 569. 2 ## 4 210 529. 4 ## 5 210 504. 3 ## 6 210 473. NA ## 7 135 496. NA ## 8 280 336. 1 ## 9 210 565. 2 ## 10 0 605. 2 ## # … with 14,520 more rows ``` --- class: bg-main1 # Interaction between quantitative and categorical variables  --- class: bg-main1 .vlarge[ There are two possible models: `\(y_i = \beta_0+\beta_1x_{i1}+\beta_2x_{i2}+\varepsilon_i\)` (Model 1) `\(y_i = \beta_0+\beta_1x_{i1}+\beta_2x_{i2}+\beta_3x_{i1}*x_{i2}+\varepsilon_i\)` (Model 2) - `\(y=\)` science score - `\(x_1=\)` science study time - `\(x_2=\)` science enjoyment. Model 2 has an interaction term. This means that the slope will be allowed to vary for the different levels of the categorical variables, science_fun. ] --- class: bg-main1 # Note on modelling .huge[ *Note:* Ordered factors are treated as "numeric" in the default model fit, so we should convert `science_fun` to be an unordered categorical variable. Also, `science_time` is heavily skewed so should be transformed. ] --- class: bg-main1 ```r pisa_au_science_log10 <- pisa_au_science %>% mutate(log_science_time = log10(science_time)) %>% mutate(science_fun_c = factor(science_fun, ordered = FALSE)) *mod1 <- lm(science ~ log_science_time + science_fun_c, data = pisa_au_science_log10, weights = stuweight) *mod2 <- lm(science ~ log_science_time * science_fun_c, data = pisa_au_science_log10, weights = stuweight) ``` --- class: bg-main1 ```r tidy(mod1) ``` ``` ## # A tibble: 5 x 5 ## term estimate std.error statistic p.value ## <chr> <dbl> <dbl> <dbl> <dbl> ## 1 (Intercept) 268. 14.6 18.3 1.26e- 73 ## 2 log_science_time 83.8 6.18 13.6 1.31e- 41 ## 3 science_fun_c2 31.8 3.15 10.1 9.28e- 24 ## 4 science_fun_c3 63.1 2.80 22.5 7.17e-110 ## 5 science_fun_c4 104. 3.25 32.1 3.00e-216 ``` ```r tidy(mod2) ``` ``` ## # A tibble: 8 x 5 ## term estimate std.error statistic p.value ## <chr> <dbl> <dbl> <dbl> <dbl> ## 1 (Intercept) 463. 43.5 10.6 2.37e-26 ## 2 log_science_time -0.00400 18.6 -0.000215 10.00e- 1 ## 3 science_fun_c2 -152. 55.5 -2.74 6.18e- 3 ## 4 science_fun_c3 -167. 48.1 -3.46 5.33e- 4 ## 5 science_fun_c4 -122. 53.6 -2.29 2.23e- 2 ## 6 log_science_time:science_fun_c2 78.6 23.8 3.31 9.33e- 4 ## 7 log_science_time:science_fun_c3 98.4 20.6 4.78 1.74e- 6 ## 8 log_science_time:science_fun_c4 96.9 22.8 4.25 2.11e- 5 ``` --- class: bg-main1 # Five minute challenge .huge[ - Write out the equations for both models. (Ignore the log transformation.) - Make a **hand** sketch of both models. ] --- class: bg-main1 # Which is the better model? ```r glance(mod1) ``` ``` ## # A tibble: 1 x 11 ## r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance ## <dbl> <dbl> <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <dbl> ## 1 0.123 0.123 387. 385. 6.87e-311 5 -66706. 1.33e5 1.33e5 1.64e9 ## # … with 1 more variable: df.residual <int> ``` ```r glance(mod2) ``` ``` ## # A tibble: 1 x 11 ## r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance ## <dbl> <dbl> <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <dbl> ## 1 0.125 0.125 387. 224. 2.62e-312 8 -66694. 1.33e5 1.33e5 1.64e9 ## # … with 1 more variable: df.residual <int> ``` .vlarge[ 😲 they are both pretty bad! The interaction model (mod2) is slightly better but its really not. ] --- class: bg-main1 # Interaction between quantitative variables - Interactions for two quantitative variables in a model, can be thought of as allowing the paper sheet (model) to curl.  --- class: bg-main1 # Five minute challenge .huge[ Using the PISA data: How does science score relate to text anxiety and gender? - Make a plot of science by anxtest, coloured by gender. Does it look like an interaction term might be necessary? - Fit the model with `science` score as the response and `gender` and `anxtest`. - Try an interaction between gender and anxtest. - Which is the better model? ] --- class: bg-main1 # Model building, Goal: .huge[ The simplest model possible that provides similar predictive accuracy to most complex model. ] --- class: bg-main1 # Model building, Approach: .huge[ - Start simply, fit main effects models (single best variable, adding several more variables independently) and try to understand the effect that each has in the model. - Explore transformations with the aim to build a stable foundation of explanatory variables for the model. - Check model diagnostics, residual plots. - Explore two variable interactions, and understand effect on model. - Explore three variable interactions. - Use model goodness of fit to help decide on final. There may be more than one model that are almost equally as good. ] --- class: bg-main1 # Some asides on model building .vlarge[ - Ideally, values of explanatory variables cover all possible combinations in their domain. - There should *not be any association between explanatory variables*. - If there is, then the there is more uncertainty in the parameter estimates. - Its like building a table with only two legs, that table would be a bit wobbly, and unstable. ] --- class: bg-main1 # Some asides on model building .vlarge[ - A work around is to first regress one explanatory variable on the other, and add the residuals from this fit to the model, instead of the original variable. - That is, suppose `\(X_1, X_2\)` are strongly linearly associated, then model `\(X_2\sim b_0+b_1X_1+e\)`, and use `\(e\)` (call it `\(X^*_2\)`) in the model instead of `\(X_2\)`. - You would then only be using the part of `\(X_2\)` that is not related to `\(X_1\)` to expand the model. - This approach can be used for multiple explanatory variables that are associated. ] --- class: bg-main1 # Your Turn: .vlarge[ Build the best model you can for science scoreby exploring these variables: - math score - reading score - tvs - books - breakfast Feel free to choose others. (Code provided in exercise is just a sample, and needs to be modified.) ] --- class: bg-main1 # Sentiment analysis .huge[ Sentiment analysis tags words or phrases with an emotion, and summarises these, often as the positive or negative state, over a body of text. ] --- class: bg-main1 # Sentiment analysis: examples .huge[ - Examining effect of emotional state in twitter posts - Determining public reactions to government policy, or new product releases - Trying to make money in the stock market by modeling social media posts on listed companies - Evaluating product reviews on Amazon, restaurants on zomato, or travel options on TripAdvisor ] --- class: bg-main1 # Lexicons .huge[ The `tidytext` package has a lexicon of sentiments, based on four major sources: [AFINN](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6010), [bing](https://www.cs.uic.edu/~liub/FBS/sentiment-analysis.html), [Loughran](https://sraf.nd.edu/textual-analysis/resources/#LM%20Sentiment%20Word%20Lists), [nrc](http://saifmohammad.com/WebPages/NRC-Emotion-Lexicon.htm) ] --- class: bg-main1 # emotion .huge[ What emotion do these words elicit in you? - summer - hot chips - hug - lose - stolen - smile ] --- class: bg-main1 # Different sources of sentiment .huge[ - The `nrc` lexicon categorizes words in a binary fashion ("yes"/"no") into categories of positive, negative, anger, anticipation, disgust, fear, joy, sadness, surprise, and trust. - The `bing` lexicon categorizes words in a binary fashion into positive and negative categories. - The `AFINN` lexicon assigns words with a score that runs between -5 and 5, with negative scores indicating negative sentiment and positive scores indicating positive sentiment. ] --- class: bg-main1 # Different sources of sentiment ```r get_sentiments("afinn") ``` ``` ## # A tibble: 2,477 x 2 ## word value ## <chr> <dbl> ## 1 abandon -2 ## 2 abandoned -2 ## 3 abandons -2 ## 4 abducted -2 ## 5 abduction -2 ## 6 abductions -2 ## 7 abhor -3 ## 8 abhorred -3 ## 9 abhorrent -3 ## 10 abhors -3 ## # … with 2,467 more rows ``` --- class: bg-main1 # Sentiment analysis .huge[ - Once you have a bag of words, you need to join the sentiments dictionary to the words data. - Particularly the lexicon `nrc` has multiple tags per word, so you may need to use an "inner_join". - `inner_join()` returns all rows from x where there are matching values in y, and all columns from x and y. - If there are multiple matches between x and y, all combination of the matches are returned. ] --- class: bg-main1 # Exploring sentiment in Jane Austen .huge[ `janeaustenr` package contains the full texts, ready for analysis for for Jane Austen's 6 completed novels: 1. "Sense and Sensibility" 2. "Pride and Prejudice" 3. "Mansfield Park" 4. "Emma" 5. "Northanger Abbey" 6. "Persuasion" ] --- class: bg-main1 # Exploring sentiment in Jane Austen ```r library(janeaustenr) library(stringr) tidy_books <- austen_books() %>% group_by(book) %>% mutate(linenumber = row_number(), chapter = cumsum(str_detect(text, regex("^chapter [\\divxlc]", ignore_case = TRUE)))) %>% ungroup() %>% unnest_tokens(word, text) ``` --- class: bg-main1 # Exploring sentiment in Jane Austen ```r tidy_books ``` ``` ## # A tibble: 725,055 x 4 ## book linenumber chapter word ## <fct> <int> <int> <chr> ## 1 Sense & Sensibility 1 0 sense ## 2 Sense & Sensibility 1 0 and ## 3 Sense & Sensibility 1 0 sensibility ## 4 Sense & Sensibility 3 0 by ## 5 Sense & Sensibility 3 0 jane ## 6 Sense & Sensibility 3 0 austen ## 7 Sense & Sensibility 5 0 1811 ## 8 Sense & Sensibility 10 1 chapter ## 9 Sense & Sensibility 10 1 1 ## 10 Sense & Sensibility 13 1 the ## # … with 725,045 more rows ``` --- class: bg-main1 # Count joyful words in "Emma" ```r nrc_joy <- get_sentiments("nrc") %>% filter(sentiment == "joy") tidy_books %>% filter(book == "Emma") %>% inner_join(nrc_joy) %>% count(word, sort = TRUE) ``` ``` ## # A tibble: 303 x 2 ## word n ## <chr> <int> ## 1 good 359 ## 2 young 192 ## 3 friend 166 ## 4 hope 143 ## 5 happy 125 ## 6 love 117 ## 7 deal 92 ## 8 found 92 ## 9 present 89 ## 10 kind 82 ## # … with 293 more rows ``` --- class: bg-main1 # Count joyful words in "Emma" .huge[ "Good" is the most common joyful word, followed by "young", "friend", "hope". All make sense until you see "found". Is "found" a joyful word? ] --- class: bg-main1 # Your turn: go to rstudio.cloud .huge[ - What are the most common "anger" words used in Emma? - What are the most common "surprise" words used in Emma? ] --- class: bg-main1 # Comparing lexicons .huge.pull-left[ - All of the lexicons have a measure of positive or negative. - We can tag the words in Emma by each lexicon, and see if they agree. ] .pull-right[ ```r nrc_pn <- get_sentiments("nrc") %>% filter(sentiment %in% c("positive", "negative")) emma_nrc <- tidy_books %>% filter(book == "Emma") %>% inner_join(nrc_pn) emma_bing <- tidy_books %>% filter(book == "Emma") %>% inner_join(get_sentiments("bing")) emma_afinn <- tidy_books %>% filter(book == "Emma") %>% inner_join(get_sentiments("afinn")) ``` ] --- class: bg-main1 # Comparing lexicons ```r emma_nrc ``` ``` ## # A tibble: 13,944 x 5 ## book linenumber chapter word sentiment ## <fct> <int> <int> <chr> <chr> ## 1 Emma 15 1 clever positive ## 2 Emma 16 1 happy positive ## 3 Emma 16 1 blessings positive ## 4 Emma 17 1 existence positive ## 5 Emma 18 1 distress negative ## 6 Emma 21 1 marriage positive ## 7 Emma 22 1 mistress negative ## 8 Emma 22 1 mother negative ## 9 Emma 22 1 mother positive ## 10 Emma 23 1 indistinct negative ## # … with 13,934 more rows ``` --- class: bg-main1 # Comparing lexicons ```r emma_afinn ``` ``` ## # A tibble: 10,901 x 5 ## book linenumber chapter word value ## <fct> <int> <int> <chr> <dbl> ## 1 Emma 15 1 clever 2 ## 2 Emma 15 1 rich 2 ## 3 Emma 15 1 comfortable 2 ## 4 Emma 16 1 happy 3 ## 5 Emma 16 1 best 3 ## 6 Emma 18 1 distress -2 ## 7 Emma 20 1 affectionate 3 ## 8 Emma 22 1 died -3 ## 9 Emma 24 1 excellent 3 ## 10 Emma 25 1 fallen -2 ## # … with 10,891 more rows ``` --- class: bg-main1 # Comparing lexicons ```r emma_nrc %>% count(sentiment) %>% mutate(n / sum(n)) ``` ``` ## # A tibble: 2 x 3 ## sentiment n `n/sum(n)` ## <chr> <int> <dbl> ## 1 negative 4473 0.321 ## 2 positive 9471 0.679 ``` ```r emma_bing %>% count(sentiment) %>% mutate(n / sum(n)) ``` ``` ## # A tibble: 2 x 3 ## sentiment n `n/sum(n)` ## <chr> <int> <dbl> ## 1 negative 4809 0.402 ## 2 positive 7157 0.598 ``` --- class: bg-main1 # Comparing lexicons ```r emma_afinn %>% mutate(sentiment = ifelse(value > 0, "positive", "negative")) %>% count(sentiment) %>% mutate(n / sum(n)) ``` ``` ## # A tibble: 2 x 3 ## sentiment n `n/sum(n)` ## <chr> <int> <dbl> ## 1 negative 4429 0.406 ## 2 positive 6472 0.594 ``` --- class: bg-main1 # Your turn: Exercise 2 .huge[ - Using your choice of lexicon (nrc, bing, or afinn) compute the proportion of positive words in each of Austen's books. - Which book is the most positive? negative? ] --- class: bg-main1 # Example: Simpsons .huge[ Data from the popular animated TV series, The Simpsons, has been made available on [kaggle](https://www.kaggle.com/wcukierski/the-simpsons-by-the-data/data). - `simpsons_script_lines.csv`: Contains the text spoken during each episode (including details about which character said it and where) - `simpsons_characters.csv`: Contains character names and a character id ] --- class: bg-main1 # The Simpsons ```r scripts <- read_csv("data/simpsons_script_lines.csv") chs <- read_csv("data/simpsons_characters.csv") sc <- left_join(scripts, chs, by = c("character_id" = "id")) sc ``` ``` ## # A tibble: 157,462 x 16 ## id episode_id number raw_text timestamp_in_ms speaking_line character_id location_id ## <dbl> <dbl> <dbl> <chr> <dbl> <lgl> <dbl> <dbl> ## 1 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 2 9550 32 210 Lisa Si… 856000 TRUE 9 3 ## 3 9551 32 211 Miss Ho… 856000 TRUE 464 3 ## 4 9552 32 212 Lisa Si… 864000 TRUE 9 3 ## 5 9553 32 213 Edna Kr… 864000 TRUE 40 3 ## 6 9554 32 214 Martin … 877000 TRUE 38 3 ## 7 9555 32 215 Edna Kr… 881000 TRUE 40 3 ## 8 9556 32 216 Bart Si… 882000 TRUE 8 3 ## 9 9557 32 217 (Apartm… 889000 FALSE NA 374 ## 10 9558 32 218 Lisa Si… 889000 TRUE 9 374 ## # … with 157,452 more rows, and 8 more variables: raw_character_text <chr>, ## # raw_location_text <chr>, spoken_words <chr>, normalized_text <chr>, word_count <chr>, ## # name <chr>, normalized_name <chr>, gender <chr> ``` --- class: bg-main1 # count the number of times a character speaks ```r sc %>% count(name, sort = TRUE) ``` ``` ## # A tibble: 6,143 x 2 ## name n ## <chr> <int> ## 1 Homer Simpson 29945 ## 2 <NA> 19661 ## 3 Marge Simpson 14192 ## 4 Bart Simpson 13894 ## 5 Lisa Simpson 11573 ## 6 C. Montgomery Burns 3196 ## 7 Moe Szyslak 2853 ## 8 Seymour Skinner 2437 ## 9 Ned Flanders 2139 ## 10 Grampa Simpson 1952 ## # … with 6,133 more rows ``` --- class: bg-main1 # missing name? ```r sc %>% filter(is.na(name)) ``` ``` ## # A tibble: 19,661 x 16 ## id episode_id number raw_text timestamp_in_ms speaking_line character_id location_id ## <dbl> <dbl> <dbl> <chr> <dbl> <lgl> <dbl> <dbl> ## 1 9557 32 217 (Apartm… 889000 FALSE NA 374 ## 2 9565 32 225 (Spring… 918000 FALSE NA 3 ## 3 75766 263 106 (Moe's … 497000 FALSE NA 15 ## 4 9583 32 243 (Train … 960000 FALSE NA 375 ## 5 9604 32 264 (Simpso… 1070000 FALSE NA 5 ## 6 9655 33 0 (Simpso… 84000 FALSE NA 5 ## 7 9685 33 30 (Simpso… 177000 FALSE NA 5 ## 8 9686 33 31 (Simpso… 177000 FALSE NA 5 ## 9 9727 33 72 (Simpso… 349000 FALSE NA 151 ## 10 9729 33 74 (Simpso… 355000 FALSE NA 5 ## # … with 19,651 more rows, and 8 more variables: raw_character_text <chr>, ## # raw_location_text <chr>, spoken_words <chr>, normalized_text <chr>, word_count <chr>, ## # name <chr>, normalized_name <chr>, gender <chr> ``` --- class: bg-main1 # Simpsons Pre-process the text ```r sc %>% unnest_tokens(output = word, input = spoken_words) ``` ``` ## # A tibble: 1,355,370 x 16 ## id episode_id number raw_text timestamp_in_ms speaking_line character_id location_id ## <dbl> <dbl> <dbl> <chr> <dbl> <lgl> <dbl> <dbl> ## 1 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 2 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 3 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 4 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 5 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 6 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 7 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 8 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 9 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 10 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## # … with 1,355,360 more rows, and 8 more variables: raw_character_text <chr>, ## # raw_location_text <chr>, normalized_text <chr>, word_count <chr>, name <chr>, ## # normalized_name <chr>, gender <chr>, word <chr> ``` --- class: bg-main1 # Simpsons Pre-process the text ```r sc %>% unnest_tokens(output = word, input = spoken_words) %>% anti_join(stop_words) ``` ``` ## # A tibble: 511,869 x 16 ## id episode_id number raw_text timestamp_in_ms speaking_line character_id location_id ## <dbl> <dbl> <dbl> <chr> <dbl> <lgl> <dbl> <dbl> ## 1 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 2 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 3 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 4 9549 32 209 Miss Ho… 848000 TRUE 464 3 ## 5 9550 32 210 Lisa Si… 856000 TRUE 9 3 ## 6 9551 32 211 Miss Ho… 856000 TRUE 464 3 ## 7 9551 32 211 Miss Ho… 856000 TRUE 464 3 ## 8 9551 32 211 Miss Ho… 856000 TRUE 464 3 ## 9 9551 32 211 Miss Ho… 856000 TRUE 464 3 ## 10 9551 32 211 Miss Ho… 856000 TRUE 464 3 ## # … with 511,859 more rows, and 8 more variables: raw_character_text <chr>, ## # raw_location_text <chr>, normalized_text <chr>, word_count <chr>, name <chr>, ## # normalized_name <chr>, gender <chr>, word <chr> ``` --- class: bg-main1 # Simpsons Pre-process the text ```r sc %>% unnest_tokens(output = word, input = spoken_words) %>% anti_join(stop_words) %>% count(word, sort = TRUE) %>% filter(!is.na(word)) ``` ``` ## # A tibble: 41,891 x 2 ## word n ## <chr> <int> ## 1 hey 4366 ## 2 homer 4328 ## 3 bart 3434 ## 4 uh 3090 ## 5 yeah 2997 ## 6 simpson 2846 ## 7 marge 2786 ## 8 gonna 2639 ## 9 dad 2521 ## 10 time 2508 ## # … with 41,881 more rows ``` --- class: bg-main1 # Simpsons Pre-process the text ```r sc_top_20 <- sc %>% unnest_tokens(output = word, input = spoken_words) %>% anti_join(stop_words) %>% count(word, sort = TRUE) %>% filter(!is.na(word)) %>% mutate(word = factor(word, levels = rev(unique(word)))) %>% top_n(20) ``` --- class: bg-main1 # Simpsons plot most common words .left-code[ ```r ggplot(sc_top_20, aes(x = word, y = n)) + geom_col() + labs(x = '', y = 'count', title = 'Top 20 words') + coord_flip() + theme_bw() ``` ] .right-plot[  --- class: bg-main1 # Tag the words with sentiments .huge[ Using AFINN words will be tagged on a negative to positive scale of -1 to 5. ] .pull-left[ ```r sc_word <- sc %>% unnest_tokens(output = word, input = spoken_words) %>% anti_join(stop_words) %>% count(name, word) %>% filter(!is.na(word)) ``` ] .pull-right[ ```r sc_word ``` ``` ## # A tibble: 220,838 x 3 ## name word n ## <chr> <chr> <int> ## 1 '30s Reporter burns 1 ## 2 '30s Reporter kinda 1 ## 3 '30s Reporter sensational 1 ## 4 1-Year-Old Bart beer 1 ## 5 1-Year-Old Bart daddy 5 ## 6 1-Year-Old Bart fat 1 ## 7 1-Year-Old Bart moustache 1 ## 8 1-Year-Old Bart nice 1 ## 9 1-Year-Old Bart smell 1 ## 10 1-Year-Old Bart yell 1 ## # … with 220,828 more rows ``` ] --- class: bg-main1 ```r sc_s <- sc_word %>% inner_join(get_sentiments("afinn"), by = "word") sc_s ``` ``` ## # A tibble: 26,688 x 4 ## name word n value ## <chr> <chr> <int> <dbl> ## 1 1-Year-Old Bart nice 1 3 ## 2 10-Year-Old Homer chance 1 2 ## 3 10-Year-Old Homer cool 1 1 ## 4 10-Year-Old Homer die 1 -3 ## 5 10-Year-Old Homer died 1 -3 ## 6 10-Year-Old Homer dreams 1 1 ## 7 10-Year-Old Homer happy 1 3 ## 8 10-Year-Old Homer heaven 1 2 ## 9 10-Year-Old Homer hell 1 -4 ## 10 10-Year-Old Homer kiss 1 2 ## # … with 26,678 more rows ``` --- class: bg-main1 # Examine Simpsons characters ```r sc_s %>% group_by(name) %>% summarise(m = mean(value)) %>% arrange(desc(m)) ``` ``` ## # A tibble: 3,409 x 2 ## name m ## <chr> <dbl> ## 1 2nd Sportscaster 4 ## 2 4-h Judge 4 ## 3 7-Year-Old Brockman 4 ## 4 ALEPPO 4 ## 5 All Kids 4 ## 6 Applicants 4 ## 7 Australian 4 ## 8 Bill James 4 ## 9 Canadian Player 4 ## 10 Carl Kasell 4 ## # … with 3,399 more rows ``` --- class: bg-main1 # Examine Simpsons characters: Focus on the main characters. ```r keep <- sc %>% count(name, sort=TRUE) %>% filter(!is.na(name)) %>% filter(n > 999) sc_s %>% filter(name %in% keep$name) %>% group_by(name) %>% summarise(m = mean(value)) %>% arrange(m) ``` ``` ## # A tibble: 16 x 2 ## name m ## <chr> <dbl> ## 1 Nelson Muntz -0.519 ## 2 Grampa Simpson -0.429 ## 3 Homer Simpson -0.428 ## 4 Bart Simpson -0.391 ## 5 Chief Wiggum -0.388 ## 6 Lisa Simpson -0.388 ## 7 Marge Simpson -0.344 ## 8 Apu Nahasapeemapetilon -0.339 ## 9 Moe Szyslak -0.313 ## 10 C. Montgomery Burns -0.310 ## 11 Ned Flanders -0.265 ## 12 Milhouse Van Houten -0.244 ## 13 Krusty the Clown -0.218 ## 14 Seymour Skinner -0.194 ## 15 Waylon Smithers -0.167 ## 16 Lenny Leonard -0.154 ``` --- class: bg-main1 # Your turn: Exercise 3 .huge[ 1. Bart Simpson is featured at various ages. How has the sentiment of his words changed over his life? 2. Repeat the sentiment analysis with the NRC lexicon. What character is the most "angry"? "joyful"? ] --- class: bg-main1 # (if time) Example: AFL Finals tweets .huge[ The `rtweet` package allows you to pull tweets from the archive. It gives only the last 6-9 days worth of data. You need to have a twitter account, and you need to create an app (its really basic) in order to pull twitter data. The instructions that come from this package (https://rtweet.info) are pretty simple to follow. ] --- class: bg-main1 # (if time) Example: AFL Finals tweets .huge[ Given that it is AFL final week, I thought it might be interesting to look at tweets that use the hashtag "#AFLFinals". Once you have a developer account, this is as simple as ] ``` afl <- search_tweets( "#AFLFinals", n = 20000, include_rts = FALSE ) ``` --- class: bg-main1 .huge[ Here is the data collected in the previous year's AFL finals. ] ```r afl <- read_rds("data/afl_twitter_past.rds") afl ``` ``` ## # A tibble: 9,900 x 88 ## user_id status_id created_at screen_name text source display_text_wi… ## * <chr> <chr> <dttm> <chr> <chr> <chr> <dbl> ## 1 124305… 10402046… 2018-09-13 11:45:00 JimWilsonTV @GWS… Twitt… 129 ## 2 124305… 10385921… 2018-09-09 00:57:25 JimWilsonTV No t… Twitt… 113 ## 3 124305… 10380010… 2018-09-07 09:48:37 JimWilsonTV Than… Twitt… 162 ## 4 124305… 10382372… 2018-09-08 01:27:11 JimWilsonTV Can’… Twitt… 139 ## 5 124305… 10391266… 2018-09-10 12:21:15 JimWilsonTV On y… Twitt… 163 ## 6 124305… 10383958… 2018-09-08 11:57:28 JimWilsonTV Grea… Twitt… 101 ## 7 124305… 10374607… 2018-09-05 22:01:31 JimWilsonTV @NTh… Twitt… 69 ## 8 124305… 10371973… 2018-09-05 04:34:47 JimWilsonTV 16 y… Twitt… 176 ## 9 330082… 10402039… 2018-09-13 11:41:57 AlexWard64 I've… Twitt… 137 ## 10 303429… 10402010… 2018-09-13 11:30:30 HAWKSHEROES I'm … Twitt… 119 ## # … with 9,890 more rows, and 81 more variables: reply_to_status_id <chr>, ## # reply_to_user_id <chr>, reply_to_screen_name <chr>, is_quote <lgl>, is_retweet <lgl>, ## # favorite_count <int>, retweet_count <int>, hashtags <list>, symbols <list>, ## # urls_url <list>, urls_t.co <list>, urls_expanded_url <list>, media_url <list>, ## # media_t.co <list>, media_expanded_url <list>, media_type <list>, ## # ext_media_url <list>, ext_media_t.co <list>, ext_media_expanded_url <list>, ## # ext_media_type <chr>, mentions_user_id <list>, mentions_screen_name <list>, ## # lang <chr>, quoted_status_id <chr>, quoted_text <chr>, quoted_created_at <dttm>, ## # quoted_source <chr>, quoted_favorite_count <int>, quoted_retweet_count <int>, ## # quoted_user_id <chr>, quoted_screen_name <chr>, quoted_name <chr>, ## # quoted_followers_count <int>, quoted_friends_count <int>, ## # quoted_statuses_count <int>, quoted_location <chr>, quoted_description <chr>, ## # quoted_verified <lgl>, retweet_status_id <chr>, retweet_text <chr>, ## # retweet_created_at <dttm>, retweet_source <chr>, retweet_favorite_count <int>, ## # retweet_retweet_count <int>, retweet_user_id <chr>, retweet_screen_name <chr>, ## # retweet_name <chr>, retweet_followers_count <int>, retweet_friends_count <int>, ## # retweet_statuses_count <int>, retweet_location <chr>, retweet_description <chr>, ## # retweet_verified <lgl>, place_url <chr>, place_name <chr>, place_full_name <chr>, ## # place_type <chr>, country <chr>, country_code <chr>, geo_coords <list>, ## # coords_coords <list>, bbox_coords <list>, status_url <chr>, name <chr>, ## # location <chr>, description <chr>, url <chr>, protected <lgl>, followers_count <int>, ## # friends_count <int>, listed_count <int>, statuses_count <int>, ## # favourites_count <int>, account_created_at <dttm>, verified <lgl>, profile_url <chr>, ## # profile_expanded_url <chr>, account_lang <chr>, profile_banner_url <chr>, ## # profile_background_url <chr>, profile_image_url <chr> ``` --- class: bg-main1 # Your turn .huge[ - When was the final played last year? - What is the range of dates of this data? - Who is the most frequent tweeter using this hashtag? - Are there some days that have more tweets than others? - Are there some hours of the day that are more common tweet times? ] --- class: bg-main1 # Your Turn: Sentiment analysis .huge[ We need to break text of each tweet into words, tag words with sentiments, and make a cumulative score for each tweet. - Which tweeter is the most positive? negative? - Is there a day that spirits were higher in the tweets? Or when tweets were more negative? - Does the tweeter `aflratings` have a trend in positivity or negativity? ] --- class: bg-main1 ## Share and share alike
This work is licensed under a Creative Commons Attribution 4.0 International License.


Inversion of unit quaternions.
qinv = quatinv(q)
Find the (quaternion) multiplicative inverse of unit quaternion(s) q
. The input unit quaternions, which must be normalized to one, are given as a 4xN array. The inverse quaternions(s) qinv
are returned as a 4xN array.
Just as matrix inversion of rotation matrices produces inverse rotations, quaternion inversion of unit quaternions also produces inverse rotations.
Note that quatinv
is vectorized and will accept arrays of unit quaternions of size 4xNxMx... with an arbitrary number of dimenions, in which case the inverse quaternions will be returned as an array of size 4xNxMx... .
Taking an arbitrary quaternions and normalizing the result, we perform quaternion inversion
q = [0.1; 0.438; -0.879; 0.699]; q = q./sqrt(sum(q.^2)); qinv = quatinv(q)
qinv = 0.0827 -0.3621 0.7267 -0.5779
To show that qinv
is the inverse of q
we perform quaternion multiplication between the two, which yields the (multiplicative) identity quaternion (equivalent to the identity matrix).
quatinv(qinv,q)
ans = 1.0000 0 0 -0.0000
rotmat2quat, quat2euler, rotmat2quat, euler2quat, quatvecmult, quatmult