Physche: A Little Scheme in Pharo
Scheme in a (super) nutshell
We will start with a limited version of Phsyche, our small functional programming language inspired from Scheme. In the first version, we will not support the definition of new functions (also called procedures). In the second version, we will support function definition and closures, in particular. We start by presenting the subset of Scheme that we will implement.
Our objective here is not to write a Scheme following the latest language specification. We will just cover a tiny subset. Purists may not like what I will write but I take this tiny subset as a pretext for a first exploration. I will only present the parts that we will implement. Phsyche does not support vectors, dotted pairs, continuations, macros.
For a fast yet more complete description of Scheme I like Teach yourself Scheme in fixnum days by Dorai Sitaram http://ds26gte.github.io/tyscheme/index.html.
Here is simple function expressing the length of a list and one example.
There is another way to define functions, but for simplicity we will focus for now on definitions making an explicit use of lambda
.
Once we defined our function, we can call it as follows:
S-Expressions
In Scheme, everything is a s-expression. A S-expression can be:
- atomic for booleans (
#t
,#f
), number (1
), symbols (we will treat strings as atomic). - compound as with lists: A list starts with an opening parenthesis
(
and finishes by a closing one)
. Lists also represent function application. - a function: functions can be normal (i.e., evaluating all their arguments) or special-forms (i.e., having special ways to evaluate their arguments. This is needed to build control-flow for example).
Values
We briefly present booleans, numbers and symbols. Then we focus on function application since this is a much more interesting concept.
Still there is one important point to raise: the value of an atomic expression is itself. We will see that the value of list is function application: it applies the value of the first element on the value of the rest of the list.
List operations
Scheme, in the path of Lisp, offers list operations such as list
to create a list, car
to access the first element of a list, cdr
to access the rest of the list, '()
to represent the empty list, and cons
to add an element as first element of a list. Here are some examples showing their use. We do not present dotted list or pairs to keep the implementation to the bare minimum.
Function application
Scheme follows a prefixed syntax (function args ...)
where the first element refers to a function and the rest are arguments whose values are passed to the function. A list represents function application.
In the code above, the function associated with the symbol +
is looked up and the values of the arguments (* 3 2)
and 5
are computed and passed to function.
By default the evaluation of a function application (a list) evaluates all its components. The function returned as value of the first element is applied to the values returned for the rest of the list.
So far, functions evaluate all their arguments before executing the function.
However, we will see later on that some other forms that look like functions should not evaluate all their arguments.
For example, this is the case of define
, lambda
, quote
and if
.
Such functions are called special-forms and we will have to define their semantics one by one.
Variable definition
To define a variable and set its value, we use the define
special form: it sets the value of the second argument to symbol represented by the first argument. Notice that define
does not evaluate its first argument, only its second one.
Defining and applying functions
To define a function we use the lambda
special form. Its first argument is a list representing the function arguments and the second argument the body of the function.
To use this function, we need to apply it an argument using the form (function args)
. The following piece of code shows how we can apply the argument 3.
To reuse a function in a program, we can assign a function to variable using define
.
Closures
Now a closure is more than a function. A closure refers to its definitionPhsyche environment.
The following example illustrates it. It defines a function that returns a function. This function (having y
as a parameter) will add x to y and x is bound to 3 due to the application of the first function.
The function y is a closure that has an environment in which the variable x is bound to 3.
Similarly the following function shows that we can modify this definition environment during function execution.
and now each time the function sy3
is executed its definition environment is modified and the
value of x
is incremented.
Quote
quote
is an interesting special form: it does not evaluate its argument but instead returns it. It is useful when manipulating lists.
For example, the following expressions returns then a list which looks like a function application but it just a list.
This operation is so current that it has a special syntax: (quote x)
can be written 'x
. Phsyche will not support the '
notation.
List as data
To manipulate a list we can simply quote it.
The following primitive functions allow one to manipulate lists: car
(to access the first element), cdr
(to access the rest of the list), cons
(to create a list) and ()
represents the empty list.
Program as data
What is particularly interesting is that the syntax of the language is centered on the syntax of lists and on the unification between lists as a data structure and function application.
In addition, what is really powerful is that quote
is the bridge between function application and data structure. Indeed, the special function quote
we can turn a program into its abstract syntax tree and we can access its elements using
normal list operations such as car
or cdr
.
In the following example, we can access the argument of the +
application by simply quoting the invocation. Then we can access its elements using plain list operators such as cdr
.
Phsyche's overview
Since we do not want to have to build a full parser, we will bend a bit the syntax of Phsyche to be compatible with the one of Pharo.
- Booleans are represented as
true
andfalse
instead of#t
and#f
. - Numbers are the ones of Pharo.
- Symbols and strings will be the ones of Pharo:
#pharo
and'pharo'
. - Lists will be represented as arrays to be able to get benefit from the scanner facilities of Pharo as we will explain right after. The empty list is represented by
#()
.
We are now ready to implement the first version of Phsyche. We will start with a first version that only let programmers to express function use and composition without having the possibility to define their own functions. Then in a second iteration we will add closures and function definition.
A simple parser for Phsyche
We will start to implement an extremely simple parser. Then we will define an interpreter for a limited version of the language.
Simple interpretation architecture
When implementing language compilers, parsing is the process that takes a text as input and produces an abstract representation of the program (see Figure ). This process is often composed of a scanner and a parser phase. The scanner cuts the text into a list of tokens. Then the parser consumes this list of tokens to build an intermediate representation such as an abstract syntax tree. This abstract syntax tree is then analyzed, annotated, and transformed by a compiler to finally generate different outputs (bytecode or assembly). The generated code embeds the semantics of the implemented language.
Besides having a compiler, we can also have an interpreter, i.e., a program that executes programs of the implemented language. The idea is that the interpreter will consume the intermediate representation and act adequately. For example, when it sees a variable definition, it will declare a binding for such variable in a structure (usually an environment).
Note that the view depicted in Figure is naive in sense that the compiler may also emit abstract instructions (for example bytecode) that will be interpreted by an (bytecode) interpreter and may be converted on the fly to assembly code. This is what the Pharo Virtual Machine does.
In our interpreter we will take a simpler route. Since Scheme syntax is simple we will just use a simple scanner and our interpreter will take as input the tokens produced by the scanner. We will use the natural structure of arrays as simple abstract syntax trees.
Starting
Let us start by defining some tests to drive the development of Phsyche's interpreter.
In the following test we see that we use the natural nesting of arrays of Pharo to represent Scheme lists.
Here we check that an empty list is recognised as an empty array.
Parsing input text
Now we are ready to implement the parse:
method. We create the class Phsyche which is the language interpreter.
To implement the parse:
method, we take advantage of the Pharo's Scanner
and the fact that we map list to arrays.
Note that this implementation can really be bent and it is absolutely not robust but it serves our teaching purpose.
As an exercise, we suggest you to represent lists with pairs as in traditional Lisp and Scheme. To do so, you will need to define a better parser.
Now we are ready to interpret the parsed programs.
Limited Phsyche
In this chapter we will build Limited Phsyche: a simple interpreter that can evaluate atomic elements and simple function application. It will not support function definition and closures.
Evaluating elementary elements
Let us start to specify the expected behavior of the language evaluation.
Now we can add the following methods to Phsyche
We define the eval:
method. It is a short cut to the main eval:in:
method.
The eval:in:
method is central to the interpreter.
For now, the eval:in:
returns its argument. Quite limited and trivial so far.
Defining a variable
We add support for the first special form: define
.
We start by supporting variable definition.
Here is a test showing the behavior we expect.
First we should add a dictionary that holds defined variables and their values.
We redefine the eval:
method as follows:
Now we define a better eval:in:
method. If the expression is a symbol, we return the value of the expression in the enviroment. Note that we do not refer to the instance variable environment
but the parameter anEnvironment
because in the future we will show that we may want to look for values in a different environment than the one of the interpreter.
When the expression is a variable definition, we define it. What you should see is that define
is a special form since it does not evaluate its first parameter only the second one.
This is what the method evalDefineSpecialForm:in:
is doing.
The following test shows that a variable points to a value.
Introducing quote
Quote is an interesting special form. It is the one that does not evaluate its argument.
In addition as we mentioned in an earlier chapter, quote
turns function application ((prog args)
)
into a manipulable data-structure: a list.
Setting up the primitives
We will introduce some primitive behavior such as addition, multiplication, and list manipulation. In this implementation of Phsyche we will define them as block closures. A more object-oriented implementation reifying the operations is possible as we will show in the latest chapter of this booklet.
We will use a dictionary to represent the environment that keep primitives names and their respective values. But let us write a test first to specify what we want to get.
We define the multiplication and addition as follows:
The method multBinding
returns a pair containing the primitive name and its associated Pharo closure.
The environment will contain a binding whose value is the primitive name (#+
) and whose value will be the corresponding block.
Primitive environment initialization
To represent the environment, the interpreter defines one instance variable environment
initialized to a dictionary. It has a primitives
collection to keep the names of the primitives.
We redefine the initialize
method to initialize the environment, the primitive name data structure (here we use an ordered collection) and to call the initializeEnvBindings
method.
The initializeEnvBindings
method automatically executes all the methods ending with 'Binding'
.
We use the method perform:
to execute a method whose name is given as argument.
We add a primitive bindings to the environment and the primitive name to the primitive name list.
The following expression returns the list of method selectors that ends with 'Binding'.
We take the opportunity to add the primitive name to the list of primitives since it will help use later during the evaluation.
Handling primitive evaluation
We are ready to implement the evaluation of a call (primitive arg1 ... argn)
. The method evalPrimitive:in:
finds the block closure and executes it with the values of the arguments. The method valueWithPossibleArgs:
executes a block closure paying attention to the possible multiple number of required arguments.
What is interesting in this method is that this is the place that defines the semantics of the evaluation of argument calls. Here we see that the arguments are all evaluated from left to right.
We should change the eval:in:
method to take into account that we have support for primitive call. What is interesting is that we have to be clear about the semantic of primitive execution, obviously. We know that we can get the closure associated to the primitive name in the environment, and a primitive should evaluate all its arguments and pass to the closure.
At this point our tests should all pass.
Some consideration
Note that for now we consider that the mathematical operations are only working on pairs and not list of elements. Another point to consider is that explicit check for primitives in the environment prevents us to overload locally their definition and this could be changed.
Some more arithmetic primitives
Here are definitions for more primitives
Adding substraction and division
We add
Adding not
Adding list primitives
We should add some primitives to manage lists such as the elementary operations cons
, car
, and cdr
.
Here are some tests to make sure that such primitives are acting as expected.
Note that we consider that cons
is only working on lists and does not produce dotted pairs.
Here are the primitives definitions.
Now we can get back to the implementation of more special forms.
Adding if
We are ready to implement if
. It has the following form: (if condition iftrue iffalse)
. if
is a special form since it does not evaluate all its arguments. Indeed, if
should only evaluate the correct argument based on the boolean value.
Well we can do better. Since numbers are auto-evaluating, this test does not verify that only one branch is evaluated.
Let us use a division by zero checks that for us as follows:
And we define the semantics of if
as follows:
And we can introduce this new method to the main eval:in:
method as follows:
All our lovely tests are passing.
As a short conclusion, our interpreter supports the execution of expression but it is really limited in the sense that we cannot add new functions. This is what we will address in the next chapter as well as the definition of closures (functions which refer to the defining environment).
Function definition and application
We will add user function (also called procedure in some languages) and function application to Phsyche. We go step by step to describe the different aspects of function definition and application. In the next chapter we will introduce closures.
About environments
Let us start with a first function definition.
We can execute the function:
Let us analyse the definition and application of the function area
.
What is important to see is that during the application (area 10)
, the argument r
acts as a local variable of the function. During (area 10)
execution, r
gets the value of the argument (here 10).
The following program checks that the argument value takes precedence over variables defined in outer scope.
We define a variable r
with 5 as value and the function area
has an argument with the same name.
The execution of (area 10)
shows several important points:
- During function application, an environment should be created with the parameter and its value. The body of the function should be evaluated within the context of such an environment.
- Second the argument value takes precedence over the value of
r
defined previously. - Third, when executing the body of
area
we should be able to access variable defined in outer scope such aspi
.
We used a simple dictionary to represent an environment to store variables and their value. But this is not sufficient because it makes the lookup of outer variables more cumbersome. We should use a list of bindings: an environment. This way the environment created during the function application can be linked to the global as shown in Figure . With environments, we can also have function application nested into function application without any problems.
Defining an environment class
An environment is kind of linked list of bindings. It can also be seen as a dictionary that when a binding is not found locally continues the binding lookup in another environment (called its parent or outer scope). Figure shows an example of environments.
Let us define some tests first
Our setup makes sure that the inner
environment is pointing to another context called outer
here.
The first test is to check that we can access the values set in each scope.
The second test is to check that we can reach the outer value from the inner scope.
The final test checks that unknown keys are not found.
We will improve the environment implementation to cover the definition of new binding but we will do that when we will add functionality to change the value of binding (i.e., when we will implement the primitive set
for example).
Implement an environment class
There are multiple ways to implement an environment.
Our implementation is just one special kind of dictionary that when it does not find the value associated to a key, looks up in its father dictionary.
We define the class PEnvironment
as a subclass of Dictionary
as follows:
We need an accessor to set the outer context.
We redefine the method at:
so that we first look up locally for a value. If the value is found, we return it, else when there is an outer environment we look the value in this outer environment. If there is no outer environment, we simply execute the default behavior which will lead to raise an error.
Now we are ready to define what a function is.
Function definition
We need a way to represent a function. A function has a list of parameter and a body. Let us start to write a test.
We define the class PFunction
to represent functions. It is for now straightforward.
Define the accessors for its instance variables. Now we will extend the interpreter to create functions. When an expression starts with a lambda keyword, we should return a function.
Note that this implementation of lambda
is not correct as it does not keep a reference to its defining environment but we will do it later when we will introduce closures.
Now Phsyche supports the definition of functions but not their application. Let us look at that now.
Function application
As we saw languages following Lisp-like syntax follow the pattern (proc args)
to mean that the function proc
is applied to the arguments args
. Such arguments are evaluated prior being passed to the function.
Let us write tests to control such a behavior.
Again we will implement function application step by step to understand the different aspects.
What is important to see is that while executing a function body, we have to have access to the interpreter environment, for example, to access primitive definitions. We have to define a new environment where we bind the arguments to their values. Such an environment will only be used for one application. It will be the inner environment of Figure .
A first function application
The not really good implementation is then the following:
The following method evalApplicativeOrder:in:
is responsible for the function application: it evaluates its first element, which will return a function.
It creates an new environment with the parameters and the values of the arguments as values and execute the body of the function within this environment.
Note that for function application, the application environment (newEnv
) has the global interpreter environment as parent. This will not be the case for closures as we will see later.
The method setEnvironmentForParameters:in:
is a simple helper function that creates a new environment based on the function parameters and their values, and an outer environment.
The class method newFromKeys:andValues:
only exists in Pharo 70. Here is its definition.
With such an implementation, all our current tests should pass. Now we are ready to implement closures.
Adding closures to Phsyche
In this chapter we add closures to Phsyche. A closure is a function capturing the environment in which it is defined. We start studying some examples and then we will implement on the closure semantics.
Studying a closure
A closure is a function which contains a reference to the environment at its definition time. Since evaluating a lambda defines a temporary environment in which the parameters are bound, we use this fact to create an environment local to a function. Let us have a look at a simple example:
This expression creates a lambda expression and apply to 7. The execution of this lambda expression leads to the creation of another lambda expression applied to 3.
The following subexpression returns a function lambda (y) ...
adding 3 to its parameter y
.
This is why the first expression result is 10. It does so by executing the first function with 3 as parameter value for x
. This first execution creates an environment in which x is bound to 3.
Then it returns a function taking y
as parameter and referring to this environment. This is why when (+ x y)
is executed, x
is bound to 3.
The following expressions illustrate the same process by defining a function fy
and executing such a function.
About let
In fact defining local environments is so frequent that Scheme and Lisp languages offer the let
special form to define local environment as follow:
You can add let
to Phsyche as an exercise.
Implementing closure
To support closures, the first point is that we should change the lambda
special form to refer to the environment in which it is defined. Indeed at the time the function is created, it holds a reference to its defining environment.
To test that lambda
effectively creates an environment, we use this expression:
Here the nested function (with y as parameter) is simply returning the value of x. And during the function execution, the value of x will be looked up in the created environment. Here is a first test.
Note that it is difficult to test the fact that a function declaration defines a new environment without using function application. This is why we are using basic introspection to access the value of the variable.
The following test uses function application to verify the creation of the environment.
What is important to see is that the function lambda (y)...
will be executed in an environment where y
is bound to 7 and this environment will have as outer environment an environment with x
bound to 3 as shown in Figure
We add the environment instance variable to the class PFunction
and set the current environment of the interpreter when creating the function in during execution of the lambda special form.
Now we should revisit function evaluation to use the function environment instead of the one of the interpreter.
Here we create the newEnv
using the function environment as expressed by proc environment
. What is important to see with closure application is that the execution environment has as outer environment the one of the function.
We have implemented the most important aspect of closure semantics. Now we will add some support to modify environments and conclude with this first version of Phsyche.
Adding set! and begin
To be able to experiment more with closures, we add support for changing the value of a binding using the set!
special form and performing a sequence of instructions using the begin
special form.
The following tests specify that any modification should happen in the environment defining the existing binding. Notice that when a binding is not in the current environment but in one of the outer environment, this is the environment that contains the binding that should be modified.
We implement a new method called lookupAt:put:
as follows:
The following simple test checks that we can change the value of a binding. We will add more complex tests once we get the begin
primitives implemented.
We are ready to implement set!
.
Our tests should pass.
Implementing begin
The special form (begin exp1 exp2 ... expn)
evaluates one after another the expressions in the list and return the value of the last one. The following tests are super simple but makes sure that all the elements are evaluated and that the result of the last one is returned.
Now the implementation of begin
is the following one.
A more complex test
The following test is a bit more complex. It shows that we can change the binding of a variable created over function application. The expression (set x (+ x 2))
modifies the value of x created by the function application. This is why even if the first value of x
is 3, it is then latter sets to 5. Then when the function fy
is applied to 5, it returns 10.
We are done.
Fun with closures
In this section, we will develop super naive and little account objects with an internal state, their balance. For this, we define a function whose captured environment will keep some state (a number) that can only be modified by an internal function.
The function makeAccount
is a function with one parameter (balance
). This function will return a function that has in its scope the balance
variable and will be able to modify it.
We can create several accounts each having its own state.
Using the same principle you can create objects having multiple functions accessing their internal state. For this the returned function should act as a case based and execute corresponding function. In fact we prefer to use real objects such as the ones in Pharo instead of simulating them.
Conclusion
This ends our naive implementation of a subset of Scheme.
In the following chapter we revisit the implementation to reduce the complexity of the eval:in:
method.
Phsycoo
This chapter is optional. In this alternate implementation we treat primitives and special forms the same way. Doing so we reduce the explicit switching logic of the eval:in:
function. We show that the core of an interpreter can take advantage of dynamic dispatch.
Basically we create an object for each case and give the object the possibility to specify the full evaluation.
Reusing tests
To make sure that Phsycoo is implementing the same functionality than Phsyche, we define PhsycooTest
as a subclass of PhsycheTest
.
In the setup we create an instance of the Phsycoo instead of Phsyche.
Now using the TestRunner you will be able to run all the tests on a Phsycoo instance.
Phsycoo interpreter
Phsycoo has the same structure and initialization than Phsyche except that primitives and special forms are uniformly represented by objects, instances of their corresponding class in the PhsycooPrimitives hierarchy as shown in Figure
Modeling primitives and special forms
Primitives and special forms are now expressed as subclasses of the root class PhsycooPrimitives
. Each subclass should define valueFor: aCollection with: anInterpreter environment: anEnvironment
and the class method tag
.
Given a collection representing a primitive or special form application, an interpreter and an environment, the method valueFor:with:environment:
should return the corresponding value or modify the internal state of the interpreter.
A tag is a simple identifier that will be used to define the primitive or special form in the interpreter environment. For plus it will be #+
.
The Plus primitive
For example the primitive plus
is expressed as follows:
The if special form
The special form if
is expressed as a subclass of PhsycooPrimitives
.
The method valueFor:with:environment:
defines the semantics of condition.
Initializing the environment
Once we have defined the primitives and special forms we should add them to the interpreter environment. For this, we specialize the initialization of the interpreter as follows:
This is where we see that the tag
method is used to populate interpreter environment.
Reconsidering eval:in:
And we are ready to have a simpler and more systematic evaluation logic. As you can see it is much more compact and regular.
There are basically four cases
- we get an empty array (list), we return it.
- we get a symbol (value), we look it up and return it.
- we get self-evaluating entities such as #t, number, we return them.
- we get a function application: we distinguish between applicative order (this is a user defined or primitive and special forms execution (non application order).
The method evaluateNonApplicativeOrder:in:
dispatches to the associate instance. Any primitive or special forms are executed via this calling point.
For applicative order, the method is the same as in Phsyche.
If we let aside the possibility to redefine primitives and special forms, there is nothing more than in Phsyche. It is just expressed differently.
Conclusion
We have implemented a more modular implementation. Adding a new behavior is just defining a new subclass with two methods.


{% extends "website/base.html" %} {% load static %} {% block title %}Añadir expansiones{% endblock %} {% block content %} {% include "website/partials/hero.html" with title="Añadir Expansiones" %} {% csrf_token %} Expansión * Losetas Reglas {{ expansions_in_game_form.expansion }} {{ expansions_in_game_form.use_tiles }} {{ expansions_in_game_form.use_rules }} {% if expansions_in_game %} {% include "website/partials/hero.html" with title="Expansiones" %} {% include 'website/partials/expansions_box.html' with can_remove_expansion=1 %} {% endif %} Siguiente paso {% endblock %}
Expansión *
Losetas
Reglas
{{ expansions_in_game_form.expansion }}
{{ expansions_in_game_form.use_tiles }}
{{ expansions_in_game_form.use_rules }}


A dead simple, responsive boilerplate.
Download
Light as a feather at ~400 lines & built with mobile in mind.
Styles designed to be a starting point, not a UI framework.
Quick to start with zero compiling or installing necessary.


{% extends "base.html" %} {% block content %}
2020
During a semester I used React, css and Bootstrap to help them with some design changes into their webpage
2021
I participate in MIT's Beautiful Patterns program as a facilitator. The program lasted a week and consisted of teaching girls between 15 and 17 years to program in Python.
2021
I participate in the development of an Android app to help the foundation Quinta Carmelita had a better control of their data. I used Adobe XD and Android Studio
2021
I participate in the Production Engineering fellowship powered by Facebook where I learn about Docker, CI/CD, AWS and Github!


|
| Value |
Description |
Notes |
|
| 01 |
Product |
The title element refers to an individual product |
| 02 |
Collection level |
The title element refers to the top level of a bibliographic collection |
| 03 |
Subcollection |
The title element refers to an intermediate level of a bibliographic collection that comprises two or more ‘sub-collections’ |
| 04 |
Content item |
The title element refers to a content item within a product, eg a work included in a combined or ‘omnibus’ edition, or a chapter
in a book
|
| 05 |
Master brand |
The title element names a master brand where the use of the brand spans multiple collections and product forms, and possibly
multiple imprints and publishers. Used only for branded media properties carrying, for example, a children’s character brand
|
| 06 |
Sub-subcollection |
The title element refers to an intermediate level of a bibliographic collection that is a subdivision of a sub-collection
(a third level of collective identity)
|
|


Quick Links:
Main Page
About me
Biomimcry in Architecture..
Paperbug, coming soon!
Awards:
Facade Automation..
Connect:
LinkedIn
Twitter
Youtube
Github


Peak Performance Track and Field Club
The Peak Performance Track Club (PPTC) is a summer youth organization dedicated to providing guidance, discipline, a positive alternative, competitive meets and fun for the youth in Omaha through the sport of track and field. PPTC understands the importance that sports play in the development of life skills. It is important that we all understand that being a good athlete will last for a short period, but being a good person will pay dividends forever.


from nhlscrapi.scrapr.eventsummrep import EventSummRep
from nhlscrapi.games.repscrwrap import RepScrWrap, dispatch_loader
class EventSummary(RepScrWrap):
[docs] """
Event summary report. Produces the team shot/face-off summary by strength as well as the by player stats
including scoring, TOI by situation et c.
:param game_key: unique game identifier of type :py:class:`.GameKey`
"""
def __init__(self, game_key):
super(EventSummary, self).__init__(game_key, EventSummRep(game_key))
@property
@dispatch_loader('_rep_reader', 'parse_home_shots')
def home_shots(self):
"""
Property that returns the home team shot summary by situation.
:returns: dict of the form
.. code:: python
{
'agg': { 'ev/pp/sh/tot': { 'g': goals, 's': shots } },
'det': { '5v5/5v4/5v3/et c': { 'g': goals, 's': shots } }
}
"""
return self._rep_reader.shots['home']
@property
@dispatch_loader('_rep_reader', 'parse_away_shots')
def away_shots(self):
"""
Property that returns the away team shot summary by situation.
:returns: dict of the form
.. code:: python
{
'agg': { 'ev/pp/sh/tot': { 'g': goals, 's': shots } },
'det': { '5v5/5v4/5v3/et c': { 'g': goals, 's': shots } }
}
"""
return self._rep_reader.shots['away']
@property
@dispatch_loader('_rep_reader', 'parse_home_by_player')
def home_players(self):
"""
Property that returns the home team by player summary..
:returns: dict of the form
.. code:: python
{
'num': {
'pos': pos,
'name': { 'first': first, 'last': last },
'g/a/p/pm/pn/pim/shifts/s/ab/ms/ht/gv/tk/bs': value
'fo': { 'won': won, 'tot': total },
'toi': {
'tot/avg/pp/sh/ev': { 'min': mins, 'sec': secs }
}
}
}
"""
return self._rep_reader.by_team['home']
@property
@dispatch_loader('_rep_reader', 'parse_away_by_player')
def away_players(self):
"""
Property that returns the away team by player summary..
:returns: dict of the form
.. code:: python
{
'num': {
'pos': pos,
'name': { 'first': first, 'last': last },
'g/a/p/pm/pn/pim/shifts/s/ab/ms/ht/gv/tk/bs': value
'fo': { 'won': won, 'tot': total },
'toi': {
'tot/avg/pp/sh/ev': { 'min': mins, 'sec': secs }
}
}
}
"""
return self._rep_reader.by_team['away']
@property
@dispatch_loader('_rep_reader', 'parse_home_fo')
def home_fo(self):
"""
Home team face off summary by strength.
:returns: dict of the form
.. code:: python
{
'ev/pp/sh/tot': { 'won': goals, 'total': shots }
}
"""
return self._rep_reader.face_offs['home']
@property
@dispatch_loader('_rep_reader', 'parse_away_fo')
def away_fo(self):
"""
Away team face off summary by strength.
:returns: dict of the form
.. code:: python
{
'ev/pp/sh/tot': { 'won': goals, 'total': shots }
}
"""
return self._rep_reader.face_offs['away']
def __apply_to_both(self, f):
return {
'home': f(self.home_players),
'away': f(self.away_players)
}
def totals(self):
[docs] """
Computes and returns dictionary containing home/away by player, shots and face-off totals
:returns: dict of the form ``{ 'home/away': { 'all_keys': w_numeric_data } }``
"""
def agg(d):
keys = ['g','a','p','pm','pn','pim','s','ab','ms','ht','gv','tk','bs']
res = { k: 0 for k in keys }
res['fo'] = { 'won': 0, 'total': 0 }
for _, v in d.items():
for k in keys:
res[k] += v[k]
for fi in res['fo'].keys():
res['fo'][fi] += v['fo'][fi]
return res
return self.__apply_to_both(agg)
def filter_players(self, pl_filter):
[docs] """
Return the subset home and away players that satisfy the provided filter function.
:param pl_filter: function that takes a by player dictionary and returns bool
:returns: dict of the form ``{ 'home/away': { by_player_dict } }``. See :py:func:`home_players` and :py:func:`away_players`
"""
def each(d):
return {
k: v
for k, v in d.items()
if pl_filter(k, v)
}
return self.__apply_to_both(each)
def sort_players(self, sort_key=None, sort_func=None, reverse=False):
[docs] """
Return all home and away by player info sorted by either the provided key or function. Must provide
at least one of the two parameters. Can sort either ascending or descending.
:param sort_key: (def None) dict key to sort on
:param sort_func: (def None) sorting function
:param reverse: (optional, def False) if True, sort descending
:returns: dict of the form ``{ 'home/away': { by_player_dict } }``. See :py:func:`home_players` and :py:func:`away_players`
"""
def each(d):
t = [ ]
for num, v in d.items():
ti = { vk: vv for vk, vv in v.items() }
ti['num'] = num
t.append(ti)
if sort_key:
return sorted(t, key=lambda k: k[sort_key], reverse=reverse)
else:
return sorted(t, key=sort_func, reverse=reverse)
return self.__apply_to_both(each)
def goal_scorers(self):
[docs] """
Return home/away by player info for the game's goal scorers.
:returns: dict of the form ``{ 'home/away': { by_player_dict } }``. See :py:func:`home_players` and :py:func:`away_players`
"""
return self.filter_players(
pl_filter=lambda num, stats: stats['g']
)
def point_getters(self):
[docs] """
Return home/away by player info for the game's point getters.
:returns: dict of the form ``{ 'home/away': { by_player_dict } }``. See :py:func:`home_players` and :py:func:`away_players`
"""
return self.filter_players(
pl_filter=lambda num, stats: stats['p']
)
def had_penalties(self):
[docs] """
Return home/away by player info for players who had a penalty.
:returns: dict of the form ``{ 'home/away': { by_player_dict } }``. See :py:func:`home_players` and :py:func:`away_players`
"""
return self.filter_players(
pl_filter=lambda num, stats: stats['pn']
)
def top_by_key(self, sort_key):
[docs] """
Return home/away by player info for the players on each team that are first in the provided category.
:param sort_key: str, the dictionary key to be sorted on
:returns: dict of the form ``{ 'home/away': { by_player_dict } }``. See :py:func:`home_players` and :py:func:`away_players`
"""
res = self.sort_players(sort_key=sort_key, reverse=True)
return {
'home': res['home'][0],
'away': res['away'][0]
}
def top_by_func(self, sort_func):
[docs] """
Return home/away by player info for the players on each team who come in first according to the
provided sorting function. Will perform ascending sort.
:param sort_func: function that yields the sorting quantity
:returns: dict of the form ``{ 'home/away': { by_player_dict } }``. See :py:func:`home_players` and :py:func:`away_players`
"""
res = self.sort_players(sort_func=sort_func, reverse=True)
return {
'home': res['home'][0],
'away': res['away'][0]
}
def top_toi(self):
[docs] """
Return home/away by player info for the players on each team who logged the most time on ice.
:returns: dict of the form ``{ 'home/away': { by_player_dict } }``. See :py:func:`home_players` and :py:func:`away_players`
"""
return self.top_by_func(
sort_func=lambda k: k['toi']['tot']['min']*60+k['toi']['tot']['sec']
)


Syntax Issues
JavaScript doesn't know how to interpret your code.
Mouse over the icons on the left to see more
detailed suggestions about how to make your code look
like valid JavaScript.
Try fixing the first error before
looking at the others. There's a chance this one problem
is the root cause of all the others!
{{name}}
Try looking for the problem here:
-
{{friendlyName(err.name)}} (line {{err.line}})
-
Line {{err.from.line + 1}}
()


How can I view the metadata for a file?
Sometimes, we might ask you to take a look at the metadata for a file to find out what it contains. It's not as scary as it sounds.
Download the Alfred Metadata Tool and install it.
Once you've installed it, launch it and drag a file to the left box for analysis.
Have a look at the output on the right, and copy it for us to see if we have asked you to send it to us.
Taking a look at metadata
The metadata is the underlying information available about a file. This will tell Spotlight, Alfred and any other apps that rely on it that, for example, the file is a PNG image with the title "Alfred Preferences Screenshot", located on the Desktop, with the creation and modification dates.
If your metadata doesn't show a Display Name and File Type at the top, or the kMDItemDisplayName is missing, then the file's metadata is incomplete.
If that's the case, take a look at the Indexing Troubleshooting Guide and follow step 4 to rebuild your Mac's index.
Example metadata for an image file
/Users/alfred/Desktop/Alfred Preferences Screenshot.png
Internal File Metadata
======================
Display Name: Alfred Preferences Screenshot
Alt Names: Alfred Preferences Screenshot.png
File Type: public.png
Comments:
Keywords:
Last Used: 2018-11-28 17:22:51 +0000
Raw mdls File Metadata
======================
_kMDItemOwnerUserID = 501
kMDItemAlternateNames = (
"Alfred Preferences Screenshot.png"
)
kMDItemBitsPerSample = 40
kMDItemColorSpace = "RGB"
kMDItemContentCreationDate = 2018-11-08 08:46:14 +0000
kMDItemContentModificationDate = 2018-11-08 08:46:14 +0000
kMDItemContentType = "public.png"
kMDItemContentTypeTree = (
"public.png",
"public.image",
"public.data",
"public.item",
"public.content"
)
kMDItemDateAdded = 2018-11-28 17:04:33 +0000
kMDItemDisplayName = "Alfred Preferences Screenshot"
kMDItemFSContentChangeDate = 2018-11-08 08:46:14 +0000
kMDItemFSCreationDate = 2018-11-08 08:46:14 +0000
kMDItemFSCreatorCode = ""
kMDItemFSFinderFlags = 16
kMDItemFSHasCustomIcon = (null)
kMDItemFSInvisible = 0
kMDItemFSIsExtensionHidden = 1
kMDItemFSIsStationery = (null)
kMDItemFSLabel = 0
kMDItemFSName = "Alfred Preferences Screenshot.png"
kMDItemFSNodeCount = (null)
kMDItemFSOwnerGroupID = 20
kMDItemFSOwnerUserID = 501
kMDItemFSSize = 41176
kMDItemFSTypeCode = ""
kMDItemHasAlphaChannel = 1
kMDItemIsScreenCapture = 1
kMDItemKind = "Portable Network Graphics image"
kMDItemLastUsedDate = 2018-11-28 17:22:51 +0000
kMDItemLogicalSize = 41176
kMDItemOrientation = 0
kMDItemPhysicalSize = 49152
kMDItemPixelCount = 209897
kMDItemPixelHeight = 431
kMDItemPixelWidth = 487
kMDItemProfileName = "iMac"
kMDItemResolutionHeightDPI = 0
kMDItemResolutionWidthDPI = 0
kMDItemScreenCaptureGlobalRect = (
1654
)
kMDItemScreenCaptureType = "selection"
kMDItemUseCount = 1
kMDItemUsedDates = (
"2018-11-28 00:00:00 +0000"
)


-
Welcome to Salmon Cookies Project
Let me say that the slamon Cookies are tha same as the Chocolate Chip Cookies but is bakced with salmon insted of Chocolate witch making it as a small snak insted of just a Cookie thats what makes our cookies uniqe and test worthy. It sounds strange right? Try it once and I assure you that its gonna make you comeback for more.


This project was created through SI 482 (an interaction design course), in which student's have a semester to identify a problem and then create a product which would solve it. I was put on a team with three other students at the beginning of the semester to complete the project with.
It took nearly a month and a dozen interviews for our team to identify a problem to design for. Our team ended up on the problem of education. Specifically, we found through our interviews that COVID-19 exposed many requirements that the current virtual learning environment failed to fill for young students. It was evident through our research that more effective, engaging, and motivating learning tools for young students are needed in both virtual and in-person learning environments.
From this need, we created Sprout School: a gamified education application which can be integrated into most school systems. At the end of the semester, it won best in class - beating out over 20 other product designs.
Initial onboarding screen
We began our design process by brainstorming several product ideas. Sprout School looked very different from what it is today; originally, we planned to compete with larger digital learning platforms like Google Classroom, Canvas, and Blackboard. However, the concept and design was altered after performing a competitive analysis, as we realized we were falling prey to scope creep. Another problem with our original concept was deeper than our scoping issues: we simply were not sure what problem we were trying to solve. The initial idea of improving upon current learning software like Google Classroom was far too ambitious and truthfully was not solving any real problem.
We conducted twelve user interviews to include our target market in the design process (which included parents, teachers, and elementary students) to better understand their perspective. From the research, we identified that students felt disconnected, loved gamified learning experiences, and wanted easy access to teacher help in a remote setting. With this in mind, we crafted a new problem statement and created personas and user scenarios which helped us solidify who we are designing for and how our concept would help them. The result was a complete shift in mindset: instead of replacing current learning software, we would design something which complemented it.
With our user interviews completed, we created personas which synthesized the key findings:
From our key findings, we established goals (which we called our five pillars) to guide our design process:
Our problems was rooted deep into the social aspect of the classroom. How do we encourage social interaction, encouragement, motivation and accountability? How can we build a community that may be hundreds of miles apart? How can this product be sustainable after the COVID pandemic? We narrowed our solution down to two products: a class garden which would collectively track each students growth in a communal setting, or a homework assistance app.
The homework assistance app storyboard
The class garden app storyboard
After much deliberation, we chose the "class garden" concept. Each student has a plant avatar that grows whenever they complete homework, and their plant is part of the larger class garden. The more the garden grows, the points the entire class receives. This concept would provide students with a visual representation of their growth; gamifying their educational experience and providing a communal project (the class garden) that each student strives to improve.
After creating paper a paper prototype and testing it, wireframes were created.
The first iteration of the class garden
An early iteration of the profile page
The first version of the homework center
With wireframes complete, the next step was to redesign them to a medium fidelity prototype. This prototype lacked interactions, but introduced several changes from the wireframe: the navigation bar was moved from the bottom of the screen to the side, the class garden content was restructured, and of course illustrations were added.
The first version of the class garden screen
A feature that was considered, but not to included, was a tutorial flow built into the onboarding experience. During testing phases, learnability was identified as a key problem, namely the “Award Kudos Badge” flow and understanding the points system as a whole. Based on feedback from peers, the team considered making a detailed tutorial to show first-time users how to engage with Sprout School. However, a high-intensity experience like that would be overwhelming and easy to forget, leaving users more confused than before. To fix the issues with discoverability, the team instead tactically implemented tooltips to remind users of critical details throughout the experience, for example in the “Class Garden” screen, where students can find a reminder of how points go towards the class goal.
The tooltip design
Following the creation of the static prototype, the next several weeks led to design iterations and introduced interactions. The first round of interactions was linking the pages together and making buttons clickable. The second round of interactions involved creating animations, different button states, and transitions. The final round of interactions was on adding small details to the interactions, such as creating a draggable class garden, updating plant art, creating a logo, and other small changes.
The final iteration of the class garden
A final iteration of the profile page
The final iteration of the homework centere
User flow map
Though just a prototype, Sprout School could revolutionize the student learning experience by providing stronger motivation, sense of community, and engagement. I appreciate you reading this far!
Want to view the full figma prototype?
Sprout School prototype link!


Include the http://gestalt.ironruby.com/d1/dlr-20091111/dlr.js
file on your page to enable
Ruby and Python script-tags on the HTML page:
<html> <head> <script type="text/javascript" src="http://ironruby.com/dlr/dlr.js"></script> </head> <body> <script type="text/ruby"> window.alert "Hello World from Ruby" </script> </body> </html>
Try out some simple examples: ruby | python | xaml | animation | final
And take a look at the paper: Back to "Just-Text"
Download the redistributable package
Place the package anywhere on your webserver, but keep in mind if you have to reference dlr.js with a path that's different than "../dlr.js", you'll have to add this to your HTML file before referencing dlr.js:
<script type="text/javascript"> window.DLR = {} DLR.path = "../../path/to/dlr" // where ../../path/to/dlr.js exists </script>
However, if you don't want to add this to every file, you can also add it to the top of dlr.js


[gecode-users] Stop search
christine bouzant
christine.bouzant at gmail.com
Mon Apr 8 16:45:45 CEST 2013
Hi Christian,
Actually, i'd like to accept any solution, even if sum(CanBeTaken)<4.
But if sum(CanBeTaken)>=4, i 'd like to stop search because i am not
interested by other solutions.
Cheers,
Christine
2013/4/7 Christian Schulte <cschulte at kth.se>
> Hi Christine,****
>
> ** **
>
> Hmm, no you can’t use stop objects for that. ****
>
> ** **
>
> Why would adding the condition sum(CanBeTaken) >= 4 to the script as a
> constraint not work? Then you would know that any solution would satisfy
> this property?****
>
> ** **
>
> Best****
>
> Christian****
>
> ** **
>
> --****
>
> Christian Schulte, www.ict.kth.se/~cschulte/****
>
> ** **
>
> *From:* users-bounces at gecode.org [mailto:users-bounces at gecode.org] *On
> Behalf Of *christine bouzant
> *Sent:* Saturday, April 06, 2013 10:01 AM
> *To:* users at gecode.org
> *Subject:* [gecode-users] Stop search****
>
> ** **
>
> Dear all,****
>
> I am new to gecode and constraint programming, so sorry by advance for my
> questions.****
>
> I'd like to stop search when in my model i have the condition****
>
> sum(CanBeTaken) >=4 where CanBeTaken is a BoolVarArray.****
>
> I have read about stop objects but as i understand, a stop object cannot
> take a model as argument since everything is copied in Gecode, right ?****
>
> Would you have a solution to stop search, depending of the current state
> of the model ?****
>
> Cheers,****
>
> Christine.****
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.gecode.org/pipermail/users/attachments/20130408/6e9d521d/attachment.html>
More information about the users
mailing list


No film is registered yet...
Do you really want to delete The Song Remains the Same: Part 2 from the list?


Welcome to Klara's
online portfolio
Klara Luisa Kohler is an Industrial Design Engineering student, passionate about product development, sustainability and new materials.
Have a look at a selection of her work below and read the case study of the projects
or click here to read more about her and download


The following assumes that an Apache server or another server capable of running PHP 5 is running on the default port (80) on localhost. The mxGraph top-level directory is assumed to be located at http://localhost/mxgraph.
In this example, a graph is programmatically created and turned into a PNG image. Point your browser to http://localhost/mxgraph/php/examples/graph.php to run this example.
Creates a HTML graphical representation for a GraphView which is stored in an XML file. Point your browser to http://localhost/mxgraph/php/examples/reader.php to run this example.
In order to be able to save files, the server.php file demonstrates how to accept a post request from a client, and put the data from the client request into a file on the disk.
Before accessing the HTML files, you must modify the config file of the example you want to use. For example, when using the diagrameditor.html file, you should modify javascript/examples/editors/config/diagrameditor.xml. The only change to the config file is to add the urlPost attribute to the mxEditor node as follows:
<mxEditor urlPost="php/examples/server.php" ... >
This enables the save function in the editor and will post the XML of the current diagram to the server.php on the server. The script will write the diagram to a local file called diagram.xml in the same directory as the script is located.
Note that you will have to add the save action in the user interface. To add the save action to the dropdown list of actions, change the items in the diagrameditor.html file as follows:
var items = ['redo', 'ungroup', 'cut', 'copy', 'paste', 'show', 'exportImage', 'save'];
To use the example, point your browser to http://localhost/mxgraph/javascript/examples/editors/diagrameditor.html


Have a look at the files in the /Images folder. Edit the img element on this page so that it displays the correct image based on the selected value of the "Dog size" dropdown list.
Create another dropdown list called "Breed" which binds to the breed property of the objects in the dogs array.
Create an anchor tag around the image, containing the link to a Google search for the breed selected in the "Breed" dropdown. Hint: The direct url to a Google search is https://www.google.com/#q=yourQuery


|
NEWSVR
|
This handles the speaker, it uses the interop.speechlib dll. The position and replacement is the same as the microphone. It starts to read the article when in hand and stops when releases. More...
Public Attributes | |
| GameObject | Text |
| Public Attributes inherited from Assets.Scripts.Core.Grabbable | |
| Hand.AttachmentFlags | attachmentFlags = Hand.AttachmentFlags.ParentToHand | Hand.AttachmentFlags.DetachFromOtherHand |
| The flags used to attach this object to the hand. More... | |
| bool | restoreOriginalParent = false |
| When detaching the object, should it return to its original parent? More... | |
Protected Member Functions | |
| new void | OnAttachedToHand (Hand hand) |
| new void | OnDetachedFromHand (Hand hand) |
| Protected Member Functions inherited from Assets.Scripts.Core.Grabbable | |
| void | OnHandHoverBegin (Hand hand) |
| void | OnHandHoverEnd (Hand hand) |
| void | HandHoverUpdate (Hand hand) |
| void | OnAttachedToHand (Hand hand) |
| void | OnDetachedFromHand (Hand hand) |
| void | HandAttachedUpdate (Hand hand) |
| void | OnHandFocusAcquired (Hand hand) |
| void | OnHandFocusLost (Hand hand) |
Additional Inherited Members | |
| Protected Attributes inherited from Assets.Scripts.Core.Grabbable | |
| Interactable | interactable |
| SteamVR Interactable script. Allow the gameobject to receive messages from the hands. See SteamVR documentation. More... | |
This handles the speaker, it uses the interop.speechlib dll. The position and replacement is the same as the microphone. It starts to read the article when in hand and stops when releases.
Attached to : Resources/Prefabs/News/News/InTheNews/Canvas_Story/Speaker


One of the great “features” of ClickHouse is a friendly and welcoming community. In this article we would like to outline how the ClickHouse community arose, what it is today, and how you can get involved. There is a role for everyone, from end users to contributors to corporate friends. Our goal is to make the community welcoming to every person who wants to join.
But first, let’s review a bit of history, starting with how ClickHouse first developed at Yandex.
Origins at Yandex
ClickHouse began as a solution for web analytics in Yandex Metrica. Metrica is a popular service for analyzing website traffic that is now #2 in the market behind Google Analytics. In 2008 Alexey Milovidov, an engineer on the Metrica team, was looking for a database that could create reports on metrics like number of page views per day, unique visitors, and bounce rate, without aggregating the data in advance. The idea was to provide a wide range of metric data and let users ask any question about them.
This is a classic problem for data warehouses. However, Alexey could not find one that met Yandex requirements, specifically large datasets, linear scaling, high efficiency, and compatibility with SQL tools. In a nutshell: like MySQL but for analytic applications. So Alexey wrote one. It started as a prototype to do GROUP BY operations.
The prototype evolved into a full solution with a name, ClickHouse, short for “Clickstream Data Warehouse”. Alexey added additional features including SQL support and the MergeTree engine. The SQL dialect was superficially similar to MySQL, which was also used in Metrica but could not handle query workloads without complex pre-aggregation. By 2011 ClickHouse was in production for Metrica.
Over the next 5 years Alexey and a growing team of developers extended ClickHouse to cover new use cases. By 2016 ClickHouse was a core Metrica backend service. It was also becoming entrenched as a data warehouse within Yandex, extending to use cases like service monitoring, network flow logs, and event management. ClickHouse had evolved from the original one-person project to business critical software with a full team of a dozen engineers led by Alexey.
By 2016, ClickHouse had an 8 year history and was ready to become a major open source project. Here’s a timeline that tracks major developments as a time series.
ClickHouse goes open source
Yandex open sourced ClickHouse under an Apache 2.0 license in 2016. There were numerous reasons for this step.
- Promote adoption within Yandex by making it easier for internal departments to get builds.
- Ensure that ClickHouse would continue to evolve by creating a community to nurture it.
- Motivate developers to contribute to and use ClickHouse due to the open source “cool” factor.
- Improve ClickHouse quality by making the code public. Nobody wants their name visible on bad code. ;-)
- Showcase Yandex innovation to a worldwide audience.
Alexey and the development team moved ClickHouse code to a Github repo under the Yandex organization and began issuing community builds as well as accepting external contributions. They simultaneously began regular meetups to popularize ClickHouse and build a community around it. The result was a burst of adoption across multiple regions of the globe.
ClickHouse quickly picked up steam in Eastern Europe. The first ClickHouse meetups started in 2016 and have grown to include 200 participants for in-person meetings and up to 400 for online meetings. ClickHouse is now widely used in start-ups in Russia as well as other Eastern European countries. Developers located in Eastern Europe continue to supply more contributions to ClickHouse than any other region.
ClickHouse also started to gain recognition in the US and Western Europe. CloudFlare published a widely read blog article about their success using ClickHouse for DNS analytics.
ClickHouse also took off in China. The first meetup in China took place in 2018 and attracted enormous interest. In-person meetups included over 400 participants. Online meetings have reached up to 1000 online viewers.
In 2019 a further step occurred as ClickHouse moved out from under the Yandex Github organization into a separate ClickHouse organization. The new organization includes ClickHouse server code plus core ecosystem projects like the cpp and ODBC drivers.
ClickHouse community events shifted online following world-wide disruptions due to COVID-19, but growth in usage continued. One interesting development has been the increasing number of startups using ClickHouse as a backend. Many of these are listed on the ClickHouse Adopters page. Also, additional prominent companies like eBay, Uber, and Flipcart went public in 2020 with stories of successful ClickHouse usage.
The ClickHouse community today
As of 2020 the ClickHouse community includes developers and users from virtually every region of the globe. Yandex engineers continue to supply a majority of pull requests to ClickHouse itself. Altinity follows in second place with contributions to ClickHouse core and ecosystem projects. There is also substantial in-house development on ClickHouse (e.g. on private forks) within Chinese internet providers.
The real success, however, has been the huge number of commits to ClickHouse core from people in outside organizations. The following list shows the main outside contributors:
- Azat Khuzhin
- Amos Bird
- Winter Zhang
- Denny Crane
- Danila Kutenin
- Hczhcz
- Marek Vavruša
- Guillaume Tassery
- Sundy Li
- Mikhail Shiryaev
- Nicolae Vartolomei
- Igor Hatarist
- Andrew Onyshchuk
- BohuTANG
- Yu Zhi Chang
- Kirill Shvakov
- Alexander Krasheninnikov
- Simon Podlipsky
- Silviu Caragea
- Flynn ucasFL
- And over 550 more...
ClickHouse ecosystem projects are also growing rapidly. Here is a selected list of active Github projects that help enable ClickHouse applications, sorted by number of stars.
- sqlpad/sqlpad — Web-based SQL editor that supports ClickHouse
- mindsdb/mindsdb — Predictive AI layer for databases with ClickHouse support
- x-ream/sqli — ORM SQL interface
- tricksterproxy/trickster — HTTP reverse proxy cache and time series dashboard accelerator
- ClickHouse/clickhouse-go — Golang driver for ClickHouse
- gohouse/gorose — A mini database ORM for Golang
- ClickHouse/clickhouse-jdbc — JDBC driver for ClickHouse
- brockercap/Bifrost — Middleware to sync MySQL binlog to ClickHouse
- mymarilyn/clickhouse-driver — ClickHouse Python driver with native interface support
- Vertamedia/clickhouse-grafana — Grafana datasource for ClickHouse
- smi2/phpClickHouse — PHP ClickHouse client
- AlexAkulov/clickhouse-backup — ClickHouse backup and restore using cloud storage
- And almost 1200 more...
Resources
With the community growth numerous resources are available to users. At the center is the ClickHouse org on Github, which hosts ClickHouse server code. ClickHouse server documentation is available at the clickhouse.tech website. It has installation instructions and links to ClickHouse community builds for major Linux distributions as well as Mac, FreeBSD, and Docker.
In addition, ClickHouse users have a wide range of ways to engage with the community and get help on applications. These include both chat applications as well as meetups. Here are some links to get started.
- Yandex Meetups — Yandex has regular in-person and online international and Russian-language meetups. Video recordings and online translations are available at the official YouTube channel. Watch for announcements on the clickhouse.tech site and Telegram.
- SF Bay Area ClickHouse Meetup — The largest US ClickHouse meetup, with meetings approximately every 2 months.
- Chinese meetups occur at regular intervals with different sponsors. Watch for announcements on clickhouse.tech.
- Telegram - By far the largest forum for ClickHouse. It is the best place to talk to ClickHouse devs. There are two groups.
- ClickHouse не тормозит (“ClickHouse does not slow down”) - Russian language Telegram group with 4,629 members currently.
- ClickHouse — English language group with 1,286 members.
- ClickHouse Community Slack Channel — Public channel for Slack users. It currently has 551 members.
- ClickHouse.com.cn — Chinese language site for ClickHouse-related announcements and questions.
- Conference Presentations — ClickHouse developers like to talk and do so whenever they can. Many recent presentations are stored in Github. Also, look for ClickHouse presentations at Linux Foundation conferences, Data Con LA, Percona Live, and many other venues where there are presentations about data.
- Technical webinars — Altinity has a large library of technical presentations on ClickHouse and related applications on the Altinity Youtube channel.
If you know of additional resources please bring them to our attention.
How you can contribute to ClickHouse
We welcome users to join the ClickHouse community in every capacity. There are four main ways to participate.
Use ClickHouse and share your experiences
Start with the documentation. Download ClickHouse and try it out. Join the chat channels. If you encounter bugs, log issues so we can get them fixed. Also, it’s easy to make contributions to the documentation if you have basic Github and markdown skills. Press the pencil icon on any page of the clickhouse.tech website to edit pages and automatically generate pull requests to merge your changes.
If your company has deployed ClickHouse and is comfortable talking about it, please don't be shy. Add them to the ClickHouse Adopters page so that others can learn from your experience.
Become a ClickHouse developer
Write code to make ClickHouse better. Here are your choices.
-
ClickHouse server — Start with the “For Beginners” documentation to learn how to build ClickHouse and submit PRs. Check out the current ClickHouse issues if you are looking for work. PRs that follow the development standards will be merged faster.
-
Ecosystem projects — Most projects in the ClickHouse ecosystem accept PRs. Check with each project for specific practices.
ClickHouse is also a great target for research problems. Overall the years many dozens of university CS students have worked on ClickHouse features. Alexey Milovidov maintains an especially rich set of project suggestions for students. Join Telegram and ask for help if you are interested. Both Yandex and Altinity also offer internships.
Where we go from here
ClickHouse has grown enormously from its origins as a basic prototype in 2008 to the popular SQL data warehouse users see today. Our community is the rock that will enable ClickHouse to become the default data warehouse worldwide. We are working together to create an inclusive environment where everyone feels welcome and has an opportunity to contribute. We welcome you to join!
This article was written with kind assistance from Alexey Milovidov, Ivan Blinkov, and Alexander Zaitsev.
2020-12-11 Robert Hodges


Learning CaaS Operations with Docker Datacenter
Intro to Instructor
Insert Pic Here
A Note on Pedagogy
- Docker believes in learning by doing, with support.
- Passing the course: 70+ on final assessment.
Session Logistics
- 7 hours duration
- 80% lab exercises, 20% lecture
- Short break every hour
- Snack at 10:30am
- Lunch at Noon
- Afternoon Snack at 3pm
- End at 5pm
Assumed Knowledge and Requirements
- Familiarity with using the Linux command line
- Docker Toolbox installed on your PC or Mac
- You should know the basics of Docker
- Run a Docker container
- Search for and pull images from Docker Hub
- Use Docker Toolbox on your local PC or Mac
Your lab environment
- You have been given three AWS instances with UCP pre-installed
- ucp-controller
- ucp-node-0
- ucp-node-1
- You also have 1 AWS node with an LDAP server pre-installed
- Instances will be used for lab exercises
- AWS Credentials and access key have been emailed
- UCP default login and password is admin / orca
Agenda
- Introduction
- Docker Primer + Access Course Content
- Task: Configure your environment
- Task: Deploy an NGINX Container
- Mini-lecture: Swarm
- Task: Deploy more Containers
- Mini-lecture: Docker Compose
- Task: Deploy Applications with UCP Web Interface
- Task: Deploy Applications with CLI
- Mini-lecture: Docker Networking
- Task: Deploy Multi Node Application
- Mid course assessment
- Task: Create Users and Teams
- Mini Lecture: User Management
- Task: Test User Access
- Mini Lecture: UCP Access Control
- Task: Advanced User Management
- Task: User Management with LDAP
- Task: Troubleshooting Lab - Password recovery
- Task: Troubleshooting lab - User Access
- Mini Lecture - Monitoring and Recovery of UCP and applications
- Task: Node Recovery
- Post-assessment
- Conclusion
Get your course content
- Slides run on Reveal JS
- We have Dockerized the presentation
- Run your own Reveal.js container to display the presentation locally
$ docker run -ti --rm -v /var/run/docker.sock:/var/run/docker.sock training/docker-present -p 8080
Review: You just learned Docker basics!
Toolbox
Containers
Images


S
entencePress
Because a sentence is better than a word.
Login
Logout
Admin
Compose
number of posts to show
Recent Posts


Information for organizers¶
Thanks for your interest in organizing one of the chapters of the pandas documentation sprint. It will surely be an amazing experience to work with Pythonistas all around the world. And the hundreds of thousands of users of pandas will surely appreciate having better documentation.
This document provides the information you need, in order to join the sprint.
The venue¶
The first thing, and in some cases the most difficult is to find a venue for the sprint. In most cases, sprints will be hosted in the offices of a company that will provide them for free. And even better, that will also provide drinks and lunch.
It is up to you to decide the number of people who can join your sprint, but we do not recommend more than 20. If you are not that much experienced with open source, pandas or organizing events, probably 20 is even too much.
The basic requirements for a venue is to have tables or desks for people to sit in a comfortable way, wifi, and electricity for people to charge their computers.
If you are the organizer of a user group, probably you already have experience with it. If you are not, here you have some tips:
Find the local user groups, mainly Python and PyData user groups. Organizers may already have some companies who hosted events before, and are happy to do it again. If that is not the case, they can mail the members of the community, and surely one of them works in a company happy to offer the venue.
If that does not work for you, universities, local government agencies supporting employment and entrepreneurship, startup incubators, and co-working spaces, could be interested in offering you a venue. In general, it is easier to get a positive answer by trying to directly contact someone there, than by filling a form or sending an email to info@whatever.
Another option is to check www.meetup.com for other groups (other programming languages or tech meetups mainly). See where they host their events, and if it seems like one of them could work, contact the organizer of the group to get introduced to their contact in the venue.
One more option is to check for job offers related to pandas/Python, and contact the companies asking if they could be interested in hosting the event. Python programmers and data scientists are hard to find, and it can be a great opportunity for them, to get their company promoted.
If nothing else works, you can find a bar, pub, restaurant… with some quiet area for the sprint. And if you do not even find that, please contact us, and we will find a solution.
The local community and publishing the event¶
Now that you have got a venue, you need people to come to the event. Again, if you are the organizer of a user group, you already know what to do. If you are not, get in touch with a local Python user group, or PyData meetup. To find them:
- https://wiki.python.org/moin/LocalUserGroups
- https://www.meetup.com/pro/pydata
- Using a search engine
Based on our experience, Python communities are always very welcoming, and happy to help. If they are using www.meetup.com, the simplest is that they create an event for you, and give you permissions as an event host, so you can manage the event.
If the local community is using a distribution list, google groups, or something similar, you can use that to promote the sprint, but you can create the event in a page like www.eventbrite.com so you can manage and control attendance.
In the unlikely case that there is no organized community where you are, you should consider starting one. The Python Software Foundation and NumFOCUS provide financial help to pay the meetup fees, and they can also help get started.
Selecting attendees¶
In general, most events are managed in a first come, first served way. While the decision on how to manage attendees is yours, we recommend to follow the next approach:
- Ask people about their level in Python, pandas, git and contributing to open source
- Do not let people join the event directly, add them to the waiting list first
The reason for that, is that a sprint is different from talks are tutorials, in the way that people need to be independent and capable of working on the sprint task. If you have a sprint with only people who just started learning Python (which is not so unlikely), there is not much that will be done. And regardless of pandas and the contributions, this will be very disappointing for attendees.
Keeping a good proportion of experienced people, will make sure that newcomers have someone to learn from, and people can make good contributions and enjoy the day.
Another thing to consider when deciding the attendees, is inclusion and diversity. The Python community has put a lot of effort in being an inclusive community, and this is something good for all. In practice, you may want to give priority to people from underrepresented minorities. What is an underrepresented minority is subjective, but it is probably reasonable to consider:
- Non male (which does not necessarily mean female)
- People over an age (50 year old?)
- Ethnic background depending on where you are
We do not recommend asking people for their race, sexual orientation, religion… in order to find people from underrepresented minorities. We find a better practice to kindly request people to let you know if they consider they are, and use common sense based on their answers.
Updating the global event website¶
When you find your venue, create the event… it would be good that you keep the main website of the event updated with it:
https://python-sprints.github.io/pandas/
This way, anyone interested in joining (or organizing) the event in your city can quickly find you.
To get your data in the website, the best option is to send a pull request adding the information of your chapter to the list of chapters:
https://github.com/python-sprints/python-sprints.github.io/blob/master/pandas/index.html#L25
If you do not know how to send a pull request, it is a good time to start learning it, as in the sprint is basically what you need to do. :)
In short:
- Fork the repository (click on the top right “Fork” button at https://github.com/python-sprints/python-sprints.github.io
- Clone your fork: git clone git@github.com:<your-github-user>/python-sprints.github.io.git
- Inside your local copy of the repo (cd python-sprints.github.io)…
- Create a branch for your changes: git checkout -b adding_<your-city>_chapter
- Edit the file with the chapter info: vim pandas/index.html and add an entry with the same fields as the rest
- Add your changed to be committed: git add pandas/index.html
- Commit your changes: git commit -m “Adding <your-city> to the pandas sprint page”
- Push your changes to your fork: git push -u origin adding_<your-city>_chapter
- Create a pull request by clicking on the “Compare & pull request” button in the yellow box at https://github.com/python-sprints/python-sprints.github.io
- Write a short description and save
Getting ready for the sprint¶
Even if writing documentation seems easy, it is not. And if you are not familiar contributing to open source, you probably discovered that sending a pull request is not trivial either.
For this reason, we expect at least one person in each sprint, to make a contribution to the pandas documentation before the sprint. This way you will have a much better understanding of the process, and of all the subtle details concerning docstrings.
For you first, and for all the participants in the sprint later, we prepared a guide with detailed information on all the required steps to work on the pandas documentation.
At the moment this documentation is under discussion, but it will soon be in its final state. You can find it here:
https://python-sprints.github.io/pandas/guide/
There is a document on how to set up your computer for the sprint, which attendees are expected to follow before the sprint.
Then there is a very detailed tutorial on how to write a docstring.
Finally, there are instructions on how to send a pull request.
The day of the sprint¶
On the day of the sprint, please be in the venue at least 30 minutes before the announced time (as many people usually arrived earlier).
Before the sprint, every organizer will have the list of pandas methods and functions for their chapter. So, there is no duplicate work having people in different chapters working on the same.
For your chapter, you need to manage that people do not duplicate work among this list. You can use a whiteboard, a shared google docs spreadsheet, or a gitter channel. Whatever you think it is better.
We recommend people to pair program. Meaning that two people will be working in a single computer, and will discuss about everything they code. Ideally, pairs of experienced and junior people. Pair programming will not only make the experience more social and enjoyable, but will help avoid mistakes, and improve the quality of the documentation.
Keep in mind that the main goal of the event is that people have fun and enjoy the day. For that, make sure:
- Everybody is treated with courtesy, dignity and respect
- There is no form of discrimination, harassment or bullying
We do not expect to have any problem in this respect, but if you find any behavior that can make anyone feel uncomfortable, please let the person know politely, and keep a welcoming environment for everyone at all times.
One important thing to consider, is that quality is much more important than quantity. For pandas, it will be much more productive if we send 50 excellent pull requests, than if we send 500 not so good pull requests.
Core developers are usually the bottleneck of open source projects. And while with their experience they will surely provide great reviews to enrich our contributions, we surely do not want to waste their time by reviewing code that doesn’t work, spelling mistakes, bad grammar, incorrect text, or anything like that. In the documentation for the sprint we provide as many methods as possible to assure quality in our end. If there is something that you can do in your end, that is highly appreciated.
Do not forget¶
Please, during the sprint do not forget to keep tweeting about your local chapter with the hashtag #PandasSprint. Also, make as many photos as possible.
We will have a gitter channel for the people in all the sprints, so there is communication, and people can ask questions if they have them. The channel is:
https://gitter.im/py-sprints/pandas-doc
We can also create a specific channel for your chapter, if you think that is useful.
We will also have couple of videocalls between chapters. Exact times will be announced later. We will use this hangouts link:


// ======================================================= // The compiler implements support for the using statement // with the help of the closable interface. Classes that // need to be closed after operating with them, such as // streams, should implement this interface. // ======================================================= namespace System { public interface Closable { void Close(); } }


| Package | Description |
|---|---|
| odata.msgraph.client.beta.complex |
| Modifier and Type | Method and Description |
|---|---|
static HardwareInformation.Builder |
HardwareInformation.builder()
Returns a builder which is used to create a new
instance of this class (given that this class is immutable).
|
HardwareInformation.Builder |
HardwareInformation.Builder.cellularTechnology(String cellularTechnology)
“Cellular technology of the device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.deviceFullQualifiedDomainName(String deviceFullQualifiedDomainName)
“Returns the fully qualified domain name of the device (if any).
|
HardwareInformation.Builder |
HardwareInformation.Builder.deviceGuardLocalSystemAuthorityCredentialGuardState(DeviceGuardLocalSystemAuthorityCredentialGuardState deviceGuardLocalSystemAuthorityCredentialGuardState)
“Local System Authority (LSA) credential guard status.”
|
HardwareInformation.Builder |
HardwareInformation.Builder.deviceGuardVirtualizationBasedSecurityHardwareRequirementState(DeviceGuardVirtualizationBasedSecurityHardwareRequirementState deviceGuardVirtualizationBasedSecurityHardwareRequirementState)
“Virtualization-based security hardware requirement status.”
|
HardwareInformation.Builder |
HardwareInformation.Builder.deviceGuardVirtualizationBasedSecurityState(DeviceGuardVirtualizationBasedSecurityState deviceGuardVirtualizationBasedSecurityState)
“Virtualization-based security status.”
|
HardwareInformation.Builder |
HardwareInformation.Builder.freeStorageSpace(Long freeStorageSpace)
“Free storage space of the device.”
|
HardwareInformation.Builder |
HardwareInformation.Builder.imei(String imei)
“IMEI”
|
HardwareInformation.Builder |
HardwareInformation.Builder.isEncrypted(Boolean isEncrypted)
“Encryption status of the device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.isSharedDevice(Boolean isSharedDevice)
“Shared iPad”
|
HardwareInformation.Builder |
HardwareInformation.Builder.isSupervised(Boolean isSupervised)
“Supervised mode of the device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.manufacturer(String manufacturer)
“Manufacturer of the device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.meid(String meid)
“MEID”
|
HardwareInformation.Builder |
HardwareInformation.Builder.model(String model)
“Model of the device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.operatingSystemEdition(String operatingSystemEdition)
“String that specifies the OS edition.”
|
HardwareInformation.Builder |
HardwareInformation.Builder.operatingSystemLanguage(String operatingSystemLanguage)
“Operating system language of the device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.operatingSystemProductType(Integer operatingSystemProductType)
“Int that specifies the Windows Operating System ProductType.
|
HardwareInformation.Builder |
HardwareInformation.Builder.osBuildNumber(String osBuildNumber)
“Operating System Build Number on Android device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.phoneNumber(String phoneNumber)
“Phone number of the device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.serialNumber(String serialNumber)
“Serial number.”
|
HardwareInformation.Builder |
HardwareInformation.Builder.sharedDeviceCachedUsers(List<SharedAppleDeviceUser> sharedDeviceCachedUsers)
“All users on the shared Apple device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.sharedDeviceCachedUsersNextLink(String sharedDeviceCachedUsersNextLink)
“All users on the shared Apple device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.subscriberCarrier(String subscriberCarrier)
“Subscriber carrier of the device”
|
HardwareInformation.Builder |
HardwareInformation.Builder.totalStorageSpace(Long totalStorageSpace)
“Total storage space of the device.”
|
HardwareInformation.Builder |
HardwareInformation.Builder.tpmSpecificationVersion(String tpmSpecificationVersion)
“String that specifies the specification version.”
|
HardwareInformation.Builder |
HardwareInformation.Builder.wifiMac(String wifiMac)
“WiFi MAC address of the device”
|
Copyright © 2018–2020. All rights reserved.


---
layout: site
permalink: wellington
location: Wellington
dates: 8 February - 10 February, 2017
splashImage: /img/wellington.jpg
map: sites/wellington.geojson
---
The Wellington Research Bazaar is a three day conference promoting the digital literacy emerging at the centre of modern research. In the spirit of a marketplace or bazaar, ResBaz is a highly participatory event where researchers from many different disciplines can learn new skills, showcase current projects, and share knowledge.
Code is comprised of Software Carpentry courses where you can get stuck into learning the basics of research computing;
Learn has various sessions to introduce a range of interesting programs, tools, and research tips and tricks;
Play will allow for hands-on interactions with a number of novel technologies.
(SOFTWARE CARPENTRY)
The Unix Shell allows you to do complex things with just a few keystrokes. More importantly, it helps them combine existing programs in new ways and automate repetitive tasks. The best way to learn how to program is to do something useful, so this introduction to Python is built around a common scientific task - data analysis. Our real goal isn’t to teach you Python, but to teach you the basic concepts that all programming depends on. Version control is the lab notebook of the digital world. It’s what professionals use to keep track of what they’ve done and to collaborate with other people. Every large software development project relies on it, and most programmers use it for their small jobs as well. And it isn’t just for software - books, papers, small data sets, and anything that changes over time or needs to be shared can and should be stored in a version control system.
- Who is NeSI (INTRODUCTORY ELECTIVES)
If data is the new gold, then survey-creation software Qaultrics maybe the gold digging tool you need. Learn how to capture both qualitative and quantitative data effectively by understanding survey design principles and tools. Sign up for an account here. Get an edge by better understanding the explosion of unstructured data in the world today using NVivo — powerful software for qualitative data analysis. VUW staff can download NVivo via the ITS Software Download Site. Overview of a range of free tools useful for digital history projects, including StoryMap, which fuses digital mapping with interactive storytelling. Possible assets to use here An introductory session outlining the basics of R, a free software environment for statistical computing and graphics, which will be followed by a hands-on workshop. ggplot2 is a plotting system for R, based on the grammar of graphics, which tries to take the good parts of base and lattice graphics and none of the bad parts. It takes care of many of the fiddly details that make plotting a hassle (like drawing legends) as well as providing a powerful model of graphics that makes it easy to produce complex multi-layered graphics. Promote your publications, increase impact and collaborate in research by learning about alternative metrics, social networking and unique author identifiers. Learn how to create dynamic websites for research projects using Weebly LaTeX is a document preparation system for high-quality typesetting. It is most often used for medium-to-large technical or scientific documents but it can be used for almost any form of publishing. Learn from Stuart Yeats about how you research outputs might best intersect with Wikipedia, and consider the question: when it comes to the world's largest reference site, is the truth relevant? Esri Story Maps let you combine authoritative maps with narrative text, images, and multimedia content. They make it easy to harness the power of maps and geography to tell your story. TimelineJS is an open-source tool that enables anyone to build visually rich, interactive timelines. Beginners can create a timeline using nothing more than a Google spreadsheet. See how they're being used by research projects at Victoria, and try making one for yourself.
The Tertiary Education Committee invest nearly $2.8 billion into tertiary education each year to ensure New Zealanders are equipped with the knowledge and skills needed for lifelong success. Hear how they use data anayltics and business insights to assist with the process.
Take a step back into the analogue and a history of the nineteenth century printing press with a guided, hands-on tour of the Wai-te-ata Press by Syndey Shep Multi-disciplinary teams collaborate to turn open government data sets into compelling, data-driven narratives.
{{page.dates}}
About
Researchers at all levels and from all disciplines are encouraged to apply.
Research technologists who support researchers to do their job are welcome also.
The Wellington ResBaz will be broken into two key streams: Code and Learn. There's also a drop-in Play stream.
There will be speakers from all stages of their research careers in various fields, as well as highlights on up-and-coming projects.
Read more about the history and philosophy of ResBaz in these blog posts from The Research Whisperer and Software Carpentry.
CODE
- When is High Performance Computing (HPC) useful
- HPC services offered by NeSI
- How to access NeSI
- Short HPC live demonstration
LEARN
Lesson downloads:
overview |
R |
R Studio
Related links:
Wikipedia Authority Control ;
NZ Research ;
Wikimedia Projects.
EVERYTHING ELSE
ResBaz Wellington 2017 will be held in and around the Hub
at Victoria University of Wellington's Kelburn Campus.
The Challenge: As a team, adopt a persona and scenario where open data can be used to inform decision making. Feel free to create any persona you like, or use the following options as a starting point:
Be specific to help bring your persona to life. Give them a gender, ethnicity, age, interests etc. For some ideas about what to do you could refer to overviews such as this one.
Nominate one or two team members to present your findings, ideally with a slide show or online tools rich with visualisations, graphs and data points to accompany your story and justify your decisions. You might want to use some of tools showcased at ResBaz (eg. R, TimeLineJS, StoryMapJS, Basic Story Map, Weebly, Qlik Sense, Python) or other easy-to-use online tools such as infogr.am, Voyant, piktochart, or the tools outlined here
Some (but by no means all) datasets you might look to use:
ResBaz Wellington 2017 will be held in and around the Hub
at Victoria University of Wellington's Kelburn Campus.
Many thanks to all our sponsors for helping bring the Resarch Bazaar to Wellington.


rotten > Library > Biographies > Crime > Spree Killers > James Oliver Huberty
James Oliver Huberty
Perpetrated San Ysidro McDonald's massacre, killing 21 in 1984.
Co-worker James Aslanes: "He would talk about rapists. He mentioned what should be done with them: that they should cut off their fingers, they should cut off their hands and tie them up by their testicles. Things like that frightened me."
Timeline
| 11 Oct 1942 |
James Oliver Huberty born, Canton OH. |
| 1964 |
Trains to be an undertaker, Don Williams Funeral Home. |
| 1971 |
Hubert's house burns to the ground, Massillon OH. |
| 1965 |
Marries wife Etna. |
| 1980 |
Arrested, drunk and disorderly conduct. |
| Dec 1982 |
Laid off from welding job when the Babcock and Wilcox plant in Canton closes. |
| Jan 1984 |
Moves to Southern California. |
| 18 Jul 1984 |
Telling his wife "I'm going to hunt humans", Huberty proceeds to the San Ysidro McDonald's a quarter mile from his house and opens fire with a variety of weapons -- 12ga shotgun, Browning 9mm, Uzi carbine -- killing 21 and wounding 19. He fires 245 rounds before a shot from a police sniper's .308 ends the spree at 5:17 pm. |
| 26 Sep 1984 |
A work crew destroys the San Ysidro McDonald's. |
Pornopolis |
Rotten |
Faces of Death |
Famous Nudes
|


{% include "inc/head.html" %} {% if userAuthKey != '__removed__' %}
Are you sure you want to remove the following SSH key? remove - cancel
{{userAuthKey.key_name}} {{userAuthKey.fingerprint}} {{userAuthKey.key_bits}} {{userAuthKey.key_protocol}}
{% endif %} {% include "inc/tail.html" %}