Copyright 2002-2006 by The BioBike Team (contact<EMAIL_ADDRESS>[If you are running this tutorial live, there are a few places where the [DO IT] button will only work on FireFox because of a length limitation in Internet Explorer. If you only have IE, you can manually enter the code in these places. We've indicated these. Sorry for the inconvenience.]
 Biologists often talk about
a biochemical "pathway", which is a group of related reactions that
serve some purpose, like the related steps in a procedural computer
program. And we looked a the glycolytic pathway, which is the one
that hexokinase participates in. You might want to review the section on pathways, wherein the most important
thing to remember is that: "pathways are a figment
of our collective imagination!; There's little specific machinery
in the cell that dictates these pathways." Another way to put
this is: Pathways arise from
explanations! What we're going to do in this section is to
see what that means.
Below are two different versions of the glycolytic pathway. Each line like this:
Here's a more complex one:
Now, let's look at those two glycolytic pathways. First notice that
they both end up with malate. Notice too that after the red part,
they are both the same; The difference is only whether we began at
Fructose, or Glucose:
The Kyoto Encyclopedia of Genes and Genomes (KEGG) has tools to find
all of the D-Pathways between two molecules.
Let's go back to KEGG and do some system reasoning. This link
will open a new browser into the Kegg page that "generates possible
reaction pathways between two compounds." Select it and then get
yourself set up so that you can read this at the same time that you
can press buttons on the KEGG page.
In the slot for "initial substrate" enter "Glucose" (don't put the
quotes!), and in the slot for "final product" enter "pyruvate" (again,
the quotes are just for us, you'd just put: pyruvate without quotes.)
Next set the Cutoff Length to 8 (it defaults to 5).
Now hit "Exec" on the bottom. The first time you do this it will
just replace the names glucose and pyruvate with KEGG's internal
names for these molecules (C00293, and C00022).
Now we're ready for the actual reasoning step: Hit "Exec" (at the
top of the page) again! This will take some time (think of big
computers computing in Japan!). When it comes back, you should see
something like this:
Each line in the long list at the end is one way that you can
enzymatically get from Glucose to Pyruvate; This result is
not precomputed; Kegg figured it out just now, based upon your
query and the model that it has of metabolism!
Let's look at some of these. Go to the first one, and press the
link on the far right, called "Show compound structures." What you'll
get is a diagram made up of the results. The enzymes are represented
in terms of their EC numbers, and both the reaction arrows and the
molecules are "live" -- you can button them to see which reaction is
used in each step.
Explore some of these a while, then come back to the Result page.
Before trying something else, let's hit the link called "Show as
diagram." This will make a complex and messy picture of all the ways
that KEGG knows how to get from Glucose to Pyruvate.
Now, you might be wondering if Glycolysis is somewhere among these 30
results. The answer is "No!" Why not? Because glycolysis is more
than 8 steps long, and we limited Kegg to finding pathways that are
only 8 steps long. These are only the solutions that can in
theory do this chemistry. In fact, the energy requirements of all
of these pathways is unfavorable, and none of them actually exist in
real organisms.
So, can we get KEGG to find the actual Glycolytic pathway? Maybe.
Let's back up now to the query page (the one with the "Exec" button;
one or two back, depending upon where you are). Notice the slot that
says "Enter cutoff length." It's at 8. That's why KEGG limited its
search to pathways that are only 8 or shorter in length. Let's change
that to a 10, and then press Exec again.
It should take a lot longer. How many pathways are there now?
Yow! By just changing that little number from 8 to 10 we
went from 30 to over 810 pathways!!! Probably the true Glycolysis
is someplace in these hundreds of solutions, but we'd never be able
to find it!
Let's start with a representation for reactions. A reaction structure
(a "struct" or "defstruct" in Lisp) represents a reaction(like glu +
atp-(hxk)-> g6p + adp). Reactants is a list of molecules required for
the reaction to take place. Catalysts are also required, though they
may be inactive. Products are created when the reaction takes place
(although the reacants are not consumed in this model).
For the moment we're going to use a simple representation for
molecules to represent them. Later on, we'll want a more detailed
representation for molecules. Type can be one of three options: s,
ns, or ins. S stands for specific; molecules that fall into this
category tend to be large, multi-carbon molecules. NS is non-specific;
these are molecules like water or hydrogen that are present in
practically inexhaustible amounts. INS stands for interesting
non-specific; these are molecules like ATP, ADP, or C02, that
contain atoms (P and C) that we want to keep track of.
And let's have a function that finds a molecule by abbreviation:
[If you are running this tutorial live, the [DO
IT] button for the following two definitions will only work on FireFox
because of a length limitation in Internet Explorer. If you only have
IE, you can manually enter these definitions, but you'll have to
remove the >> marks. Sorry for the inconvenience.]
>> (defun add-molecules ()
>> (setq *molecules* nil)
>> (add-molecule P "phosphatate" ins)
>> (add-molecule C "carbon" ins)
>> (add-molecule aden "adenosine" ns)
>> (add-molecule guan "guanosine" ns)
>> (add-molecule H+ "H+" ns)
>> (add-molecule H2O "H2O" ns)
>> (add-molecule NAD+ "NAD+" ns)
>> (add-molecule FAD "FAD" ns)
>> (add-molecule coa "CoA" s)
>> (add-molecule atp "ATP" ins)
>> (add-molecule adp "ADP" ins)
>> (add-molecule gdp "GDP" ins)
>> (add-molecule gtp "GTP" ins)
>> (add-molecule NADH "NADH" ns)
>> (add-molecule CO2 "Co2" ins)
>> (add-molecule FADH2 "FADH2" ns)
>> (add-molecule glu "glucose" s)
>> (add-molecule fru "fructose" s)
>> (add-molecule dha "dihydroxyacetone" s)
>> (add-molecule glh "glyceraldehyde" s)
>> (add-molecule gla "glycerate" s)
>> (add-molecule pyr "pyruvate" s)
>> (add-molecule ace "acetyl" s)
>> (add-molecule oxa "oxaloacetate" s)
>> (add-molecule cit "citrate" s)
>> (add-molecule ict "isocitrate" s)
>> (add-molecule akg "a-ketoglutarate" s)
>> (add-molecule suc "succinate" s)
>> (add-molecule fum "fumarate" s)
>> (add-molecule mal "malate" s)
>> (add-molecule g6p "glucose 6-phosphate" s)
>> (add-molecule f1p "fructose 1-phosphate" s)
>> (add-molecule f6p "fructose 6-phosphate" s)
>> (add-molecule fbp "fructose 1,6 bisphosphate" s)
>> (add-molecule dap "dihydrozyacetone phosphate" s)
>> (add-molecule g3p "glyceraldehyde 3-phosphate" s)
>> (add-molecule bpg "1,3-bisphosphoglycerate" s)
>> (add-molecule 3pg "3-phosphoglycerate" s)
>> (add-molecule 2pg "2-phosphoglycerate" s)
>> (add-molecule pep "phosphoenolpyruvate" s)
>> (add-molecule aca "acetyl CoA" s)
>> (add-molecule sca "succinyl CoA" s)
>> )
>> (defun add-reactions ()
>> (setq *reactions* nil)
>> (add-reaction (fru) (f1p) "Fructokinase")
>> (add-reaction (f1p) (glh dap) "Fructose 1-phosphate aldolase")
>> (add-reaction (glh) (g3p) "G3p kinase")
>> (add-reaction (glu atp) (g6p adp) "Hexokinase")
>> (add-reaction (g6p) (f6p) "Phosphoglucomutase")
>> (add-reaction (f6p atp) (fbp adp) "Phosphofructokinase")
>> (add-reaction (fbp) (dap g3p) "Aldolase")
>> (add-reaction (dap) (g3p) "Isomerase")
>> (add-reaction (P NAD+ g3p) (NADH H+ bpg) "G3p dehydrogenase")
>> (add-reaction (bpg adp) (3pg atp) "Phosphoglycerate kinase")
>> (add-reaction (3pg) (2pg) "Phosphoglyceromutase")
>> (add-reaction (2pg) (pep H2O) "Enolase")
>> (add-reaction (pep atp) (pyr adp) "Pyruvate kinase")
>> (add-reaction (pyr NAD+ coa) (NADH H+ CO2 aca) "Citrate synthase")
>> (add-reaction (cit) (ict) "Aconitase")
>> (add-reaction (ict NAD+) (akg NADH H+ CO2) "Isocitrate dehydrogenase")
>> (add-reaction (akg NAD+ coa) (sca NADH H+ CO2) "a-ketogluterate dehydrogenase complex")
>> (add-reaction (sca gdp P) (suc gtp coa) "Succinyl CoA synthase")
>> (add-reaction (suc FAD) (fum FADH2) "Succinate dehydrogenase")
>> (add-reaction (fum H2O) (mal) "Fumerase")
>> (add-reaction (mal NAD+) (oxa NADH H+) "Malate dehydrogenase")
>> )
Let's init everything and check out the various globals that we've
defined to make sure that everything's cool so far. (We'll also write
a pretty-printer for reactions here.)
This gets us the whole list of them:
So we need a way to find all the reactions that apply in the current
environment:
So, there are two reactions that apply in the initial environment from
along the list of, what was it?, 21 reactions. Now we need to be able
to update the environment according to the plausible reactions:
Okay, so now we're ready to implement the grand plan, as above:
Uh oh... you should be able to see that there's already going to be a
little problem here. Presumably, since we're never removing anything
from the environment, the list of possible reactions can only get
bigger, not smaller, so unless we're extremely lucky and run into our
goal molecule accidentally and nearly immediately, we're just going to
keep executing the same reaction over and over! (You can prove this
to yourself by trying to call (paths *env* *goal*) as defined above
and see if it ever returns, but set your timeout preference to
something like 2 seconds first or you'll quickly fill memory with
ever-growing chemical junk! -- or better, don't do it at all -- just
take my word that it will go into a loop!)
One way to resolve this is to never permit the same reaction to be run
twice on the same search path.
It's easy to fix this problem by simply removing pathways that are
either set-duplicates of others; that is, that have the same set of
reactions, or that are supersets of others. (Why do we want to drop
supersets instead of just dropping duplicates?)
Now, there are two problems with the approach we've been using so far.
First, it won't scale up very well; with only 21 reactions we created
nearly 10,000 paths, most of which turned out to be redundant. When
there are thousands of known reactions, as there are in any
reasonably sized organism, there's no way that we'll be able to get
away with the complete-search approach that we used above.
It turns out that there's an easy way to make this much more
efficient. In the foregoing code, we search through every possible
reaction that could apply in the environment at every step. Although
this is a good simulation method, it isn't how you'd do it if
you were thinking through the reaction pathways -- that is, if you
were forming an explanation to yourself -- would you? Probably you'd
only bother to look at the reactions that could apply, and that
were linked to the previous reaction in the pathway! In other
words, you'd only bother with those reactions that had reactants (left
hand side molecules) that matched one of the products (the right hand
side molecules) from the previous reaction! (Otherwise, what's the
point of having a pathway if the reactions don't link up?!)
This is called "constraining the search" -- in this case:
"constraining the search to only track reactions that link to the
previous reaction in the pathway."
While we're thinking about constraint, let's add one more efficiency
constraint, which is that we're only going to track type "S"
(specific) molecules This avoids tracking things like ATP that go
everyplace!
Let's code that in Lisp:
Notice that we didn't even bother to do superset duplicate removal
because I think that that was a result of insufficient constraint, and
we won't need it this time. I'm so confident that this is
going to be so much faster than the old search, we're not even
going to compile these functions!
So, that's a much better way to do dynamic pathway creation!
Remember that above I said there were two problems, but we only
dealt with one of them (inefficiency). The second problem will become
apparent if you carefully examine then example that we gave at the
very beginning of this section (here's one of the two again, with
slightly different highlighting):
What happens if we ask PATHTO
to find one of the molecules in the TCA cycle, for example, MALATE:
In the next tutorial we'll see how to resolve both of these problems.,
but I think that this lesson has gotten pretty long already, so let's
take a break and come back to these problem in the next sections.
(Exercises for this tutorial are at the end of the next one!)
Copyright 2002-2006 by The BioBike Team (contact<EMAIL_ADDRESS>Introduction to Biochemical Pathways
In this section we're going to do some pure symbolic reasoning about
metabolic pathways. There are several sections on this topic,
beginning (here) with the simplest sort of reasoning wherein we
dynamically find pathways among sets of reactions. In later sections
we'll both undertake technical improvements in the methods developed
here, and we'll expand to include a little bit pathway-based
microarray interpretation, and even some interesting cases of
automated discovery.
fructose ---[Fructokinase (FRK)]--> fructose 1-phosphate
represents a biochemical reaction. In the above case, the enzyme
"Fructokinase" (abbreviated "FRK") catalyzes the reaction that changes
fructose into fructose 1-phosphate.
phosphatate + NAD+ + glyceraldehyde 3-phosphate ---[G3p dehydrogenase (GAPDH)]--> NADH + H+ + 1,3-bisphosphoglycerate
This one has several reactants (on the left side) and products (on the right side).
Pathway #1
fructose ---[Fructokinase (FRK)]--> fructose 1-phosphate
fructose 1-phosphate ---[Fructose 1-phosphate aldolase (F1PA)]--> glyceraldehyde + dihydrozyacetone phosphate
dihydrozyacetone phosphate ---[Isomerase (ISO)]--> glyceraldehyde 3-phosphate
phosphatate + NAD+ + glyceraldehyde 3-phosphate ---[G3p dehydrogenase (GAPDH)]--> NADH + H+ + 1,3-bisphosphoglycerate
1,3-bisphosphoglycerate + ADP ---[Phosphoglycerate kinase (PGK)]--> 3-phosphoglycerate + ATP
3-phosphoglycerate ---[Phosphoglyceromutase (PYM)]--> 2-phosphoglycerate
2-phosphoglycerate ---[Enolase (ENO)]--> phosphoenolpyruvate + H2O
phosphoenolpyruvate + ATP ---[Pyruvate kinase (PYK)]--> pyruvate + ADP
malate + NAD+ ---[Malate dehydrogenase (MDH)]--> oxaloacetate + NADH + H+
pyruvate + NAD+ + CoA ---[ NIL]--> NADH + H+ + Co2 + acetyl CoA
acetyl CoA + oxaloacetate ---[Citrate synthase (CSY)]--> citrate + CoA
citrate ---[Aconitase (ACT)]--> isocitrate
isocitrate + NAD+ ---[Isocitrate dehydrogenase (IDH)]--> a-ketoglutarate + NADH + H+ + Co2
a-ketoglutarate + NAD+ + CoA ---[a-ketogluterate dehydrogenase complex (ADHC)]--> succinyl CoA + NADH + H+ + Co2
succinyl CoA + GDP + phosphatate ---[Succinyl CoA synthase (SCS)]--> succinate + GTP + CoA
succinate + FAD ---[Succinate dehydrogenase (SDH)]--> fumarate + FADH2
fumarate + H2O ---[Fumerase (FAS)]--> malate
--------------------------------
Pathway #2
glucose + ATP ---[Hexokinase (HXK)]--> glucose 6-phosphate + ADP
glucose 6-phosphate ---[Phosphoglucomutase (PGM)]--> fructose 6-phosphate
fructose 6-phosphate + ATP ---[Phosphofructokinase (PFK)]--> fructose 1,6 bisphosphate + ADP
fructose 1,6 bisphosphate ---[Aldolase (ALD)]--> dihydrozyacetone phosphate + glyceraldehyde 3-phosphate
phosphatate + NAD+ + glyceraldehyde 3-phosphate ---[G3p dehydrogenase (GAPDH)]--> NADH + H+ + 1,3-bisphosphoglycerate
1,3-bisphosphoglycerate + ADP ---[Phosphoglycerate kinase (PGK)]--> 3-phosphoglycerate + ATP
3-phosphoglycerate ---[Phosphoglyceromutase (PYM)]--> 2-phosphoglycerate
2-phosphoglycerate ---[Enolase (ENO)]--> phosphoenolpyruvate + H2O
phosphoenolpyruvate + ATP ---[Pyruvate kinase (PYK)]--> pyruvate + ADP
malate + NAD+ ---[Malate dehydrogenase (MDH)]--> oxaloacetate + NADH + H+
pyruvate + NAD+ + CoA ---[ NIL]--> NADH + H+ + Co2 + acetyl CoA
acetyl CoA + oxaloacetate ---[Citrate synthase (CSY)]--> citrate + CoA
citrate ---[Aconitase (ACT)]--> isocitrate
isocitrate + NAD+ ---[Isocitrate dehydrogenase (IDH)]--> a-ketoglutarate + NADH + H+ + Co2
a-ketoglutarate + NAD+ + CoA ---[a-ketogluterate dehydrogenase complex (ADHC)]--> succinyl CoA + NADH + H+ + Co2
succinyl CoA + GDP + phosphatate ---[Succinyl CoA synthase (SCS)]--> succinate + GTP + CoA
succinate + FAD ---[Succinate dehydrogenase (SDH)]--> fumarate + FADH2
fumarate + H2O ---[Fumerase (FAS)]--> malate
(The above output is produced by a program written by me (Jeff
Shrager) and Julian Brooke, recently of Stanford University. Much of
the code in these sections on metabolic pathway analysis is based on
our original code.)
Static versus Dynamic Pathways
Now, I didn't just write those pathways into the computer, although I
could have done that, and some important "pathways knowledge bases",
such as BioCyc and Kegg, have pathways built into them in that way.
But biochemical pathways are really a fiction of sorts; they are an
explanation of how the cell gets from one molecule to another
by using a series of (usually catalyzed) biochemical reactions. For
this, and a variety of other reasons, we really want to find
(that is compute!) pathways, not just write them down from a
textbook. I call precomputed pathways "Static" or "Stryer" or
"S-Pathways" (after the author of the most common biochemistry
textbook: Stryer). But what we want is "dynamic" or "D-Pathways" that
we compute on the fly!
Result of Pathway Computation
Organism : all
Initial substrate : C00293 Glucose
Final product : C00022 Pyruvate
Cutoff length : 8
Relaxation : No relaxation
Number of Results : 30
[Show as Diagram]
3 C00293 <<IP_ADDRESS>> C00089 <<IP_ADDRESS>> C00615 <<IP_ADDRESS>> C00022
4 C00293 <<IP_ADDRESS>> C00132 <<IP_ADDRESS>> C00067 <<IP_ADDRESS>> C00058 <<IP_ADDRESS>> C00022
4 C00293 <<IP_ADDRESS>> C00132 <<IP_ADDRESS>> C00067 <<IP_ADDRESS>> C00184 <<IP_ADDRESS>> C00022
...
Building our own Dynamic Pathway Calculator
Representing Molecules and Reactions
Let's see how Kegg did that! We're going to build an explicit
computational representation of biochemical reactions, and get the
computer to build pathways for us. After that we'll actually go
farther, and break some of the reactions in a simulated "knockout"
experiment (that is, we're going to knock out one of the genes that
codes for the enzymes that catalyzes the reactions that participate in
the pathways); We'll see that we can get the computer to "discover"
new plausible reactions that might fill in the gap left by this
knockout.
>>(defstruct reaction
>> reactants
>> catalyst
>> products
>> )
>> (defstruct molecule
>> abbrev
>> fullname
>> type
>> )
We're going to keep all of the molecules in a global variable called
*MOLECULES*, and similarly with reactions:
>> (defvar *molecules* nil)
>> (defvar *reactions* nil)
Okay, so now we can set up some molecules and reactions. We'll define
a couple of macros to make this a little simpler:
>> (defmacro add-molecule (abbrev fullname type &rest constituents)
>> `(push (make-molecule :abbrev ',abbrev
>> :fullname ,fullname
>> :type ',type)
>> *molecules*))
(Macros are probably new to you! We're not going to go into them
much. Just briefly: Whereas a function takes the values of its
arguments, does some calculation and returns a result, a macro take the
form of the arguments, does some calculation on the form
and returns an expression that, when you evalulate it, does some
calculation on the values of the argument. This is way
too meta for the moment! All you need to understand is that macros
save you from having to single-quote things that you don't want
evaluated, so they're useful for data entry, which is how they are
being used here!)
>> (defun find-molecule (abbrev)
>> ;; Comment test.
>> (find abbrev *molecules* :key #'molecule-abbrev))
;;; Same thing, but for a list of abbreviations.
>> (defun find-molecules (abbrevs)
>> (remove nil (mapcar #'find-molecule abbrevs)))
>> (defun find-molecule (abbrev)
>> (loop for molecule in *molecules*
>> when (eq (molecule-abbrev molecule) abbrev)
>> do (return molecule)))
Now we can use the molecular abbreviations to define reactions:
>> (defmacro add-reaction (reactants products enzyme)
>> (unless (listp reactants) (setq reactants (list reactants)))
>> (unless (listp products) (setq products (list products)))
>> `(push (make-reaction :reactants (find-molecules ',reactants)
>> :catalyst ',enzyme
>> :products (find-molecules ',products)
>> )
>> *reactions*))
>> (defun init-objects ()
>> (add-molecules)
>> (add-reactions)
>> )
Notice that through the use of the abbrev field, the reactions can
conveniently refer to the molecules.
>> (init-objects)
>> (length *molecules*)
:: 42 ; That seems plausible...
>> (length *reactions*)
:: 21 ; Okay, also seems right.
>> (pprint *reactions*)
(#S(REACTION :REACTANTS (#S(MOLECULE # # #) #S(MOLECULE # # #)) :CATALYST "Malate dehydrogenase"
:PRODUCTS (#S(MOLECULE # # #) #S(MOLECULE # # #) #S(MOLECULE # # #)))
#S(REACTION :REACTANTS (#S(MOLECULE # # #) #S(MOLECULE # # #)) :CATALYST "Fumerase" :PRODUCTS (#S(MOLECULE # # #)))
#S(REACTION :REACTANTS (#S(MOLECULE # # #) #S(MOLECULE # # #)) :CATALYST "Succinate dehydrogenase"
:PRODUCTS (#S(MOLECULE # # #) #S(MOLECULE # # #)))
#S(...) ...)
Ugh! We're gonna need a pretty-printer for reactions:
>> (defun pp-reaction (r)
>> (let* ((catalyst (reaction-catalyst r))
>> (reactants (reaction-reactants r))
>> (products (reaction-products r))
>> )
>> (pp-mols reactants)
>> (format t " --[~a]--> " catalyst)
>> (pp-mols products)
>> (format t "~%"))
>> r)
>> (defun pp-mols (m*)
>> (loop for m+ on m*
>> do (format t "~A" (molecule-fullname (car m+)))
>> (when (cdr m+)
>> (format t " + "))))
>> (pp-reaction (car *reactions*))
:: malate + NAD+ ---[Malate dehydrogenase]--> oxaloacetate + NADH + H+
Ahhhh. Much nicer!
>> (defmacro pp-reactions (reactions)
>> `(loop for reaction in ,reactions
>> do (pp-reaction reaction)))
>> (pp-reactions *reactions*)
:: ; [I won't bore you by repeating the BioBike output...]
Notice that the reaction left and righthand sides (reactants and
products) are composed of lists of actual molecule objects, not just
the name of the molecules, but the molecule objects themselves!
The Logic of Logic of Pathway Tracing
Now, let's think about the goal of the program; We want to find a path
between two arbitrary molecules, like glucose and pyruvate. But what's
really going on is that we're trying to find out what happens
biochemically in the cell. The cell is blooming buzzing confusion of
molecules and enzymes and other junk, so we're going to define that by
a thing called an "environment", which is just a list of things that
happen to be around:
>> (defvar *env* nil)
>> (defun init-env ()
>> (setq *env*
>> (find-molecules '(frk f1pa tk atp adp gdp gtp fru glu NAD+ FAD P hxk pfk pgm ald
>> gapdh pgk pym eno pyk iso csy act idh adhc scs sdh fas mdh))))
We also need a way to figure out that we're done (otherwise we can
just keep running reactions forever!) To do that we'll define a
specific goal molecule, which, when it shows up in the environment,
indicates that we're done. For now we'll set up the goal to be malate:
>> (defvar *goal* nil)
>> (defun init-goal ()
>> (setq *goal* (find-molecule 'mal)))
Oh, and while we're at it, we need a master init function:
>> (defun init ()
>> (init-objects)
>> (init-env)
>> (init-goal))
Remember to actually call it!
>> (init)
Now we're ready to address the problem of getting from the start-state
to the goal state; that is, from the environment without malate, but
with a bunch of other stuff floating about, to the environment
with malate (as well as whatever other intermediates get left
around as well). This is conceptually a simple simulation and search
problem, which can be described as follows:
>> (defun possible-reactions (env)
>> (loop for reaction in *reactions*
>> when (loop for reactant in (reaction-reactants reaction)
>> when (not (find reactant env))
>> do (return nil)
>> finally (return t))
>> collect reaction))
Let's try this out, since it will be so important in what's to come:
>> (init)
>> (possible-reactions *env*)
(#S(REACTION :REACTANTS (#S(MOLECULE # # #) #S(MOLECULE # # #)) :CATALYST "Hexokinase"
:PRODUCTS (#S(MOLECULE # # #) #S(MOLECULE # # #)))
#S(REACTION :REACTANTS (#S(MOLECULE # # #)) :CATALYST "Fructokinase" :PRODUCTS (#S(MOLECULE # # #))))
That's kind of ugly, let's have a way to print a list of them:
>> (pp-reactions (possible-reactions *env*))
glucose + ATP ---[Hexokinase]--> glucose 6-phosphate + ADP
fructose ---[Fructokinase]--> fructose 1-phosphate
Much nicer!
;;; Non-destructively and non-redundantly add all the products
;;; to the environment from a possible reaction.
>> (defun apply-reaction (reaction env)
>> (loop for product in (reaction-products reaction)
>> do (pushnew product env))
>> env)
And try it out:
>> (length *env*)
:: 9
>> (pp-reaction (setq r1 (first (possible-reactions *env*))))
glucose + ATP ---[Hexokinase]--> glucose 6-phosphate + ADP
>> (length (apply-reaction r1 *env*))
:: 10
So, by running this reaction we added one more molecule to the
environment. (Why did only one get added when there are two products
specified in the reaction?)
>> (defun paths (env goal &optional path)
>> (cond ((find goal env) (list path))
>> (t (loop for reaction in (possible-reactions env)
>> append (paths (apply-reaction reaction env)
>> goal
>> (cons reaction path))))))
Notice that the recursive step adds the current reaction to the head
of the path, and that the final case (when we find the goal) returns a
LIST of the path so that the APPEND collector can automatically remove
NIL's from the path. (This is textbook Lisp; Go back to your
textbooks!)
Heading Off a Probable Problem (An Inifinite Loop)
Now, before we try this, let's think for a moment about what it's
going to do. We're going to find all the reactions that can apply
in the current environment, and apply the first one, then the next and
then the next, etc. Each time we do that, we recursively do that same
thing again, that is: find all the reactions that can apply in the
current environment, and apply the first one, then the next and then
the next, etc.
>> (defun paths (env goal &optional path)
>> (cond ((find goal env) (list path))
>> (t (loop for reaction in (loop for reaction in (possible-reactions env)
>> when (not (member reaction path))
>> collect reaction)
>> append (paths (apply-reaction reaction env) goal (cons reaction path))))
>> ))
Let's Take it Out for a Spin
Okay, so let's try it out with a simple experiment first, and ensure that
we can get to some of the early goals (and make ourselves a convenient macro):
>> (defmacro pathsto (goal)
>> `(length (setq *pathways*
>> (paths *env* (find-molecule ',goal)))))
>> (pathsto g6p)
:: 57
So there are 57 pathways between whatever molecules are in *ENV*, and
glucose 6-phosphate (g6p). Let's look at one. Conveniently, PATHSTO
has left the results in *PATHWAYS*:
>> (first *pathways*)
(#S(REACTION :REACTANTS (#S(MOLECULE # # #) #S(MOLECULE # # #)) :CATALYST "Hexokinase"
:PRODUCTS (#S(MOLECULE # # #) #S(MOLECULE # # #))))
Oops; I meant this:
>> (pp-reactions (first *pathways*))
glucose + ATP --[Hexokinase]--> glucose 6-phosphate + ADP
Well, that's kinda boring, but right, I suppose. Let's try something
a little more challenging:
>> (pathsto pyr)
:: 9490
Yow!
>> (pp-reactions (first *pathways*))
phosphoenolpyruvate + ATP --[Pyruvate kinase]--> pyruvate + ADP
2-phosphoglycerate --[Enolase]--> phosphoenolpyruvate + H2O
3-phosphoglycerate --[Phosphoglyceromutase]--> 2-phosphoglycerate
1,3-bisphosphoglycerate + ADP --[Phosphoglycerate kinase]--> 3-phosphoglycerate + ATP
glyceraldehyde 3-phosphate + NAD+ + phosphatate --[G3p dehydrogenase]--> 1,3-bisphosphoglycerate + NADH + H+
fructose 1,6 bisphosphate --[Aldolase]--> glyceraldehyde 3-phosphate + dihydrozyacetone phosphate
fructose 6-phosphate + ATP --[Phosphofructokinase]--> fructose 1,6 bisphosphate + ADP
glucose 6-phosphate --[Phosphoglucomutase]--> fructose 6-phosphate
glucose + ATP --[Hexokinase]--> glucose 6-phosphate + ADP
Hey, they're backwards! That's because we're collecting them in the
head of the path list as we go deeper into the recursion. So, reading
backwards makes it a little more understandable.
Oops; Another Little Problem (Redundant Paths)
But there are a TON of them (9490 to be exact!) How could there be so
many solutions to the same place where there are only 21 reactions in
the whole knowledge base!? Maybe it's just that the order of the reactions
appears differently in the reaction list. This could happen because
we're searching the entire space of all possible orders of
reactions in every possible order, so if the environment allows
reactions to happen in different orders, but still get to the same
place, then we will see two different pathways.
;;; When the current path is NOT a superset of
;;; anything else in the path list then collect it.
;;; (Careful not to remove it when it matches itself!)
>> (defun remove-duplicate-paths (path*)
>> (loop for this-path in path*
>> when (loop for target-path in path*
>> when (and (not (eq this-path target-path))
>> (superset? this-path target-path))
>> do (return nil)
>> finally (return t))
>> collect this-path))
>> (defun superset? (s1 s2)
>> (and (>= (length s1) (length s2))
>> (every #'(lambda (s) (member s s1)) s2)))
We have to remake our PATHTO macro:
>> (defmacro pathsto (goal)
>> `(length (setq *pathways*
>> (remove-duplicate-paths
>> (paths *env* (find-molecule ',goal))))))
Okay, let's give it a try now:
>> (pathsto pyr)
:: 3
Ah, much better! It makes a lot more sense for there to be 3
different paths than 10,000 of them! Let's use PP-REACTIONS to look
at them all (let's also reverse them, so they come out in order).
>> (defun ppp (&optional (pwys *pathways*))
>> (loop for path-n from 1 by 1
>> as path in pwys
>> do (format t "~%~%Pathway #~a:~%~%" path-n)
>> (pp-reactions (reverse path))))
>> (ppp)
Pathway #1:
glucose + ATP --[Hexokinase]--> glucose 6-phosphate + ADP
glucose 6-phosphate --[Phosphoglucomutase]--> fructose 6-phosphate
fructose 6-phosphate + ATP --[Phosphofructokinase]--> fructose 1,6 bisphosphate + ADP
fructose 1,6 bisphosphate --[Aldolase]--> glyceraldehyde 3-phosphate + dihydrozyacetone phosphate
glyceraldehyde 3-phosphate + NAD+ + phosphatate --[G3p dehydrogenase]--> 1,3-bisphosphoglycerate + NADH + H+
1,3-bisphosphoglycerate + ADP --[Phosphoglycerate kinase]--> 3-phosphoglycerate + ATP
3-phosphoglycerate --[Phosphoglyceromutase]--> 2-phosphoglycerate
2-phosphoglycerate --[Enolase]--> phosphoenolpyruvate + H2O
phosphoenolpyruvate + ATP --[Pyruvate kinase]--> pyruvate + ADP
Pathway #2:
fructose --[Fructokinase]--> fructose 1-phosphate
fructose 1-phosphate --[Fructose 1-phosphate aldolase]--> dihydrozyacetone phosphate + glyceraldehyde
dihydrozyacetone phosphate --[Isomerase]--> glyceraldehyde 3-phosphate
glyceraldehyde 3-phosphate + NAD+ + phosphatate --[G3p dehydrogenase]--> 1,3-bisphosphoglycerate + NADH + H+
1,3-bisphosphoglycerate + ADP --[Phosphoglycerate kinase]--> 3-phosphoglycerate + ATP
3-phosphoglycerate --[Phosphoglyceromutase]--> 2-phosphoglycerate
2-phosphoglycerate --[Enolase]--> phosphoenolpyruvate + H2O
phosphoenolpyruvate + ATP --[Pyruvate kinase]--> pyruvate + ADP
Pathway #3:
fructose --[Fructokinase]--> fructose 1-phosphate
fructose 1-phosphate --[Fructose 1-phosphate aldolase]--> dihydrozyacetone phosphate + glyceraldehyde
glyceraldehyde --[G3p kinase]--> glyceraldehyde 3-phosphate
glyceraldehyde 3-phosphate + NAD+ + phosphatate --[G3p dehydrogenase]--> 1,3-bisphosphoglycerate + NADH + H+
1,3-bisphosphoglycerate + ADP --[Phosphoglycerate kinase]--> 3-phosphoglycerate + ATP
3-phosphoglycerate --[Phosphoglyceromutase]--> 2-phosphoglycerate
2-phosphoglycerate --[Enolase]--> phosphoenolpyruvate + H2O
phosphoenolpyruvate + ATP --[Pyruvate kinase]--> pyruvate + ADP
NIL
Wow; Looks great! There's one path from glucose, and two from
fructose, one of which (#2) goes via Isomerase, and the other (#3)
goes through G3p kinase.
Making it a Little More Efficient
Let's return to the concept at the beginning of this section that
pathways arise from explanations. The PATHSTO function is
essentially simulating the biochemistry of the cell (in a
somewhat abstract way), but another way of thinking about what it is
doing is as forming explanations -- that is: finding ways to go
between a set of initial conditions (the environment, encoded in
*ENV*) to a final state (the environment plus the goal). In what sense
is this an "explanation?" In what sense a "simulation?" Might
explanation and simulation be part-and-parcel of the same thing???
;;; We have to come from a particular molecule, and we have to pass
;;; the pathway down along with us, so that we can use the previous
;;; reaction to constrain the search.
>> (defun paths-between (from to &optional (env *env*) path)
>> (cond ((member to env) (list path)) ; If we've found our goal, we're done! (LIST for appends up the stack.)
>> (t (loop for reaction in (possible-reactions-from from env)
>> when (not (member reaction path))
>> append (paths-via (cons reaction path) to (apply-reaction reaction env))))
>> ))
;;; Track each SPECIFIC reaction product molecule into a new path.
>> (defun paths-via (path to env)
>> (loop for link-mol in (reaction-products (car path))
>> when (eq 's (molecule-type link-mol))
>> append (paths-between link-mol to env path)))
;;; This is a constrained version of POSSIBLE-REACTIONS.
;;; The only difference is the (AND (MEMBER ...) ...) which
;;; ensures that the reaction chosen also links to the FROM molecule.
>> (defun possible-reactions-from (from env)
>> (loop for reaction in *reactions*
>> as reactants = (reaction-reactants reaction)
>> when (and (member from reactants)
>> (loop for reactant in reactants
>> when (not (find reactant env))
>> do (return nil)
>> finally (return t)))
>> collect reaction))
;;; And we'll make a new PATHTO for this search as well; We'll
;;; call it FPATHSTO -- F for "Fast"! This version doesn't even
;;; do the superset duplicate removal!
>> (defmacro fpathsto (from to)
>> `(length (setq *pathways*
>> (paths-between (find-molecule ',from)
>> (find-molecule ',to)
>> *env*))))
There's one small functional difference between the way that this
works, and the way that the old search worked; Here we need to tell it
which molecule to start off from (whereas before it used to just start
from every molecule in the environment). This will add constraints as
well, but it requires us to choose a starting molecule. This isn't
too unnatural as, again, when you're thinking through pathways you
are usually trying to go from one molecule to another.
>> (fpathsto glu pyr)
:: 2
Compare that with 9490 before we did duplicate removal above! But
there really should be only one pathway from glucose if we're to
believe our previous results. Let's look at the two we got:
>> (ppp)
Pathway #1:
glucose + ATP --[Hexokinase]--> glucose 6-phosphate + ADP
glucose 6-phosphate --[Phosphoglucomutase]--> fructose 6-phosphate
fructose 6-phosphate + ATP --[Phosphofructokinase]--> fructose 1,6 bisphosphate + ADP
fructose 1,6 bisphosphate --[Aldolase]--> glyceraldehyde 3-phosphate + dihydrozyacetone phosphate
glyceraldehyde 3-phosphate + NAD+ + phosphatate --[G3p dehydrogenase]--> 1,3-bisphosphoglycerate + NADH + H+
1,3-bisphosphoglycerate + ADP --[Phosphoglycerate kinase]--> 3-phosphoglycerate + ATP
3-phosphoglycerate --[Phosphoglyceromutase]--> 2-phosphoglycerate
2-phosphoglycerate --[Enolase]--> phosphoenolpyruvate + H2O
phosphoenolpyruvate + ATP --[Pyruvate kinase]--> pyruvate + ADP
Pathway #2:
glucose + ATP --[Hexokinase]--> glucose 6-phosphate + ADP
glucose 6-phosphate --[Phosphoglucomutase]--> fructose 6-phosphate
fructose 6-phosphate + ATP --[Phosphofructokinase]--> fructose 1,6 bisphosphate + ADP
fructose 1,6 bisphosphate --[Aldolase]--> glyceraldehyde 3-phosphate + dihydrozyacetone phosphate
dihydrozyacetone phosphate --[Isomerase]--> glyceraldehyde 3-phosphate
glyceraldehyde 3-phosphate + NAD+ + phosphatate --[G3p dehydrogenase]--> 1,3-bisphosphoglycerate + NADH + H+
1,3-bisphosphoglycerate + ADP --[Phosphoglycerate kinase]--> 3-phosphoglycerate + ATP
3-phosphoglycerate --[Phosphoglyceromutase]--> 2-phosphoglycerate
2-phosphoglycerate --[Enolase]--> phosphoenolpyruvate + H2O
phosphoenolpyruvate + ATP --[Pyruvate kinase]--> pyruvate + ADP
The only difference is the Isomerase reaction. Superset duplicate
removal was removing this before, but we don't do that any longer. But
even without that, we got just the right pathways, and it isn't clear
whether or not you want the Isomerase superset pathway as it is
a legal pathway, after all!
Pathway #1
fructose ---[Fructokinase (FRK)]--> fructose 1-phosphate
fructose 1-phosphate ---[Fructose 1-phosphate aldolase (F1PA)]--> glyceraldehyde + dihydrozyacetone phosphate
dihydrozyacetone phosphate ---[Isomerase (ISO)]--> glyceraldehyde 3-phosphate
phosphatate + NAD+ + glyceraldehyde 3-phosphate ---[G3p dehydrogenase (GAPDH)]--> NADH + H+ + 1,3-bisphosphoglycerate
1,3-bisphosphoglycerate + ADP ---[Phosphoglycerate kinase (PGK)]--> 3-phosphoglycerate + ATP
3-phosphoglycerate ---[Phosphoglyceromutase (PYM)]--> 2-phosphoglycerate
2-phosphoglycerate ---[Enolase (ENO)]--> phosphoenolpyruvate + H2O
phosphoenolpyruvate + ATP ---[Pyruvate kinase (PYK)]--> pyruvate + ADP
malate + NAD+ ---[Malate dehydrogenase (MDH)]--> oxaloacetate + NADH + H+
pyruvate + NAD+ + CoA ---[ NIL]--> NADH + H+ + Co2 + acetyl CoA
acetyl CoA + oxaloacetate ---[Citrate synthase (CSY)]--> citrate + CoA
citrate ---[Aconitase (ACT)]--> isocitrate
isocitrate + NAD+ ---[Isocitrate dehydrogenase (IDH)]--> a-ketoglutarate + NADH + H+ + Co2
a-ketoglutarate + NAD+ + CoA ---[a-ketogluterate dehydrogenase complex (ADHC)]--> succinyl CoA + NADH + H+ + Co2
succinyl CoA + GDP + phosphatate ---[Succinyl CoA synthase (SCS)]--> succinate + GTP + CoA
succinate + FAD ---[Succinate dehydrogenase (SDH)]--> fumarate + FADH2
fumarate + H2O ---[Fumerase (FAS)]--> malate
The Problem with Cycles
There's something bizarre about the red path of this pathway: It's a
cycle! That is, it produces it's own starting products.
Specifically, it's the TCA cycle (TCA is for 'Tri-Carboxylic Acid';
it's also called the Citric Acid Cycle, or the Krebs Cycle). This
takes the pyruvate created in glycolysis and produce a bunch of
important molecules used as energy by the rest of your cellular
system. It also produces the carbon dioxide (CO2) that you eventually
breath out! Here's
a nice description of this important part of metabolism, along with
some nice 3D pictures of the enzymes that catalyze it!
>> (pathsto mal)
:: 0
>> (pathsto aca)
:: 0
etc...
Oops; what's up? If you closely examine the reactions that we've
given, and the environment, you'll see that we don't have all of the
required intermediates to enter the TCA cycle, and all the reactions
in the cycle require products from other reactions in the cycle! Ack!
How are we going to resolve this!?


7 days before take-off
7 days and 48 hours before take-off
48 hours and 4 hours before take-off
4 hours before take-off


SNIGDHA VERMA
An enthusiastic person is how I describe myself as. Exploring things and extending my horizon to reach new heights is what I love doing. Currently, I'm persuing Bachelors in the field of Technology, specialisation in Electronics and Communication stream.


Enumeration
methods that are used on collections and may be replaced with equivalent
Iterator
constructs.
Example:
Enumeration<String> keys = map.keys();
while (keys.hasMoreElements()) {
String name = keys.nextElement();
}
After the quick-fix is applied:
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String name = iterator.next();
}


WITNESS LIST Appropriations Committee March 29, 2003-7:00A Budget For: Barker, Ann (Self) Bell, Gene (Texas Diabetes Council) Berry, Jorey (March of Dimes) Block, Roy (Self and Texas Foster Family Association) Craven, Susan (Texans Care for Children) De Luna-Castro, Eva (Center for Public Policy Priorities) Forrester, Donald (Texas Baptist Chlidren's Homes and Family Services) Fox, Rhonda (Self) Freeman, Lana (Texas State Foster Parents) Garza, J.G. (Self and Texans Supporting State Schools; Parents Association for the Retarded of Texas) Gay, Clifford (Self) Guynn, MD, Robert (Harris County Psychiatric Center) Harracksingh, Rachel B. (Texas Ambulance Association) Hooser, Greg (Private Providers of Texas) Littlefield, Rita (Self and Texas Renal Coalition) Parker, PhD, Carolyn A. (Texas AIDS Network) Patterson, Blake (Deep East Texas Council of Government-STAR Program) Reed, Jeff (Self) Romberg, Peggy (Women's Health and Family Planning Association of Texas) Ross, DPM, MD, Dr. Jeffrey A. (Texas Diabetes Council; Governor's Fitness Advisory Council) Scott, Ron (Self and Robin McClanahan) Sokol, PhD, Marian (Self and Any Baby Can, Inc.) Steiner, Dwight (Self) Tod, Theresa (Texas Network of Youth Services) Tracy, Kevin P. (Self) Waddleton, Wayne (Deep East Texas Council of Government - STAR) Youngblood, Debra (Self and Texas Sunrise Services, Inc. - D.B.A. Daybreak) Against: Berry-Gordon, Bee (Self) Borel, Dennis (Coalition of Texans with Disabilities) Broussard, Ricky (Texas Advocates) Chastain, Lori (Self) Conner, Ben F. (Self) Conner, Gladys (Self) Criss, Judge Susan (Self) Derr, Patti (Self) Donelson, Olivia (Self) Esquveil, Faustino (Self) Ferguson, Charles (Self and Texans Supporting State Schools) Gantt, Melanie (Mental Health Association in Texas) Garnett, Dr. Richard (Arc of Texas) Gothart, Chance (Self) Gothart-Barron, Sherri (Self) Halligan, Mike (Texas Mental Health Consumers) Hankins, Barbara (League of Women Voters of Texas) Harris, Barbara (Self) Headrick, Carter (Campaign for Tobacco-Free Kids) Headrick, Kelly (American Cancer Society) Hedrick, Mary M. (Self) Hello, Darlene (Self) Hyatt, Deborah (Texas Federation of Families for Childrens Mental Health) Kafka, Bob (ADAPT of Texas) Kelly, Pamela (Reaching Maximum Independence) Kenney, Robert (Self) Kern, Diana (Self and National Alliance for the Mentall Ill of Texas) Lamb, Linda L. (Self) Landry, Todd A. (Spaulding for Children) Laursen, Victoria (Self) Martin, Jackie (Self) Martinez, Eleanor (Self) Martinez Jr., Juan D. (Self) McDurham, Doug (Self and Communities in Schools of Texas; Communities in Schools-McLennan County Youth Collaboration) McKay, Rebekah (Self) Miller, Jim (Self and Texans Supporting State Schools) Mizcles, Amy (The Arc of Texas) Moy, Diane Faucher (Self) Muckleroy, Penny (Self) Murphree, Susan (Self) Murray, Robert (Mission Road Developmental Center) Newhouse, Liz (Self and Epilepsy Coalition of Texas) Panks, Judy (Self) Ranson, Jude (Self) Shannon, Jackie (Self and NAMI of Texas) Simmons, Woody (Self) Smith, Carole Lynn (Private Providers Association of Texas) Snyder, Ruth (Self) Stephens, Mike (PART) Thomas, Stephanie (Self and ADAPT of Texas) Valdez, Arthur (Texas State Employees Union) Van Winkle, James (Self and Tri-County MH Consumers) Ward, Nancy (Self) On: Chapmond, Thomas (Department of Protective and Regulatory Services) Hale, Karen (Department of Mental Health and Mental Retardation) Hayes, Aaryce (Advocacy Inc.) Heckler, Jeff (Family Forward) Kelemen, George (AARP) Krueger, Donna (Department of Protective and Regulatory Services) Lutz, Judy (Department of Protective and Regulatory Services) Marshall, Susan (Texas Council for Developmental Disabilities) Minot, Reid (Texas Hospital Association) Mooney, Dr. Curtis (DePelchin Children's Center of Houston; Texas Alliance of Child and Family Services) Murphree, Susan (Advocacy Inc.) Pharr, Machelle (Department of Health) Sanchez, MD, Eduardo (Department of Health) Stabeno, Debra C. (Department of Health) Stanley, MD, Sharilyn K. (Department of Health) Wall, Matt (Texas Hospital Association) Weiss, Moonyeen (Self) Welsh, Dinah (Texas Hospital Association) Yelenosky, Stephen (Advocacy Inc.; Community Services Coalition)


Control Board is a RoboFont extension for communicating with Arduino-compatible devices using the Firmata library.
It turns physical input events from components connected to the Arduino (pressing buttons, toggling switches, turning knobs) into "ControlBoardInput" event notifications, and turns "ControlBoardOutput" notifications into changes in state of the output components connected to the board (toggling LEDs on and off or changing the color of RGB LEDs, moving motors, etc.)
It makes generous use of the Breakfastserial, pyFirmata and serial Python libraries:
Before you begin, Mac OS 10.9 and 10.10 users will need through a small process of updating the FTDI drivers that came with their computer, in order to be able to communicate with the Arduino.
You can read more about this requirement from the Arduino forum, or just follow the steps listed below.
http://forum.arduino.cc/index.php?topic=198539.01) Start by disabling the FTDI drivers that came with your Mac. From the Terminal, type the following commands
cd /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns sudo mv AppleUSBFTDI.kext AppleUSBFTDI.disabled sudo touch /System/Library/Extensions
2) Restart your computer
3) Then, install the correct FTDI drivers, found here:
http://www.ftdichip.com/Drivers/VCP.htm
You will want to choose either the 32-bit or 64-bit drivers depending on which Mac you have. To find out whether your machine is 32 or 64-bit, have a look here: https://support.apple.com/en-us/HT3696
4) After restarting your computer once more for good measure, you will be ready to communicate over USB with your Arduino.
To use Control Board, you'll need to upload the Standard Firmata library on your Arduino.
1) Start by downloading the Arduino IDE software:
http://arduino.cc/en/Main/Software
2) Plug in your Arduino, and launch the the Arduino application
3) From the "File" menu, open "Examples > Firmata > Standard Firmata"
4) From the Tools menu, under the "Board" section, choose which kind of Arduino board you're using, and from the "Serial Port" section, choose the name of a serial port which contains "USB".
5) Then, click the "Upload" button at the top of the StandardFirmata window, the button that has the image of an arrow.
If all goes well, in a moment your Arduino will have the Standard Firmata library installed on it, and you'll be ready to use Control Board. You will only need to set your Arduino up once, it will retain this Standard Firmata library until you upload a new program to it another time.
The concept is simple: wire up some basic electronic components to an Arduino's input and output pins, and list what these components are in the Control Board interface.
The "Input" components (buttons, switches, potentiometers) will broadcast "ControlBoardInput" notifications when their state has changed along with what their current state is. Likewise, when you broadcast a "ControlBoardOutput" notification from a separate script to an "Output" component (an LED, motor, etc.), its state will change.
Control Board will try to connect to the first Arduino it finds connected over USB, click "Reconnect" to try connecting again if the board was plugged in after Control Board was opened.
Once connected, set up your circuit components in the Control Board interface. For instance, if you have a button connected to pin #2, add an "Input: Button/Switch" component, choose pin 2, and give the component a name. Click "Apply" to send this configuration to your Arduino board.
Now, each time your click the button, "ControlBoardInput" notifications will happen.
The notifications will always have an "info" dictionary. The dictionary has a key for the "type" of component ("Button/Switch", "Sensor", etc.), a "name" which is the name that you gave the component in the interface, and either a "state" ("up", "down") or a "value" (a sensor value between 0 and 1).
To post your own notifications, import the following method from RoboFont's mojo library:
from mojo.events import postEvent
Then, post your notification event to the desired component name, with the state the component should take, along with other optional arguments depending on the component. For example, you can turn an LED on by posting the following event:
postEvent("ControlBoardOutput", name="My LED", state="on")and then turn it back off by posting this one:
postEvent("ControlBoardOutput", name="My LED", state="off")
For a full explanation of all component states and values, check out the sample code in the /Examples directory and the table of Component Notifications at the end of this document.
(Coming soon?)
The incoming notifications tell a lot about how a component's state changed, and an outgoing notification needs to carry the kinds of details about how an output component should change.
See the example code in the /Examples directory for a guide to using the notifications documented below.
The "name" value is always the name assigned to the component in the Control Board interface. Otherwise, here's an overview of the attributes received when observing for a "ControlBoardInput" or sent with a "ControlBoardOutput" notification:
Input: Button/Switch "name" "type": "Button" "name": The name assigned to the component in the interface "state": "up", "down", or "hold" when the button is held down for more than one second Input: Rotary Encoder "name" "type": "RotaryEncoder" "state": "changed" "value": "cw" if it was turned clockwise, or "ccw" if counter-clockwise Input: Analog Sensor (Potentiometer, LDR, pressure sensor) "name" "type": "AnalogSensor" "state": "changed" "value": A float between 0 and 1 of the current sensor value Output: LED "name" "state": "on", "off", "toggle", "blink" "value": When the state is "on", the value is a float between 0 and 1 to set the brightness of the LED, when state is "blink" the value is the frequency time in milliseconds Output: RGB LED "name" "state": "on", "off", "toggle", "blink" "value": When the state is "on", the value is either a float between 0 and 1 to set the brightness of all three components, a list of three float values for [R, G, B] between 0 and 1, or the string of the name of a color, such as "red", or "turquoise". When the state is "blink", the value is the value is the frequency time in milliseconds Output: Servo Motor "name" "position": The position the motor should turn to, in degrees between 0 and 180. Output: DC Motor "name" "state": "on", "off" "value": When the state is "on", the value is a float between 0 and 1 of the speed the motor should turn


fun withLowPowerMode(): ProximityObserverBuilder
Proximity observer will use battery efficient mode, but the scanning won't be super reliable.


class: center, middle, inverse, title-slide # Young Statisticians Workshop: Developing Your Career to Thrive in a Data-rich, Technology-driven, Reproducible Research Environment ## Organising data ### Di Cook (
<EMAIL_ADDRESS>,
@visnut
) ### 25/9/2017 --- # Overview - Terminology of statistical data exploration - Process of exploring data - Tidy vs messy data - Tidying data process - Wrangling your data --- # Exploratory data analysis "Data science is an exciting discipline that allows you to turn raw data into understanding, insight, and knowledge." [Grolemund and Wickham](http://r4ds.had.co.nz/introduction.html) Exploratory data analysis is the stage in the analysis where the analyst "plays in the sand" with their data to see what it has to tell them. It allows us to find the unexpected, and come to some understanding of the information that the data contains. [Cook and Swayne](http://www.ggobi.org/book/) --- # Exploring your data, stages - import - tidy - transform/wrangle/clean - visualise - model - communicate --- # Rectangular data - Variables are in the columns - A __variable__ is a quantity, quality, or property that you can measure. - A value is the state of a variable when you measure it. The value of a variable may change from measurement to measurement. - Observations are in the rows: An __observation__ is a set of measurements made under similar conditions (you usually make all of the measurements in an observation at the same time and on the same object). An observation will contain several values, each associated with a different variable. I’ll sometimes refer to an observation as a data point. - __Tabular data__ is a set of values, each associated with a variable and an observation. Tabular data is __tidy__ if each value is placed in its own "cell", each variable in its own column, and each observation in its own row.  We are going to work out what are the variables and what are the observations, to know what form we need to rearrange the data to get it into tidy form. --- # Example 1 What are the variables? Observations? ``` # A tibble: 6 x 4 Inst AvNumPubs AvNumCits PctCompletion <chr> <dbl> <dbl> <dbl> 1 ARIZONA STATE UNIVERSITY 0.90 1.57 31.7 2 AUBURN UNIVERSITY 0.79 0.64 44.4 3 BOSTON COLLEGE 0.51 1.03 46.8 4 BOSTON UNIVERSITY 0.49 2.66 34.2 5 BRANDEIS UNIVERSITY 0.30 3.03 48.7 6 BROWN UNIVERSITY 0.84 2.31 54.6 ``` Is it in tidy form? --- # Example 2 What are the variables? Observations? ``` # A tibble: 3 x 12 id `WI-6.R1` `WI-6.R2` `WI-6.R4` `WM-6.R1` `WM-6.R2` `WI-12.R1` <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 Gene 1 2.182424 2.2042219 4.195636 2.6273345 5.063641 4.540002 2 Gene 2 1.464224 0.5854472 1.859238 0.5152242 2.882808 1.364037 3 Gene 3 2.031792 0.8701078 3.281983 0.5330452 4.627315 2.182192 # ... with 5 more variables: `WI-12.R2` <dbl>, `WI-12.R4` <dbl>, # `WM-12.R1` <dbl>, `WM-12.R2` <dbl>, `WM-12.R4` <dbl> ``` --- # Example 3 What are the variables? Observations? ``` V1 V2 V3 V4 V5 V9 V13 V17 V21 V25 V29 V33 V37 V41 V45 V49 1 ASN00086282 1970 7 TMAX 141 124 113 123 148 149 139 153 123 108 119 112 2 ASN00086282 1970 7 TMIN 80 63 36 57 69 47 84 78 49 42 48 56 3 ASN00086282 1970 7 PRCP 3 30 0 0 36 3 0 0 10 23 3 0 4 ASN00086282 1970 8 TMAX 145 128 150 122 109 112 116 142 166 127 117 127 5 ASN00086282 1970 8 TMIN 50 61 75 67 41 51 48 -7 56 62 47 33 6 ASN00086282 1970 8 PRCP 0 66 0 53 13 3 8 0 0 0 3 5 V53 V57 V61 V65 V69 V73 V77 V81 V85 V89 V93 V97 1 126 112 115 133 134 126 104 143 141 134 117 142 2 51 36 44 39 40 58 15 33 51 74 39 66 3 5 0 0 0 0 0 8 0 18 0 0 0 4 159 143 114 65 113 125 129 147 161 168 178 161 5 67 84 11 41 18 50 22 28 74 94 73 88 6 0 0 64 3 99 36 8 0 0 0 8 36 ``` --- # Example 4 What are the variables? Observations? ``` # A tibble: 6 x 22 iso2 year m_04 m_514 m_014 m_1524 m_2534 m_3544 m_4554 m_5564 m_65 <chr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> 1 ZW 2003 NA NA<PHONE_NUMBER> 2228 981 367 205 2 ZW 2004 NA NA<PHONE_NUMBER> 2298 1056 366 198 3 ZW 2005 NA NA<PHONE_NUMBER> 1855 762 295 656 4 ZW 2006 NA NA<PHONE_NUMBER> 1939 896 348 199 5 ZW 2007 6 132<PHONE_NUMBER> 0 716 292 153 6 ZW 2008 NA NA 127 614 0 3316 704 263 185 # ... with 11 more variables: m_u <int>, f_04 <int>, f_514 <int>, # f_014 <int>, f_1524 <int>, f_2534 <int>, f_3544 <int>, f_4554 <int>, # f_5564 <int>, f_65 <int>, f_u <int> ``` --- # Example 5 ``` religion <$10k $10-20k $20-30k $30-40k 1 Agnostic 27 34 60 81 2 Atheist 12 27 37 52 3 Buddhist 27 21 30 34 4 Catholic 418 617 732 670 5 Don’t know/refused 15 14 15 11 ``` --- # Example 6 10 week sensory experiment, 12 individuals assessed taste of french fries on several scales (how potato-y, buttery, grassy, rancid, paint-y do they taste?), fried in one of 3 different oils, replicated twice.  What are the factors of the experiment? What was measured? What do you want to know? --- # Messy data patterns There are various features of messy data that one can observe in practice. Here are some of the more commonly observed patterns: - Column headers are values, not variable names - Variables are stored in both rows and columns, contingency table format - One type of experimental unit stored in multiple tables - Dates in many different formats - Every messy data set, is messy in its own way --- # What is tidy data? - Each observation forms a row - Each variable forms a column - Data is contained in a single table - Long form makes it easier to reshape in many different ways - Wide form is common for analysis --- # Tidy Same pieces, many different constructions (analogy from Hadley Wickham) ![](images/lego1.jpg) ![](images/lego2.jpg) ![](images/lego3.jpg) ![](images/lego4.jpg) ![](images/lego5.jpg) [Alan Chia/Creative Commons](https://commons.wikimedia.org/wiki/File:Lego_Color_Bricks.jpg), [dirkb86/Creative Commons](https://www.flickr.com/photos/dirkb86/8446019404/in/set-72157632691207934), [Joris/Creative Commons](https://www.wired.com/2012/08/dear-lego/), [brainbikerider/Creative Commons](https://amodularlife.wordpress.com/2010/07/26/new-sydney-opera-house-lego-set/), [Otto Normalverbraucher/Creative Commons](https://commons.wikimedia.org/wiki/File:Lego_Chicago_City_View_2001.jpg) --- # Messy Specialist pieces, limited options (analogy from Hadley Wickham) ![](images/playmobile1.jpg) [1971markus/Creative Commons](https://commons.wikimedia.org/wiki/File:Playmobil-Ochsenwagen-Modell_im_LWL-Römermuseum_in_Haltern.jpg) ![](images/playmobile2.jpg) [Angela V/Creative Commons](http://www.onesmileymonkey.com/reviews/toys-2/playmobils-adventure-tree-house-pickup-truck/) --- # Tidy verbs - `gather`: specify the **keys** (identifiers) and the **values** (measures) to make long form (used to be called melting) - `spread`: variables in columns (used to be called casting) - `nest`/`unnest`: working with list variables - `separate`/`unite`: split and combine columns --- # Tidying the example 2 data ```r genes <- read_csv("data/genes.csv") head(genes) # A tibble: 3 x 12 id `WI-6.R1` `WI-6.R2` `WI-6.R4` `WM-6.R1` `WM-6.R2` `WI-12.R1` <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 Gene 1 2.182424 2.2042219 4.195636 2.6273345 5.063641 4.540002 2 Gene 2 1.464224 0.5854472 1.859238 0.5152242 2.882808 1.364037 3 Gene 3 2.031792 0.8701078 3.281983 0.5330452 4.627315 2.182192 # ... with 5 more variables: `WI-12.R2` <dbl>, `WI-12.R4` <dbl>, # `WM-12.R1` <dbl>, `WM-12.R2` <dbl>, `WM-12.R4` <dbl> ``` --- # Gather column names into long form ```r gather(genes, variable, expr, -id) # A tibble: 33 x 3 id variable expr <chr> <chr> <dbl> 1 Gene 1 WI-6.R1 2.1824242 2 Gene 2 WI-6.R1 1.4642236 3 Gene 3 WI-6.R1 2.0317925 4 Gene 1 WI-6.R2 2.2042219 5 Gene 2 WI-6.R2 0.5854472 6 Gene 3 WI-6.R2 0.8701078 7 Gene 1 WI-6.R4 4.1956364 8 Gene 2 WI-6.R4 1.8592378 9 Gene 3 WI-6.R4 3.2819835 10 Gene 1 WM-6.R1 2.6273345 # ... with 23 more rows ``` --- # Separate columns ```r genes %>% gather(variable, expr, -id) %>% separate(variable, c("trt", "leftover"), "-") # A tibble: 33 x 4 id trt leftover expr * <chr> <chr> <chr> <dbl> 1 Gene 1 WI 6.R1 2.1824242 2 Gene 2 WI 6.R1 1.4642236 3 Gene 3 WI 6.R1 2.0317925 4 Gene 1 WI 6.R2 2.2042219 5 Gene 2 WI 6.R2 0.5854472 6 Gene 3 WI 6.R2 0.8701078 7 Gene 1 WI 6.R4 4.1956364 8 Gene 2 WI 6.R4 1.8592378 9 Gene 3 WI 6.R4 3.2819835 10 Gene 1 WM 6.R1 2.6273345 # ... with 23 more rows ``` --- ```r genes %>% gather(variable, expr, -id) %>% separate(variable, c("trt", "leftover"), "-") %>% separate(leftover, c("time", "rep"), "\\.") # A tibble: 33 x 5 id trt time rep expr * <chr> <chr> <chr> <chr> <dbl> 1 Gene 1 WI 6 R1 2.1824242 2 Gene 2 WI 6 R1 1.4642236 3 Gene 3 WI 6 R1 2.0317925 4 Gene 1 WI 6 R2 2.2042219 5 Gene 2 WI 6 R2 0.5854472 6 Gene 3 WI 6 R2 0.8701078 7 Gene 1 WI 6 R4 4.1956364 8 Gene 2 WI 6 R4 1.8592378 9 Gene 3 WI 6 R4 3.2819835 10 Gene 1 WM 6 R1 2.6273345 # ... with 23 more rows ``` --- ```r gtidy <- genes %>% gather(variable, expr, -id) %>% separate(variable, c("trt", "leftover"), "-") %>% separate(leftover, c("time", "rep"), "\\.") %>% mutate(trt = sub("W", "", trt)) %>% mutate(rep = sub("R", "", rep)) head(gtidy) # A tibble: 6 x 5 id trt time rep expr <chr> <chr> <chr> <chr> <dbl> 1 Gene 1 I 6 1 2.1824242 2 Gene 2 I 6 1 1.4642236 3 Gene 3 I 6 1 2.0317925 4 Gene 1 I 6 2 2.2042219 5 Gene 2 I 6 2 0.5854472 6 Gene 3 I 6 2 0.8701078 ``` --- # Make a picture  --- # Tidying example 3 ```r melbtemp <- read.fwf("data/ASN00086282.dly", c(11, 4, 2, 4, rep(c(5, 1, 1, 1), 31)), fill=T) melbtemp <- melbtemp[,c(1,2,3,4,seq(5,128,4))] colnames(melbtemp) <- c("id", "year", "month", "var", paste0("V",1:31)) head(melbtemp) id year month var V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 1 ASN00086282 1970 7 TMAX 141 124 113 123 148 149 139 153 123 108 119 2 ASN00086282 1970 7 TMIN 80 63 36 57 69 47 84 78 49 42 48 3 ASN00086282 1970 7 PRCP 3 30 0 0 36 3 0 0 10 23 3 4 ASN00086282 1970 8 TMAX 145 128 150 122 109 112 116 142 166 127 117 5 ASN00086282 1970 8 TMIN 50 61 75 67 41 51 48 -7 56 62 47 6 ASN00086282 1970 8 PRCP 0 66 0 53 13 3 8 0 0 0 3 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 1 112 126 112 115 133 134 126 104 143 141 134 117 142 158 149 133 143 150 2 56 51 36 44 39 40 58 15 33 51 74 39 66 78 36 61 46 42 3 0 5 0 0 0 0 0 8 0 18 0 0 0 0 13 3 0 25 4 127 159 143 114 65 113 125 129 147 161 168 178 161 145 142 137 150 120 5 33 67 84 11 41 18 50 22 28 74 94 73 88 50 48 54 78 47 6 5 0 0 64 3 99 36 8 0 0 0 8 36 25 30 56 5 69 V30 V31 1 145 115 2 63 39 3 0 3 4 114 129 5 18 39 6 3 20 ``` --- ```r melbtemp %>% gather(day, value, V1:V31) %>% head() id year month var day value 1 ASN00086282 1970 7 TMAX V1 141 2 ASN00086282 1970 7 TMIN V1 80 3 ASN00086282 1970 7 PRCP V1 3 4 ASN00086282 1970 8 TMAX V1 145 5 ASN00086282 1970 8 TMIN V1 50 6 ASN00086282 1970 8 PRCP V1 0 ``` --- ```r melbtemp %>% gather(day, value, V1:V31) %>% mutate(day = sub("V", "", day)) %>% head() id year month var day value 1 ASN00086282 1970 7 TMAX 1 141 2 ASN00086282 1970 7 TMIN 1 80 3 ASN00086282 1970 7 PRCP 1 3 4 ASN00086282 1970 8 TMAX 1 145 5 ASN00086282 1970 8 TMIN 1 50 6 ASN00086282 1970 8 PRCP 1 0 ``` --- Missing values have been coded as -9999. Need to recode these as NA. ``` min median max 1 -9999 91 1388 ``` ```r melbtemp %>% gather(day, value, V1:V31) %>% mutate(day = sub("V", "", day)) %>% mutate(value=ifelse(value==-9999, NA, value)) %>% head() id year month var day value 1 ASN00086282 1970 7 TMAX 1 141 2 ASN00086282 1970 7 TMIN 1 80 3 ASN00086282 1970 7 PRCP 1 3 4 ASN00086282 1970 8 TMAX 1 145 5 ASN00086282 1970 8 TMIN 1 50 6 ASN00086282 1970 8 PRCP 1 0 ``` --- There are more variables types that are recognisable: ``` # A tibble: 7 x 2 var n <fctr> <int> 1 DATN 62 2 DATX 31 3 MDTN 62 4 MDTX 31 5 PRCP 16399 6 TMAX 16399 7 TMIN 16399 ``` --- ```r melbtemp %>% gather(day, value, V1:V31) %>% mutate(day = sub("V", "", day)) %>% mutate(value=ifelse(value==-9999, NA, value)) %>% filter(var %in% c("PRCP", "TMAX", "TMIN")) %>% head() id year month var day value 1 ASN00086282 1970 7 TMAX 1 141 2 ASN00086282 1970 7 TMIN 1 80 3 ASN00086282 1970 7 PRCP 1 3 4 ASN00086282 1970 8 TMAX 1 145 5 ASN00086282 1970 8 TMIN 1 50 6 ASN00086282 1970 8 PRCP 1 0 ``` --- ```r melbtemp %>% gather(day, value, V1:V31) %>% mutate(day = sub("V", "", day)) %>% mutate(value=ifelse(value==-9999, NA, value)) %>% filter(var %in% c("PRCP", "TMAX", "TMIN")) %>% spread(var, value) %>% head() id year month day PRCP TMAX TMIN 1 ASN00086282 1970 7 1 3 141 80 2 ASN00086282 1970 7 10 23 108 42 3 ASN00086282 1970 7 11 3 119 48 4 ASN00086282 1970 7 12 0 112 56 5 ASN00086282 1970 7 13 5 126 51 6 ASN00086282 1970 7 14 0 112 36 ``` --- ```r melbtemp %>% gather(day, value, V1:V31) %>% mutate(day = sub("V", "", day)) %>% mutate(value=ifelse(value==-9999, NA, value)) %>% filter(var %in% c("PRCP", "TMAX", "TMIN")) %>% spread(var, value) %>% mutate(PRCP=PRCP/10, TMAX=TMAX/10, TMIN=TMIN/10) %>% head() id year month day PRCP TMAX TMIN 1 ASN00086282 1970 7 1 0.3 14.1 8.0 2 ASN00086282 1970 7 10 2.3 10.8 4.2 3 ASN00086282 1970 7 11 0.3 11.9 4.8 4 ASN00086282 1970 7 12 0.0 11.2 5.6 5 ASN00086282 1970 7 13 0.5 12.6 5.1 6 ASN00086282 1970 7 14 0.0 11.2 3.6 ``` --- # Melbourne max temperatures  --- class: inverse middle # Your turn Tidy the tuberculosis data (example 4) so that it looks like this: ``` # A tibble: 115,380 x 5 iso2 year gender age count * <chr> <int> <chr> <chr> <int> 1 AD 1989 m 04 NA 2 AD 1990 m 04 NA 3 AD 1991 m 04 NA 4 AD 1992 m 04 NA 5 AD 1993 m 04 NA 6 AD 1994 m 04 NA 7 AD 1996 m 04 NA 8 AD 1997 m 04 NA 9 AD 1998 m 04 NA 10 AD 1999 m 04 NA # ... with 115,370 more rows ``` ``` iso2 year gender age count 1 AD 1989 m 1524 NA 2 AD 1990 m 1524 NA 3 AD 1991 m 1524 NA 4 AD 1992 m 1524 NA 5 AD 1993 m 1524 NA 6 AD 1994 m 1524 NA ... ``` ![](lorikeets.png) --- class: inverse middle # Your turn Tidy the pew survey data (example 5) so that it looks like: ``` religion income count 1 Agnostic <$10k 27 2 Atheist <$10k 12 3 Buddhist <$10k 27 4 Catholic <$10k 418 5 Don’t know/refused <$10k 15 6 Evangelical Prot <$10k 575 ... ``` ![](lorikeets.png) --- # Wrangling your data: Verbs - Filter - Arrange - Select - Mutate - Summarise - Group/Ungroup --- # Filter Pick observations by their values. For example, ``` filter(var %in% c("PRCP", "TMAX", "TMIN")) ``` took the column named `var` and keeps rows that have one of three values `PRCP`, `TMAX`, `TMIN`. All other rows are removed. --- # Arrange Orders a data frame or tibble by the values in one column ```r library(lubridate) ordered_nelbtemp <- melbtemp %>% mutate(date=ymd(paste(year, month, day, sep="-"))) %>% arrange(date) ``` --- # Select Choose some of the __variables__. ```r airport <- read_csv("data/airports.csv") airport # A tibble: 13,094 x 29 AIRPORT_SEQ_ID AIRPORT_ID AIRPORT DISPLAY_AIRPORT_NAME <int> <int> <chr> <chr> 1 1000101 10001 01A Afognak Lake Airport 2 1000301 10003 03A Bear Creek Mining Strip 3 1000401 10004 04A Lik Mining Camp 4 1000501 10005 05A Little Squaw Airport 5 1000601 10006 06A Kizhuyak Bay 6 1000701 10007 07A Klawock Seaplane Base 7 1000801 10008 08A Elizabeth Island Airport 8 1000901 10009 09A Augustin Island 9 1001001 10010 1B1 Columbia County 10 1001002 10010 1B1 Columbia County # ... with 13,084 more rows, and 25 more variables: # DISPLAY_AIRPORT_CITY_NAME_FULL <chr>, AIRPORT_WAC <int>, # AIRPORT_COUNTRY_NAME <chr>, AIRPORT_COUNTRY_CODE_ISO <chr>, # AIRPORT_STATE_NAME <chr>, AIRPORT_STATE_CODE <chr>, # AIRPORT_STATE_FIPS <chr>, CITY_MARKET_ID <int>, # DISPLAY_CITY_MARKET_NAME_FULL <chr>, CITY_MARKET_WAC <int>, # LAT_DEGREES <int>, LAT_HEMISPHERE <chr>, LAT_MINUTES <int>, # LAT_SECONDS <int>, LATITUDE <dbl>, LON_DEGREES <int>, # LON_HEMISPHERE <chr>, LON_MINUTES <int>, LON_SECONDS <int>, # LONGITUDE <dbl>, AIRPORT_START_DATE <date>, AIRPORT_THRU_DATE <date>, # AIRPORT_IS_CLOSED <int>, AIRPORT_IS_LATEST <int>, X29 <chr> ``` --- ```r airport %>% select(AIRPORT, LATITUDE, LONGITUDE, AIRPORT_IS_LATEST, DISPLAY_AIRPORT_NAME) # A tibble: 13,094 x 5 AIRPORT LATITUDE LONGITUDE AIRPORT_IS_LATEST DISPLAY_AIRPORT_NAME <chr> <dbl> <dbl> <int> <chr> 1 01A 58.10944 -152.90667 1 Afognak Lake Airport 2 03A 65.54806 -161.07167 1 Bear Creek Mining Strip 3 04A 68.08333 -163.16667 1 Lik Mining Camp 4 05A 67.57000 -148.18389 1 Little Squaw Airport 5 06A 57.74528 -152.88278 1 Kizhuyak Bay 6 07A 55.55472 -133.10167 1 Klawock Seaplane Base 7 08A 59.15694 -151.82917 1 Elizabeth Island Airport 8 09A 59.36278 -153.43056 1 Augustin Island 9 1B1 42.28889 -73.71028 0 Columbia County 10 1B1 42.29139 -73.71028 1 Columbia County # ... with 13,084 more rows ``` --- # Mutate Create new, or transform existing, variables, e.g. for the Melbourne temperature data, we put the temperature and precipitation values into Celsius and mm, byt dividing by 10. ``` mutate(PRCP=PRCP/10, TMAX=TMAX/10, TMIN=TMIN/10) ``` --- # Summarise Calculate a quantity on a column, producing a single number, e.g. sample statistics for PRCP: ```r melbtemp %>% summarise(m = mean(PRCP, na.rm=TRUE), s = sd(PRCP, na.rm=TRUE), mx = max(PRCP, na.rm=TRUE), mn = min(PRCP, na.rm=TRUE)) m s mx mn 1 1.472235 4.684938 138.8 0 ``` - Stats: `mean()`, `median()`, `sd()`, `min()`, `max()`, `sum()` - Rounding: `floor()`, `ceiling()`, `trunc()`, `round()`, `signif()` --- # Grouping and ungrouping Summarise is most commonly called on subgroups of data. We might want to calculate statistics of the weather data across years. ```r melbtemp %>% group_by(year) %>% summarise(m = mean(TMAX, na.rm=TRUE), s = sd(TMAX, na.rm=TRUE), mx = max(TMAX, na.rm=TRUE), mn = min(TMAX, na.rm=TRUE)) # A tibble: 45 x 5 year m s mx mn <int> <dbl> <dbl> <dbl> <dbl> 1 1970 17.65598 5.732199 36.3 6.5 2 1971 19.44740 6.232913 38.0 9.3 3 1972 20.09370 6.021887 39.0 8.4 4 1973 19.27726 6.304111 39.8 6.5 5 1974 19.23507 6.375121 36.4 8.5 6 1975 19.51562 5.990767 39.0 6.2 7 1976 19.42186 6.426436 41.4 7.5 8 1977 19.38548 6.658039 40.2 8.0 9 1978 18.78164 6.149057 38.8 8.2 10 1979 19.81260 6.663044 41.0 10.0 # ... with 35 more rows ``` If we want to more operations on the variable `year` after these calculations, you would need to do an `ungroup()` step. --- # Melbourne max max temperature  --- # Putting it together for the french fries 10 week sensory experiment, 12 individuals assessed taste of french fries on several scales (how potato-y, buttery, grassy, rancid, paint-y do they taste?), fried in one of 3 different oils, replicated twice.  - Is the design complete? - Are replicates like each other? - How do the ratings on the different criteria differ? - Are raters giving different scores on average? - Do ratings change over the weeks? Each of these questions involves different summaries of the data. --- # Answer some Questions - Easiest question is whether the ratings are similar on the different scales, potato'y, buttery, grassy, rancid and painty. - We need to gather the data into long form, and make plots facetted by the scale. ```r ff.m <- french_fries %>% gather(type, rating, -subject, -time, -treatment, -rep) ggplot(data=ff.m, aes(x=rating)) + geom_histogram(binwidth=2) + facet_wrap(~type, ncol=5) ```  --- # Look at it a different way  --- # Comparison of the distributions of criteria Ratings on the different criteria are quite different. - Potato'y scores relatively highly. - Grassy are mostly 0's - Buttery and painty are skewed right, mostly low values a few high ratings - Rancid is quite varied, we would hope that this relates to time, that the chips get more rancid as the weeks go by. --- # Do the replicates look like each other? - We will start to tackle this by plotting the replicates against each other using a scatterplot. - If raters give the same rating to the replicates, we would expect something close to this, then all values would lie on the X=Y line - We need to - gather the data into long form, and - then get the replicates spread into separate columns. --- ```r ff.s <- ff.m %>% spread(rep, rating) head(ff.s) # A tibble: 6 x 6 time treatment subject type `1` `2` <fctr> <fctr> <fctr> <chr> <dbl> <dbl> 1 1 1 3 buttery 0.0 0.0 2 1 1 3 grassy 0.0 0.0 3 1 1 3 painty 5.5 0.0 4 1 1 3 potato 2.9 14.0 5 1 1 3 rancid 0.0 1.1 6 1 1 10 buttery 6.4 5.9 ``` --- # Check Replicates ![](2.data.organisation_files/figure-html/unnamed-chunk-37-1.png)![](2.data.organisation_files/figure-html/unnamed-chunk-37-2.png) They have some positive linear association, but there is a lot more variation than expected. One rep might have scored 15 and the other 0, that's the same batches, same oil, same criteria, same week, same rater! --- # Separately by criteria ...  buttery and potato'y look a bit better. The rest are still terrible. --- # by oil ...  Not much improvement here. --- # By subject ...  Some subjects may be more experienced than others? --- Because the replicates do not look like each other, the quality of the data might be questioned at this point. Nevertheless, lets push on with some of the other questions. --- # Completeness of experimental design If the data is complete it should be 12 x 10 x 3 x 2, that is, 6 records for each person. (Assuming that each person rated on all scales.) To check this we want to tabulate the number of records for each subject, time and treatment. That is, - select appropriate columns, - tabulate, - count and - spread it out to give a nice table. --- ```r french_fries %>% select(subject, time, treatment) %>% count(subject, time) %>% spread(time, n) # A tibble: 12 x 11 subject `1` `2` `3` `4` `5` `6` `7` `8` `9` `10` * <fctr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> 1 3 6 6 6 6 6 6 6 6 6 NA 2 10 6 6 6 6 6 6 6 6 6 6 3 15 6 6 6 6 6 6 6 6 6 6 4 16 6 6 6 6 6 6 6 6 6 6 5 19 6 6 6 6 6 6 6 6 6 6 6 31 6 6 6 6 6 6 6 6 NA 6 7 51 6 6 6 6 6 6 6 6 6 6 8 52 6 6 6 6 6 6 6 6 6 6 9 63 6 6 6 6 6 6 6 6 6 6 10 78 6 6 6 6 6 6 6 6 6 6 11 79 6 6 6 6 6 6 6 6 6 NA 12 86 6 6 6 6 6 6 6 6 NA 6 ``` Its pretty good, but subjects, 3, 31, 79, 86 all missed a rating session. --- # By criteria ``` # A tibble: 12 x 11 subject `1` `2` `3` `4` `5` `6` `7` `8` `9` `10` * <fctr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> 1 3 30 30 30 30 30 30 30 30 30 NA 2 10 30 30 30 30 30 30 30 30 30 30 3 15 30 30 30 30 30 30 30 30 30 30 4 16 30 30 30 30 30 30 30 30 30 30 5 19 30 30 30 30 30 30 30 30 30 30 6 31 30 30 30 30 30 30 30 30 NA 30 7 51 30 30 30 30 30 30 30 30 30 30 8 52 30 30 30 30 30 30 30 30 30 30 9 63 30 30 30 30 30 30 30 30 30 30 10 78 30 30 30 30 30 30 30 30 30 30 11 79 30 30 30 30 30 30 30 30 30 NA 12 86 30 30 30 30 30 30 30 30 NA 30 ``` --- # Change in rancid ratings over weeks - Filter on criteria - Compute means by subject, week and oil ```r ff.av <- ff.m %>% filter(type == "rancid") %>% group_by(subject, time, treatment) %>% summarise(rating=mean(rating)) ``` ---  Oh, its awful data! Only subject 86 is seeing the chips get more rancid over time, with maybe oil 1 being worse. Subject 63, shows some trend. Nothing is rancid for subjects 78, 79. Subject 53 thinks they taste better after many weeks in the same old oil! --- class: inverse middle # Your turn For the 2015 OECD PISA data, Australia subset, strip the state out of the STRATUM variable using this code: ```r load("data/pisa_au.rda") pisa_au <- pisa_au %>% mutate(state=as.character(substr(STRATUM, 4, 5)), schtype_yr=as.character(substr(STRATUM, 6, 7))) %>% mutate(state=recode(state, "01"="ACT", "02"="NSW", "03"="VIC", "04"="QLD", "05"="SA", "06"="WA", "07"="TAS", "08"="NT")) ``` use your wrangling skills to answer these questions: - Compute the average of math scores by state. Which state does best, on average, on math? (You should use the stuweight variable to compute a weighted average. This is survey data, and the weights indicate how representative that individual is of the population.) ``` # A tibble: 8 x 2 state m <chr> <dbl> 1 ACT 505.4857 2 NSW 494.2584 3 NT 478.0795 4 QLD 486.3467 5 SA 489.3091 6 TAS 468.9917 7 VIC 498.6085 8 WA 503.8274 # A tibble: 8 x 4 # Groups: state [8] state `1` `2` dif <chr> <dbl> <dbl> <dbl> 1 ACT 502.1651 508.7725 -6.607420 2 NSW 492.0413 496.4775 -4.436208 3 NT 463.6726 492.1481 -28.475479 4 QLD 486.8992 485.8188 1.080436 5 SA 485.8819 492.5379 -6.655965 6 TAS 466.9742 470.8269 -3.852642 7 VIC 491.9853 505.2567 -13.271372 8 WA 501.4735 506.1641 -4.690684 ``` - Compute the difference in average male and female math scores by state. Which state has the smallest average gender difference? - Does test anxiety have an effect math score? ``` Call: lm(formula = math ~ ANXTEST, data = pisa_au, weights = W_FSTUWT) Weighted Residuals: Min 1Q Median 3Q Max -1645.99 -224.24 -29.83 194.74 1467.37 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 498.6578 0.7291 683.92 <2e-16 *** ANXTEST -11.7413 0.7349 -15.98 <2e-16 *** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 356.3 on 13896 degrees of freedom (632 observations deleted due to missingness) Multiple R-squared: 0.01804, Adjusted R-squared: 0.01797 F-statistic: 255.3 on 1 and 13896 DF, p-value: < 2.2e-16 ```  --- # Summary - Tidy data is a conceptual framework that helps to be more efficient in data analysis - Most analysis tasks can be accomplished using the handful of wrangling verbs - Its worth learning! --- # Resources - Data transformation [cheatsheet](https://github.com/rstudio/cheatsheets/raw/master/source/pdfs/data-transformation-cheatsheet.pdf) - [Wickham (2007) Reshaping data](https://www.jstatsoft.org/article/view/v021i12/v21i12.pdf) - [Wickham (2011) Split-Apply-Combine](https://www.jstatsoft.org/article/view/v040i01) - [broom vignettes, David Robinson](https://cran.r-project.org/web/packages/broom/vignettes/broom.html) --- class: inverse middle # Share and share alike This work is licensed under the Creative Commons Attribution-Noncommercial 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/us/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.


|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.mariuszgromada.math.mxparser.mathcollection.BooleanAlgebra
public final class BooleanAlgebra
BooleanAlgebra - class for boolean operators.
| Field Summary | |
|---|---|
static double[][] |
AND
AND truth table |
static double[][] |
CIMP
CIMP truth table |
static double[][] |
CNIMP
CNIMP truth table |
static double[][] |
EQV
EQV truth table |
static double |
F
False as double |
static int |
FALSE
False as integer |
static double[][] |
IMP
IMP truth table |
static double |
N
Null as double |
static double[][] |
NAND
NAND truth table |
static double[][] |
NIMP
NIMP truth table |
static double[][] |
NOR
NOR truth table |
static double[] |
NOT
NOT truth table |
static int |
NULL
Null as integer |
static double[][] |
OR
OR truth table |
static double |
T
True as double |
static int |
TRUE
True as integer |
static double[][] |
XNOR
XNOR truth table |
static double[][] |
XOR
XOR truth table |
| Constructor Summary | |
|---|---|
BooleanAlgebra()
|
| Method Summary | |
|---|---|
static double |
and(double a,
double b)
Boolean AND |
static double |
cimp(double a,
double b)
Boolean CIMP |
static double |
cnimp(double a,
double b)
Boolean CNIMP |
static int |
double2IntBoolean(double a)
Double to integer boolean translation |
static double |
eqv(double a,
double b)
Boolean EQV |
static double |
imp(double a,
double b)
Boolean IMP |
static double |
nand(double a,
double b)
Boolean NAND |
static double |
nimp(double a,
double b)
Boolean NIMP |
static double |
nor(double a,
double b)
Boolean NOR |
static double |
not(double a)
Boolean NOT |
static double |
or(double a,
double b)
Boolean OR |
static double |
xnor(double a,
double b)
Boolean XNOR |
static double |
xor(double a,
double b)
Boolean XOR |
| Methods inherited from class java.lang.Object |
|---|
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
public static final int FALSE
public static final int TRUE
public static final int NULL
public static final double F
public static final double T
public static final double N
public static final double[][] AND
public static final double[][] NAND
public static final double[][] OR
public static final double[][] NOR
public static final double[][] XOR
public static final double[][] XNOR
public static final double[][] IMP
public static final double[][] CIMP
public static final double[][] EQV
public static final double[][] NIMP
public static final double[][] CNIMP
public static final double[] NOT
| Constructor Detail |
|---|
public BooleanAlgebra()
| Method Detail |
|---|
public static final int double2IntBoolean(double a)
a
- the double number
public static final double and(double a, double b)
a
- the a number (a AND b)b
- the b number (a AND b)
public static final double or(double a, double b)
a
- the a number (a OR b)b
- the b number (a OR b)
public static final double xor(double a, double b)
a
- the a number (a XOR b)b
- the b number (a XOR b)
public static final double nand(double a, double b)
a
- the a number (a NAND b)b
- the b number (a NAND b)
public static final double nor(double a, double b)
a
- the a number (a NOR b)b
- the b number (a NOR b)
public static final double xnor(double a, double b)
a
- the a number (a XNOR b)b
- the b number (a XNOR b)
public static final double imp(double a, double b)
a
- the a number (a IMP b)b
- the b number (a IMP b)
public static final double eqv(double a, double b)
a
- the a number (a EQV b)b
- the b number (a EQV b)
public static final double not(double a)
a
- the a number (NOT a)
public static final double cimp(double a, double b)
a
- the a number (a CIMP b)b
- the b number (a CIMP b)
public static final double nimp(double a, double b)
a
- the a number (a NIMP b)b
- the b number (a NIMP b)
public static final double cnimp(double a, double b)
a
- the a number (a CNIMP b)b
- the b number (a CNIMP b)
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


Aegisub / Glossary / Automation script feature
In Automation 4 a feature is a function a script makes available to Aegisub. Currently two kinds of features are specified: Export filters and macros.
If a script defines two macros and one export filter, it is said to have defined three features in total.


ID(1) User Commands ID(1) NAME id - print real and effective user and group IDs SYNOPSIS id [OPTION]... [USERNAME] DESCRIPTION Print user and group information for the specified USERNAME, or (when USERNAME omitted) for the current user. -a ignore, for compatibility with other versions -Z, --context print only the security context of the current user -g, --group print only the effective group ID -G, --groups print all group IDs -n, --name print a name instead of a number, for -ugG -r, --real print the real ID instead of the effective ID, with -ugG -u, --user print only the effective user ID --help display this help and exit --version output version information and exit Without any OPTION, print some useful set of identified information. AUTHOR Written by Arnold Robbins and David MacKenzie. REPORTING BUGS Report id bugs to<EMAIL_ADDRESS>GNU coreutils home page: <http://www.gnu.org/software/coreutils/> General help using GNU software: <http://www.gnu.org/gethelp/> Report id translation bugs to <http://translationproject.org/team/> COPYRIGHT Copyright © 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. SEE ALSO The full documentation for id is maintained as a Texinfo manual. If the info and id programs are properly installed at your site, the command info coreutils 'id invocation' should give you access to the complete manual. GNU coreutils 8.12.197-032bb September 2011 ID(1)


Smear
Blur
Slow
No Tooltips
Square Root Scale
DNA Text:
Chief Justice Roberts, President Carter, President Clinton, President Bush, President Obama, fellow Americans and people of the world, thank you. We, the citizens of America, are now joined in a great national effort to rebuild our country and restore its promise for all of our people. Together, we will determine the course of America and the world for many, many years to come. We will face challenges. We will confront hardships. But we will get the job done. Every four years we gather on these steps to carry out the orderly and peaceful transfer of power. And we are grateful to President Obama and first lady Michelle Obama for their gracious aid throughout this transition. They have been magnificent. Thank you. Today’s ceremony, however, has a very special meaning because today we are not merely transferring power from one administration to another or from one party to another, but we are transferring power from Washington, D.C., and giving it back to you, the people. For too long, a small group in our nation’s capital has reaped the rewards of government while the people have borne the cost. Washington flourished, but the people did not share in its wealth. Politicians prospered but the jobs left and the factories closed. The establishment protected itself, but not the citizens of our country. Their victories have not been your victories. Their triumphs have not been your triumphs. And while they celebrated in our nation’s capital, there was little to celebrate for struggling families all across our land. That all changes starting right here and right now, because this moment is your moment. It belongs to you. It belongs to everyone gathered here today and everyone watching all across America. This is your day. This is your celebration. And this, the United States of America, is your country. What truly matters is not which party controls our government, but whether our government is controlled by the people. January 20th, 2017, will be remembered as the day the people became the rulers of this nation again. The forgotten men and women of our country will be forgotten no longer. Everyone is listening to you now. You came by the tens of millions to become part of a historic movement, the likes of which the world has never seen before. At the center of this movement is a crucial conviction that a nation exists to serve its citizens. Americans want great schools for their children, safe neighborhoods for their families, and good jobs for themselves. These are just and reasonable demands of righteous people and a righteous public. But for too many of our citizens, a different reality exists. Mothers and children trapped in poverty in our inner cities, rusted out factories scattered like tombstones across the landscape of our nation. An education system flush with cash but which leaves our young and beautiful students deprived of all knowledge.  This American carnage stops right here and stops right now. We are one nation, and their pain is our pain. Their dreams are our dreams, and their success will be our success. We share one heart, one home, and one glorious destiny. The oath of office I take today is an oath of allegiance to all Americans. For many decades we’ve enriched foreign industry at the expense of American industry, subsidized the armies of other countries while allowing for the very sad depletion of our military. We’ve defended other nations’ borders while refusing to defend our own. And we’ve spent trillions and trillions of dollars overseas while America’s infrastructure has fallen into disrepair and decay. We’ve made other countries rich while the wealth, strength, and confidence of our country has dissipated over the horizon. One by one, the factories shuttered and left our shores with not even a thought about the millions and millions of American workers that were left behind. The wealth of our middle class has been ripped from their homes and then redistributed all across the world. But that is the past, and now we are looking only to the future. We assembled here today are issuing a new decree to be heard in every city, in every foreign capital, and in every hall of power. From this day forward, a new vision will govern our land. From this day forward, it’s going to be only America first, America first. Every decision on trade, on taxes, on immigration, on foreign affairs will be made to benefit American workers and American families. We must protect our borders from the ravages of other countries making our products, stealing our companies, and destroying our jobs. Protection will lead to great prosperity and strength. I will fight for you with every breath in my body, and I will never ever let you down. America will start winning again, winning like never before. We will bring back our jobs. We will bring back our borders. We will bring back our wealth, and we will bring back our dreams. We will build new roads and highways and bridges and airports and tunnels and railways all across our wonderful nation. We will get our people off of welfare and back to work, rebuilding our country with American hands and American labor. We will follow two simple rules: buy American and hire American. We will seek friendship and goodwill with the nations of the world, but we do so with the understanding that it is the right of all nations to put their own interests first. We do not seek to impose our way of life on anyone, but rather to let it shine as an example. We will shine for everyone to follow. We will reinforce old alliances and form new ones and unite the civilized world against radical Islamic terrorism, which we will eradicate completely from the face of the earth.  When you open your heart to patriotism, there is no room for prejudice. The Bible tells us how good and pleasant it is when God’s people live together in unity. We must speak our minds openly, debate our disagreements honestly, but always pursue solidarity. When America is united, America is totally unstoppable. There should be no fear. We are protected and we will always be protected. We will be protected by the great men and women of our military and law enforcement. And most importantly, we will be protected by God. Finally, we must think big and dream even bigger. In America, we understand that a nation is only living as long as it is striving. We will no longer accept politicians who are all talk and no action, constantly complaining but never doing anything about it. The time for empty talk is over. Now arrives the hour of action. Do not allow anyone to tell you that it cannot be done. No challenge can match the heart and fight and spirit of America. We will not fail. Our country will thrive and prosper again. We stand at the birth of a new millennium, ready to unlock the mysteries of space, to free the earth from the miseries of disease, and to harness the energies, industries, and technologies of tomorrow. A new national pride will stir ourselves, lift our sights, and heal our divisions. It’s time to remember that old wisdom our soldiers will never forget, that whether we are black or brown or white, we all bleed the same red blood of patriots. We all enjoy the same glorious freedoms and we all salute the same great American flag. And whether a child is born in the urban sprawl of Detroit or the windswept plains of Nebraska, they look up at the same night sky, they fill their heart with the same dreams, and they are infused with the breath of life by the same almighty Creator. So to all Americans in every city near and far, small and large, from mountain to mountain, from ocean to ocean, hear these words: You will never be ignored again. Your voice, your hopes, and your dreams will define our American destiny. And your courage and goodness and love will forever guide us along the way. Together we will make America strong again, we will make America wealthy again, we will make America proud again, we will make America safe again. And, yes, together we will make America great again. Thank you. God bless you. And God bless America.
Wells with restriction enzyme:


Field of View (FOV) computation
FOV algorithms return a set coordinates, visible from a starting place. Computing these works in the same fashion
as Map generators do: using a user-supplied callback function. This time, however, user has to supply two callbacks:
- Input callback, passed as a constructor argument, which provides visiblity information;
- Output callback, passed as an argument to the
compute
method, which receives FOV data.
Input callback is called by the FOV algorithm to retrieve visibility information for a given coordinate pair. This callback must return true
(light passes)
or false
(light does not pass). Output callback is called with these arguments: x
, y
, r
and visibility
:
the meaning is that "the place at [x,y] is visible with a distance of r". The last argument specifies the amount of visibility (0..1).
Currently there are these FOV algorithms available:
- Precise Shadowcasting
- Recursive Shadowcasting
Precise shadowcasting
Precise shadowcasting FOV computations currently support 360-degree viewsheds and are initiated by calling the compute
method with the following arguments:
x
y
r
– maximum visibility radius
callback
– output callback function
ROT.RNG.setSeed(12345);
var W = 80;
var H = 30;
var display = new ROT.Display({fontSize:12, width:W, height:H});
SHOW(display.getContainer());
/* create a map */
var data = {};
new ROT.Map.Uniform(W, H).create(function(x, y, type) {
data[x+","+y] = type;
display.DEBUG(x, y, type);
});
/* input callback */
function lightPasses(x, y) {
var key = x+","+y;
if (key in data) { return (data[key] == 0); }
return false;
}
var fov = new ROT.FOV.PreciseShadowcasting(lightPasses);
/* output callback */
fov.compute(50, 22, 10, function(x, y, r, visibility) {
var ch = (r ? "" : "@");
var color = (data[x+","+y] ? "#aa0": "#660");
display.draw(x, y, ch, "#fff", color);
});
Recursive shadowcasting
Recursive shadowcasting FOV computations are initiated by calling one of its three compute
methods. It currently supports viewing an entire 360-degree circle (compute
), as well as half-circles (compute180
) and quadrants (compute90
). While the compute
method behaves the same as with Precise and Discrete shadowcasting, the two partial views require an additional argument noting the direction to look in:
x
y
r
– maximum visibility radius
dir
– direction to face in from ROT.DIRS[8]
callback
– output callback function
ROT.RNG.setSeed(12345);
var W = 80;
var H = 30;
DIR_NORTH = 0;
DIR_WEST = 6;
var display = new ROT.Display({fontSize:12, width:W, height:H});
SHOW(display.getContainer());
/* create a map */
var data = {};
new ROT.Map.Uniform(W, H).create(function(x, y, type) {
data[x+","+y] = type;
display.DEBUG(x, y, type);
});
/* input callback */
function lightPasses(x, y) {
var key = x+","+y;
if (key in data) { return (data[key] == 0); }
return false;
}
var fov = new ROT.FOV.RecursiveShadowcasting(lightPasses);
/* output callback for mob with bad vision */
fov.compute90(50, 22, 10, DIR_WEST, function(x, y, r, visibility) {
var ch = (r ? "1" : "@");
var color = (data[x+","+y] ? "#aa0": "#660");
display.draw(x, y, ch, "#fff", color);
});
/* output callback for second mob with better vision */
fov.compute180(57, 14, 10, DIR_NORTH, function(x, y, r, visibility) {
var ch = (r ? "2" : "@");
var color = (data[x+","+y] ? "#aa0": "#660");
display.draw(x, y, ch, "#fff", color);
});
/* output callback for third mob with supernatural vision */
fov.compute(65, 5, 10, function(x, y, r, visibility) {
var ch = (r ? "3" : "@");
var color = (data[x+","+y] ? "#aa0": "#660");
display.draw(x, y, ch, "#fff", color);
});


PMDD - A Brief Explanation
Premenstrual dysphoric disorder (PMDD) is a severe form of premenstrual syndrome that includes physical and behavioral symptoms that usually resolve with
the onset of menstruation.
PMDD causes extreme mood shifts that can disrupt work and damage relationships.
Symptoms include extreme sadness, hopelessness, irritability, or anger,
plus common premenstrual syndrome symptoms such as breast tenderness and bloating.


Creates resource variables by default.
tf.compat.v1.enable_resource_variables()
Resource variables are improved versions of TensorFlow variables with a well-defined memory model. Accessing a resource variable reads its value, and all ops which access a specific read value of the variable are guaranteed to see the same value for that tensor. Writes which happen after a read (by having a control or data dependency on the read) are guaranteed not to affect the value of the read tensor, and similarly writes which happen before a read are guaranteed to affect the value. No guarantees are made about unordered read/write pairs.
Calling tf.enable_resource_variables() lets you opt-in to this TensorFlow 2.0 feature.


The goal of taxadb
is to provide fast access to taxonomic data and manipulations, such as resolving taxonomic names to ids, looking up higher classification ranks of given species, or returning a list of all species below a given rank. These tasks are particularly common when synthesizing data across large species assemblies, such as combining occurrence records with trait records.
Existing approaches to these problems typically rely on web APIs, which can make them impractical for work with large numbers of species or in more complex pipelines. Queries and returned formats also differ across the different taxonomic authorities, making tasks that query multiple authorities particularly complex. taxadb
creates a local database of most readily available taxonomic authorities, each of which is transformed into consistent, standard, and researcher-friendly tabular formats.
To get started, install the development version directly from GitHub:
Before we can use most taxadb
functions, we need to do a one-time installation of the database taxadb
uses for almost all commands. This can take a while to run, but needs only be done once. The database is installed on your local hard-disk and will persist between R sessions. By default, the database will be installed in your user’s application data directory, as detected by the rappdirs
package. (Set a custom location instead using dbdir
argument.)
The default behavior installs only the ITIS database. You can also specify a list of authorities to install, or install every authority using td_create("all")
.
Once the databases have been set up, we’re ready to explore.
Here’s a list of all the birds species known to ITIS:
descendants(name = "Aves", rank = "class")
#> # A tibble: 12,614 x 14
#> taxonID acceptedNameUsa… update_date scientificName taxonRank
#> <chr> <chr> <chr> <chr> <chr>
#> 1 ITIS:1… ITIS:562791 2016-04-29 Rollandia mic… species
#> 2 ITIS:1… ITIS:176409 2016-04-29 Ardea helias species
#> 3 ITIS:1… ITIS:707807 2016-04-29 Mesites varie… species
#> 4 ITIS:1… ITIS:561100 2016-04-29 Mesites unico… species
#> 5 ITIS:1… ITIS:561100 2016-04-29 Mesoenas unic… species
#> 6 ITIS:1… ITIS:707807 2016-04-29 Mesoenas vari… species
#> 7 ITIS:1… ITIS:562791 2016-04-29 Podiceps micr… species
#> 8 ITIS:1… ITIS:563259 2016-04-29 Colymbus rufi… species
#> 9 ITIS:1… ITIS:824133 2016-04-29 Podiceps tric… species
#> 10 ITIS:1… ITIS:174508 2016-04-29 Colymbus domi… species
#> # … with 12,604 more rows, and 9 more variables: taxonomicStatus <chr>,
#> # kingdom <chr>, phylum <chr>, class <chr>, order <chr>, family <chr>,
#> # genus <chr>, specificEpithet <chr>, infraspecificEpithet <chr>
The taxadb introduction provides an overview showing how taxadb
functions can help us synthesize data across a given list of species by resolving synonyms and identifiers.
See the schemas vignette for an overview of the underlying tables used by taxadb
functions, and more about the different authorities accessed by taxadb.


{% extends 'base.html' %} {% load humanize %} {% block title %}Sell Config{% endblock %} {% block content %}
Back to {{ enterprise.name }}, Purchased Launches
Company: {{ launchconfig.launch.company }}
Product: {{ launchconfig.launch.product }}
Launch Date: {{ launchconfig.launch.when_igt }}
Destination: {{ launchconfig.destination }}
Maximum Mass: {{ launchconfig.max_mass }}
Original Price: ${{ launchconfig.price|intcomma }}
Are you sure you want to sell for ${{ price|intcomma }}?
{% endblock %}