First of all, a correction:
Parsing algorithms are not made for programming languages; they are made for language Grammars.
A Grammar is a set of rules that specify how you can write characters one after the other in order to form valid sentences (that is, valid for that grammar).
For example, the English grammar tells us that you can put the characters ‘y’, ‘o’, ‘u’ one after the other and form a valid token (the word “you”), and that if you also add the characters ‘ ‘, ‘a’, ‘r’, ‘e’, ‘ ‘, ‘g’, ‘r’, ‘e’, ‘a’, ’t’, you will have made a valid sentence (that is, “you are great”). The English grammar defines the English language.
Formal Grammars work in similar way. The confusion arises because Formal Grammars are used in computer science to define new programming languages, and therefore the two definitions often get mixed. But I hope that now the distinction is clear.
Now, let’s answer the question.
A parser is an algorithm designed in order to take a sequence of tokens and decide whether that sequence is valid in the considered grammar.
This answer generates more questions, as it often happens. Here are some:
Where does the sequence of tokens come from?
From a broader point of view, a Compiler takes a stream of characters in input, for example a file with the source code of the program that must be compiled. The first step in the compilation process, called Lexical Analysis, takes care of producing the sequence of tokens from the entire characters stream. Such a sequence is then fed into the Parser, which is the second step of the compilation.
Does the parser only decide whether to accept or reject the tokens sequence? Like a Yes/No answer?
Strictly speaking, that’s correct. A parser can “just” make a decision about acceptance or rejection of the input. However, to do so it builds some data structure (tree-like) and perform some computations on it. Such data structure is also useful in the remainder of the compilation process, and therefore is not discarded by the parser, rather it can be considered its output.
What makes a tokens sequence valid?
It’s all about respecting the rules set by the Grammar. If the tokens are put one after the other in a valid order then the sequence is accepted. However, Grammars are complicated beasts, so the algorithm to decide on the validity of a token sequence is not trivial. If it was, then this article would stop here!
I believe the answers so far give a pretty good understanding of what a Parser is, although a bit too general. Let’s then go into more details.
Different Types of Parsing Algorithms
Writing a parsing algorithm is a bit like an artistic effort. In fact, if you google or maybe search on GitHub, you will find thousands of programmers who have made their own domain-specific parser. The logic and the algorithms of these Parsers do not basically follow any pattern.
Even though you can create a parser from scratch and without knowing much theory, that is not how you should do it. Science and theory exist for a good reason: to guide scientists as well as engineers and practitioners. That’s just my opinion, of course.
Thus, instead of jumping right away into writing some code that may or may not work eventually, I always try to take my time to research the problem and see what the state of the art is.
In the case of Grammar Parsing Algorithms, it turns out that the state of the art algorithms are pretty solid and widely used for a very big class of grammars (more on this last point in a minute).
Let me say it again, in different words:
You should really avoid to write a parser without first studying and understanding the basic parsing patterns that are used in the most famous compilers.
Thus, to understand and to study these algorithms is what we are about to do!
A first classification
Books and theoreticians divide parsing algorithms in two very large groups, at first. I think knowing such a definition is extremely useful: imagine yourself talking with a colleague about some piece of code. Then, you both can use this common language to understand what each is saying to the other.
This first classification is based on how the algorithm builds the parse tree in the internal memory.
First of all, let me repeat the concept: parsers build a so-called parse tree, which is a tree-like data structure whose leaves are the terminal tokens of the grammar, and the intermediate nodes in the tree are nonterminal tokens. Why a tree? This is a very good question, but let me skip it for a minute, and take it back later. Just assume we really want to have it in a tree-like shape.
If you think about a tree-like data structure, there are two sensible ways to build it. One is from the top (root) to the bottom (leaf), and the other is vice versa.
And indeed, parsing algorithms are classified in first instance as:
- Top-down Parsers,
- Bottom-up Parsers.
What does it mean in practice? Well, remember that parsing algorithms works on the grammar definition. Thus, a top-down parser will assume that the first token it sees in the input string is the start symbol of the grammar. Then, it will derive all the other tokens as children of the start symbol.
Bottom-up parsers follow the inverse logic. They will assume the first symbol seen in the input string is a leaf of the tree, and will start building the tree by deciding what is the parent node of that leaf, and so on until they arrive at the root of the tree.
This very simple classification is actually extremely important. In fact, top-down and bottom-up parsers are not different “just” in the way they build the tree. They can actually “do” different things.
In particular, and this is a very important thing to remember, bottom-up algorithms are more powerful, but also much more complex.
What does “more powerful” mean? It means that they can work with a larger set of grammars.
For example, top-down parsers do not work with left-recursive grammar, whereas bottom-up ones do. Left-recursive grammars are those grammars where a production rule for a nonterminal symbol A starts with the same symbol. For example the production rule
A : Ab
would make a grammar left-recursive, because to “replace” the symbol A
in a string you have to start with another A
(followed by a b
).
We will see in a minute why top-down parsers get into trouble in such cases.
A second classification
The second classification is based on how the algorithm expands the nodes in the parse-tree.
Generally speaking, expanding a node in a tree means to figure out what are its connections (for example, its children if you are building the tree top-down). In a parse tree this means to understand what production rule must be applied to that node. Let me give a concrete example.
Let’s say we are just starting off the parsing procedure, and want to do it with a top-down approach. Therefore, we would have only one node in the tree, the root, with the start symbol of the grammar. Let’s say this symbol is S
.
The grammar is likely to have many production rules for the starting symbol S
, for example
S : aAb | Ac | dB.
So, the first goal of a top-down parser would be to figure out what’s the right production rule that must be used to expand the root node further down in its child. It can have three children, in the form aAb, or two children in either the form Ac
or dB
.
Now, when you expand the root node, the parse tree will have either three or two nodes that must be expanded further. The question is: which one to pick up for expansion?
There are two common approaches:
- Leftmost parsers choose to expand the leftmost node in the tree that is not a terminal token.
- Rightmost parsers expand the rightmost node that is not a terminal token.
The natural question, at this point, is whether different expansions rule can lead to different parse trees, or not.
The answer is in general, yes, there can be two different parse trees for the same input string. However, and this is very important, the same string can have multiple parse trees only if the grammar is ambiguous.
Ambiguity is BAD, and in fact grammars designed for programming languages are unambiguous. That means, each string that is valid in that grammar can have one and only one parse tree. And therefore, we should get the same result no matter if we expand the leftmost or rightmost child.
Backtracking or not, that’s the question
A third classification is based on whether the parsing algorithm uses backtracking or not.
I find that knowing about this distinction is very useful to understand articles and other people’s code.
Backtracking is a general programming techniques that (very informally) says: each time you have to make a decision about what to do in the procedure, save the current state, try one of the choices you have and if it fails then simply start over again by resuming the saved state and making a different decision at that point.
In parsing, decisions are all about what production rule to choose when many of them seem fine. Let’s see a concrete example.
Consider the string a = b + 1
, and assume you have already parsed it correctly until the =
symbol (included). So, the parser must figure out what’s on the right-hand side of this assignment statement.
Your grammar is likely to have production rules about assignments that are similar to the following
assign_stm : ID '=' ID
| ID '=' expr
| ID '=' NUM
Such rule basically says:
an assignment statement can be made in three ways only: an identifier, a =
sign and another identifier; an identifier, a =
sign and a whole expression; an identifier, a =
sign and a number”.
Notice that the above rule can be also written as
assign_stm : ID '=' (ID | exp | NUM).
Thus, when you are parsing the input string and arrive at the =
sign, it’s time to figure out which of the three alternatives is the right one. If you have no clue about it, then the solution is to save the current parse tree, pick one choice among the three at random and keep going trusting this decision. If it turns out it was a wrong decision (because you reach a dead end in the parsing procedure), then you must backtrack: restore the parse tree you saved, and take a different choice.
Backtracking is a very powerful technique, because it guarantees that you will take the right decision, eventually. Or, in the case of a parser, that there was no right decision and therefore the input string has to be rejected (like in a compilation error).
However, as it often happens, powerful techniques are also expensive. And backtracking is very expensive. Therefore, you might want to avoid it in a parser.
The cost of avoiding backtracking is that you can’t assume the parser will be able to handle all types of grammars. In fact, to avoid backtracking the parser needs to have some hint about what decision to take when multiple production rules are available.
These “hints” the parser need are called lookahead. Simply, the parser algorithm is allowed to look a bit further in the input string, and it can decide what production rule to continue on based on the tokens it sees ahead.
Definitions gets a bit more complex now, but let me try to summarize them.
If a parser only needs to look one token ahead to parse the grammar successfully (that is, to parse all possible input strings), then the grammar is said to be LL(1).
- The first L means leftmost derivation (which I explained above).
- The second L means lookahead.
- The integer in the parenthesis is the number of tokens it needs to look ahead. In general, if the parser needs to look k tokens, then the grammar is said to be LL(k).
LL(k) grammars are obviously a (small) subset of all formal grammars you can make. This is what I meant by saying “backtracking is more powerful”:
- With backtracking you can parse a very large set of Grammars, but it will take a long time to execute.
- Without it, you can parse a restricted set of Grammars, but it will be much more efficient.
Recursion or not, that’s the other question
A final distinction that I want to make, because I find it very useful, is more technical and specifically related to the implementation of the parsing algorithm.
In fact, it’s well known that every recursive algorithm can be implemented with a non-recursive procedure, typically using a stack data structure (Last In First Out - LIFO).
Grammars and Programming Languages are intrinsically recursive, because the production rules uses each other. Thus, the most natural implementation of almost every parsing algorithm is via a recursive scheme. However, it’s often convenient to switch to an equivalent iterative procedure (non-recursive), for memory management purposes.
Keeping in mind this fourt distinctions has helped me quite a bit in studying parsers implementation.
Take-home Messages so far
At this point, I believe repeating a few key concepts is beneficial in order to not lose the thread of the subject, before continuing. First, about parsing in general:
- A Parser is a software able to decide whether or not a string respects a Grammar rules, and hence belongs or not to a Language.
- Parsing is the second step in a compilation process, after the Lexical Analysis. In fact, the input of the Parser is the sequence of tokens generated by the Lexical Analyzer.
- To decide whether to accept or reject the string in input, the Parser builds in memory a Parse-Tree, where the leafs are the terminal tokens of the grammar. This parse tree can be seen as the output of the parsing process (and thus the input of the next compilation step).
I’ve also discussed with you the main differences that can exist in a parser:
- The Parser can build the parse tree from the root to the leaves, in which case is said to be a top-down parser, or vice versa, in which case it’s said a bottom-up parser.
- Bottom-up parser are more general than top-down ones, in the sense that they can handle more types of grammars. On the other hand, top-down parsers have a much simpler algorithmic structure, easier to maintain.
- In building the Parse-Tree, the parser can either expand the leftmost nonterminal node in the tree, or the rightmost. Leftmost is definitely the most common approach.
- Useful Grammars have a lot of production rules, many for each symbol. In such a case, the Parser must decide what is the right production rule to apply to expand a nonterminal node. The most general approach to do this is with backtracking, which however is awfully slow. The (more commonly used) alternative is to write a parser that works for LL(k) Grammars, since with a lookahead of k tokens backtracking is not necessary.
- Although Grammars have a strong recursive footprint, Parsers can be implemented either with a recursive algorithm or with an iterative one. The latter often uses a stack data structure to imitate the recursion in an iterative fashion.
I think that makes enough for an overview of parsing algorithms! Next, I am going to dive much deeper into the nuts and bolts of a parser prototype.
References
My article What is a Programming Language Grammar?
Language Implementation Patterns. A book by Prof. Terrence Parr.
The Dragon Book. Compilers: Principles, Techniques and Tools. Wikipedia page (of the book).


Hypercanvas.js
find on
GitHub
crafted by
Jake Bian
DEMO
Functions over curved surfaces
DEMO
Hypercubes
DEMO
Axes & Spheres
DEMO
Functions on cylinder.
DEMO
3D function in 4D curved space
Link
Legacy version, with a physics engine
find on
GitHub
crafted by
Jake Bian
Copyright © 2014


Resort!
Located in the middle of the Bermuda Triangle
Come enjoy the beautiful Bermuda Triangle where your stress and troubles will disappear!


Your metadata record has been submitted to NKN for publication and we have been alerted of your submission. Once we review and approve your record, you will be able to search for it on our data search page. If modifications need to be made before your record can be approved, NKN will contact you.


--- layout: post title: Photos from our (second) Christmas date: 2004-12-17 00:00:00 category: personal ---
Photos from our (second) Christmas meal last night...


--- layout: default title: Notice of 2019 AGM ---
This notice is to provide all members with the notice required by our bylaws of our coming Annual General Meeting. This will take place on Tuesday October 22nd, at the Okotoks Alliance Church, starting at 7:00pm.
Please attend the AGM if you are able to do so; it is an important requirement under the Societies Act of Alberta that we hold this meeting, and has the serious purpose of approving accounts and electing Directors. It is the Directors who run the Society on a day-to-day basis and are accountable to you for their activities. You will hear reports of our activities over the last year and our plans for the future. All members of the Society in good standing are eligible to attend the meeting and vote. If you have yet to pay your $20 Annual Society Fee please do so, this will ensure you are a member in good standing. Our Treasurer will happily accept the fee on 22nd if you are unable to pay before then.
The Draft Agenda for the AGM is attached to this notice.
In accordance with the notice sent out on Friday September 17th, 2019 no further items may be added to the agenda, and nominations to stand as a Director have closed.
The final agenda, minutes of last year’s AGM, and the audited accounts for the year to July 31st, 2019 will be sent to you all with a final reminder about the AGM on October 15th.
Thank you,
Stuart Lloyd
President – Foothills Philharmonic Society


In general, Google "arduino" and keywords you're interested in and you might be surprised at what you find!
Last updated 10 September 2008 Todd Neller


For they are all adulterers,
a company of treacherous men.
3 They bend their tongue like a bow;
falsehood and not truth has grown strong in the land;
for they proceed from evil to evil,
and they do not know me,
declares the LORD.
4 Let everyone beware of his neighbor,
and put no trust in any brother,
for every brother is a deceiver,
and every neighbor goes about as a slanderer.
5 Everyone deceives his neighbor,
and no one speaks the truth;
they have taught their tongue to speak lies;
they weary themselves committing iniquity.
6 Heaping oppression upon oppression, and deceit upon deceit,
they refuse to know me, declares the LORD.
7 Therefore thus says the LORD of hosts:
“Behold, I will refine them and test them,
for what else can I do, because of my people?
8 Their tongue is a deadly arrow;
it speaks deceitfully;
with his mouth each speaks peace to his neighbor,
but in his heart he plans an ambush for him.
9 Shall I not punish them for these things? declares the LORD,
and shall I not avenge myself
on a nation such as this?
10 “I will take up weeping and wailing for the mountains,
and a lamentation for the pastures of the wilderness,
because they are laid waste so that no one passes through,
and the lowing of cattle is not heard;
both the birds of the air and the beasts
have fled and are gone.
11 I will make Jerusalem a heap of ruins,
a lair of jackals,
and I will make the cities of Judah a desolation,
without inhabitant.”
12 Who is the man so wise that he can understand this? To whom has the mouth of the LORD spoken, that he may declare it? Why is the land ruined and laid waste like a wilderness, so that no one passes through?
13 And the LORD says: “Because they have forsaken my law that I set before them, and have not obeyed my voice or walked in accord with it,
14 but have stubbornly followed their own hearts and have gone after the Baals, as their fathers taught them.
15 Therefore thus says the LORD of hosts, the God of Israel: Behold, I will feed this people with bitter food, and give them poisonous water to drink.
16 I will scatter them among the nations whom neither they nor their fathers have known, and I will send the sword after them, until I have consumed them.”
17 Thus says the LORD of hosts:
“Consider, and call for the mourning women to come;
send for the skillful women to come;
18 let them make haste and raise a wailing over us,
that our eyes may run down with tears
and our eyelids flow with water.
19 For a sound of wailing is heard from Zion:
‘How we are ruined!
We are utterly shamed,
because we have left the land,
because they have cast down our dwellings.’ ”
20 Hear, O women, the word of the LORD,
and let your ear receive the word of his mouth;
teach to your daughters a lament,
and each to her neighbor a dirge.
21 For death has come up into our windows;
it has entered our palaces,
cutting off the children from the streets
and the young men from the squares.
22 Speak, “Thus declares the LORD:
‘The dead bodies of men shall fall
like dung upon the open field,
like sheaves after the reaper,
and none shall gather them.’ ”
23 Thus says the LORD: “Let not the wise man boast in his wisdom, let not the mighty man boast in his might, let not the rich man boast in his riches,
24 but let him who boasts boast in this, that he understands and knows me, that I am the LORD who practices steadfast love, justice, and righteousness in the earth. For in these things I delight, declares the LORD.”
25 “Behold, the days are coming, declares the Lord, when I will punish all those who are circumcised merely in the flesh—
26 Egypt, Judah, Edom, the sons of Ammon, Moab, and all who dwell in the desert who cut the corners of their hair, for all these nations are uncircumcised, and all the house of Israel is uncircumcised in heart.”


Calculate angle for current time:
Request angle
Time:
{{clock.time}}
Angle:
{{clock.angle}}
CONTENT 2
Enter time
Compute Angle
History
Request history
ID:
{{clock.id}}
Time:
{{clock.time}}
Angle:
{{clock.angle}}


Evergrande's black swan. Will markets recover? - Weekly analysis
Market overview
Since September began, many markets has been mostly bearish. Last week we have received the Evergrande’s black swan that causes a tremendeous pre-market gap on S&P500 and many indexes on the beginning of this week.
However, many markets has shown recover symptoms at the ending of this week. In fact, if S&P500 does a upside breakout could push whole market on the bullish side.
Let’s see what’s been going on in some markets.
S&P500
S&P500 started the week with a tremendous 30 points gap. Soon after, price went to test $4322-$4333 daily support that was respected. In futures market was seen a nice double test on 4h timeframe to this support:
In the course of the week the price had a nice recover action, ending the week almost testing primary daily resistances on $4435-$4455 points. If S&P500 does a upside breakout to $4500 final daily resistance during the next coming week, price could reach a new ATH pushing whole market on the bullish side.
NASDAQ
NASDAQ had a quick test to $14790 daily support, showing recovering symptoms through the next days. Was important to NASDAQ to defend the $15000 weekly support, which it did in friday close. Now it seems that price will confront $15442 daily resistance. If price does a upside breakout to this daily resistance, NASDAQ could reach a new ATH carrying most of tech stocks.
Bitcoin
Bitcoin has failed to break the $52k weekly resistance. Since then, bears has come to play breaking almost breaking 2 daily supports on $49,1k and $46,8k. For now it seems that is respecting $40,5k daily support. Bitcoin needs to do a upside breakout to $45,5k daily resistance to get some strenght and break $52k weekly resistance. If losses $40,5k daily support is important that price respect $36,5k weekly support to still be bullish.
USOIL
USOIL has broke a weekly resistance on $68,62 per barrel, mostly bullish since then. The market retracement this week only produces in USOIL a quick test on $69,45 per barrel daily support, quickly recovering. There is no important daily resistances left. Is expected that USOIL will go to test $85,6 per barrel monthly resistance.
DXY
This week dollar got a lot of strength. In fact, ended the week almost breaking up (again) the $93,3 weekly resistance. Also has consolidate several days above $92,7 daily resistance. If dollar do a upside breakout to $93,3 weekly resistance in the coming weeks is expected that dollar go to test $97,3 monthly resistance.
What to expect now?
In the short term Evergrande’s black swan should not affect the whole market immediately. The trend is too strong at this moment, in fact many markets have recoveral signs this week. But it’s a thing must get in view in the coming weeks or months, especially because many indexes starts looking now like Dot-com bubble in monthly timeframe.
To put this in perspective, let’s see S&P500 soon after $1552 Dot-com bubble peak:
Let’s see S&P500 now, from Dot-com bubble peak:
Similarties? I think so.
Have a good week!


This cookie policy ("Policy") describes what cookies are and how Website Operator ("Website Operator", "we", "us" or "our") uses them on the noobe.io website and any of its products or services (collectively, "Website" or "Services").
You should read this Policy so you can understand what type of cookies we use, the information we collect using cookies and how that information is used. It also describes the choices available to you regarding accepting or declining the use of cookies.
What are cookies?
Cookies are small pieces of data stored in text files that are saved on your computer or other devices when websites are loaded in a browser. They are widely used to remember you and your preferences, either for a single visit (through a "session cookie") or for multiple repeat visits (using a "persistent cookie").
Session cookies are temporary cookies that are used during the course of your visit to the Website, and they expire when you close the web browser.
Persistent cookies are used to remember your preferences within our Website and remain on your desktop or mobile device even after you close your browser or restart your computer. They ensure a consistent and efficient experience for you while visiting our Website or using our Services.
Cookies may be set by the Website ("first-party cookies"), or by third parties, such as those who serve content or provide advertising or analytics services on the website ("third party cookies"). These third parties can recognize you when you visit our website and also when you visit certain other websites.
What are your cookie options?
If you don't like the idea of cookies or certain types of cookies, you can change your browser's settings to delete cookies that have already been set and to not accept new cookies. To learn more about how to do this or to learn more about cookies, visit internetcookies.org
Changes and amendments
We reserve the right to modify this Policy relating to the Website or Services at any time, effective upon posting of an updated version of this Policy on the Website. When we do we will post a notification on the main page of our Website. Continued use of the Website after any such changes shall constitute your consent to such changes. Policy was created with WebsitePolicies.
Acceptance of this policy
You acknowledge that you have read this Policy and agree to all its terms and conditions. By using the Website or its Services you agree to be bound by this Policy. If you do not agree to abide by the terms of this Policy, you are not authorized to use or access the Website and its Services.
Contacting us
If you would like to contact us to understand more about this Policy or wish to contact us concerning any matter relating to our use of cookies, you may send an email to<EMAIL_ADDRESS>This document was last updated on January 18, 2020


{% from 'macros.html' import include_src %}
{% extends "base.html" %}
{% block title %}mpld3Drag{% endblock %}
{% block content %}
{% filter markdown %}
# mpld3Drag
Testing custom plugins for mpld3. The plot is created with `matplotlib` and
rendered in `d3.js` using `mpld3`. This is based on
[http://mpld3.github.io/examples/heart_path.html](http://mpld3.github.io/examples/heart_path.html).
The only difference is that the JavaScript code is moved from the string in
the Python plugin class directly into the `
{% endblock %}


A possible chance to meet the love of your life? Or just a fun different way to meet new people.
Speed dating involves a lot of mini dates with a lot of other single people. A date lasts 3-4 minutes and when it's over you will switch your date partner. By the end of the night you will have had 8-12 mini dates. If you like someone, just note it down on your scorecard and if you match with them their contact details will be given to you the following day.
Even if you're not really looking for someone to date, it's a great evening out idea that you can do with a friend and make new friends.
The events will be held at Sir Toby's Hostel. The Garden is very suited to a speed dating event, and a pleasant location. There are individual 2 person tables to make it very date-like appropriate. If there are weather issues, or it starts getting dark too early in the evening, the event can be held in the downstairs area and bar area.
The bar will be open during the event, and will be a place to hang out before, inbetween and after the event. If you come on your own you can settle your nerves by taking a drink and chat to the other people who you won't be dating.
In order to set up these events, it is important to have participants who are compatible with each other. We would like you to fill the form out below and we will contact you by email when there is an event that you might like to join.


In this project, you'll define and train a DCGAN on a dataset of faces. Your goal is to get a generator network to generate new images of faces that look as realistic as possible!
The project will be broken down into a series of tasks from loading in data to defining and training adversarial networks.
You'll be using the CelebFaces Attributes Dataset (CelebA) to train your adversarial networks.
This dataset is more complex than the number datasets (like MNIST or SVHN) you've been working with, and so, you should prepare to define deeper networks and train them for a longer time to get good results. It is suggested that you utilize a GPU for training.
Since the project's main focus is on building the GANs, we've done some of the pre-processing for you. Each of the CelebA images has been cropped to remove parts of the image that don't include a face, then resized down to 64x64x3 NumPy images. Some sample data is show below.
If you are working locally, you can download this data by clicking here
This is a zip file that you'll need to extract in the home directory of this notebook for further loading and processing. After extracting the data, you should be left with a directory of data processed_celeba_small/
# can comment out after executing
#!unzip processed_celeba_small.zip
data_dir = 'processed_celeba_small/'
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import pickle as pkl
import matplotlib.pyplot as plt
import numpy as np
import problem_unittests as tests
#import helper
%matplotlib inline
The CelebA dataset contains over 200,000 celebrity images with annotations. Since you're going to be generating faces, you won't need the annotations, you'll only need the images. Note that these are color images with 3 color channels (RGB)#RGB_Images) each.
Since the project's main focus is on building the GANs, we've done some of the pre-processing for you. Each of the CelebA images has been cropped to remove parts of the image that don't include a face, then resized down to 64x64x3 NumPy images. This pre-processed dataset is a smaller subset of the very large CelebA data.
There are a few other steps that you'll need to transform this data and create a DataLoader.
get_dataloader
function, such that it satisfies these requirements:¶image_size x image_size
in the x and y dimension.To create a dataset given a directory of images, it's recommended that you use PyTorch's ImageFolder wrapper, with a root directory processed_celeba_small/
and data transformation passed in.
# necessary imports
import torch
from torchvision import datasets
from torchvision import transforms
def get_dataloader(batch_size, image_size, data_dir='processed_celeba_small/'):
"""
Batch the neural network data using DataLoader
:param batch_size: The size of each batch; the number of images in a batch
:param img_size: The square size of the image data (x, y)
:param data_dir: Directory where image data is located
:return: DataLoader with batched data
"""
# TODO: Implement function and return a dataloader
# resize and normalize the images
transform = transforms.Compose([transforms.Resize(image_size), # resize to 28x28
transforms.ToTensor()])
# define datasets using ImageFolder
dataset = datasets.ImageFolder(data_dir, transform)
# create and return DataLoaders
celeba_loader = torch.utils.data.DataLoader(dataset=dataset, batch_size=batch_size, shuffle=True)
return celeba_loader
celeba_train_loader
with appropriate hyperparameters.¶Call the above function and create a dataloader to view images.
batch_size
parameterimage_size
must be 32
. Resizing the data to a smaller size will make for faster training, while still creating convincing images of faces!#  You should seen square images of somewhat-centered faces.
Note: You'll need to convert the Tensor images into a NumPy type and transpose the dimensions to correctly display an image, suggested imshow
code is below, but it may not be perfect.
# helper display function
def imshow(img):
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
# obtain one batch of training images
dataiter = iter(celeba_train_loader)
images, _ = dataiter.next() # _ for no labels
# plot the images in the batch, along with the corresponding labels
fig = plt.figure(figsize=(20, 4))
plot_size = 20
for idx in np.arange(plot_size):
ax = fig.add_subplot(2, plot_size/2, idx+1, xticks=[], yticks=[])
imshow(images[idx])
You need to do a bit of pre-processing; you know that the output of a tanh
activated generator will contain pixel values in a range from -1 to 1, and so, we need to rescale our training images to a range of -1 to 1. (Right now, they are in a range from 0-1.)
# TODO: Complete the scale function
def scale(x, feature_range=(-1, 1)):
''' Scale takes in an image x and returns that image, scaled
with a feature_range of pixel values from -1 to 1.
This function assumes that the input x is already scaled from 0-1.'''
# assume x is scaled to (0, 1)
# scale to feature_range and return scaled x
min = feature_range[0]
max = feature_range[1]
x = x * (max - min) + min
return x
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
# check scaled range
# should be close to -1 to 1
img = images[0]
scaled_img = scale(img)
print('Min: ', scaled_img.min())
print('Max: ', scaled_img.max())
A GAN is comprised of two adversarial networks, a discriminator and a generator.
Your first task will be to define the discriminator. This is a convolutional classifier like you've built before, only without any maxpooling layers. To deal with this complex data, it's suggested you use a deep network with normalization. You are also allowed to create any helper functions that may be useful.
import torch.nn as nn
import torch.nn.functional as F
# helper conv function - from cycleGAN Exercies
def conv(in_channels, out_channels, kernel_size, stride=2, padding=1, batch_norm=True):
"""Creates a convolutional layer, with optional batch normalization.
"""
layers = []
conv_layer = nn.Conv2d(in_channels=in_channels, out_channels=out_channels,
kernel_size=kernel_size, stride=stride, padding=padding, bias=False)
layers.append(conv_layer)
# add batch norm layer if specified
if batch_norm:
layers.append(nn.BatchNorm2d(out_channels))
return nn.Sequential(*layers)
class Discriminator(nn.Module):
def __init__(self, conv_dim=32):
"""
Initialize the Discriminator Module
:param conv_dim: The depth of the first convolutional layer
"""
super(Discriminator, self).__init__()
self.conv_dim = conv_dim
# complete init function
# Convolutional layers, increasing in depth
# first layer has *no* batchnorm
self.conv1 = conv(3, conv_dim, 4, batch_norm=False) # out: 16
self.conv2 = conv(conv_dim, conv_dim*2, 4) # out: 8
self.conv3 = conv(conv_dim*2, conv_dim*4, 4) # out: 4
# final, fully-connected layer
self.fc = nn.Linear(conv_dim*4 * 4 * 4, 1)
def forward(self, x):
"""
Forward propagation of the neural network
:param x: The input to the neural network
:return: Discriminator logits; the output of the neural network
"""
# define feedforward behavior
# leaky relu applied to all conv layers but last
out = F.leaky_relu(self.conv1(x))
out = F.leaky_relu(self.conv2(out))
out = F.leaky_relu(self.conv3(out))
# flatten
out = out.view(-1, self.conv_dim*4 * 4 * 4)
# final fully connected layer
out = self.fc(out)
return out
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_discriminator(Discriminator)
The generator should upsample an input and generate a new image of the same size as our training data 32x32x3
. This should be mostly transpose convolutional layers with normalization applied to the outputs.
z_size
32x32x3
# helper deconv function - from DCGAN Exerices
def deconv(in_channels, out_channels, kernel_size, stride=2, padding=1, batch_norm=True):
"""Creates a transposed-convolutional layer, with optional batch normalization.
"""
# create a sequence of transpose + optional batch norm layers
layers = []
transpose_conv_layer = nn.ConvTranspose2d(in_channels, out_channels,
kernel_size, stride, padding, bias=False)
# append transpose convolutional layer
layers.append(transpose_conv_layer)
if batch_norm:
# append batchnorm layer
layers.append(nn.BatchNorm2d(out_channels))
return nn.Sequential(*layers)
class Generator(nn.Module):
def __init__(self, z_size, conv_dim):
"""
Initialize the Generator Module
:param z_size: The length of the input latent vector, z
:param conv_dim: The depth of the inputs to the *last* transpose convolutional layer
"""
super(Generator, self).__init__()
# complete init function
self.z_size = z_size
self.conv_dim = conv_dim
# setup fully connected layer
self.fc = nn.Linear(self.z_size, 4 * 4 * self.conv_dim*4)
# setup transpose conv layers (deconvolutional layers)
self.t_conv1 = deconv(conv_dim*4, conv_dim*2, 4)
self.t_conv2 = deconv(conv_dim*2, conv_dim, 4)
self.t_conv3 = deconv(conv_dim, 3, 4, batch_norm=False)
def forward(self, x):
"""
Forward propagation of the neural network
:param x: The input to the neural network
:return: A 32x32x3 Tensor image as output
"""
# define feedforward behavior
# fully-connected + reshape
out = self.fc(x)
out = out.view(-1, self.conv_dim*4, 4, 4) # (batch_size, depth, 4, 4)
# hidden transpose conv layers + relu
out = F.relu(self.t_conv1(out))
out = F.relu(self.t_conv2(out))
# last layer + tanh activation
out = self.t_conv3(out)
out = F.tanh(out)
return out
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_generator(Generator)
To help your models converge, you should initialize the weights of the convolutional and linear layers in your model. From reading the original DCGAN paper, they say:
All weights were initialized from a zero-centered Normal distribution with standard deviation 0.02.
So, your next task will be to define a weight initialization function that does just this!
You can refer back to the lesson on weight initialization or even consult existing model code, such as that from the networks.py
file in CycleGAN Github repository to help you complete this function.
def weights_init_normal(m):
"""
Applies initial weights to certain layers in a model .
The weights are taken from a normal distribution
with mean = 0, std dev = 0.02.
:param m: A module or layer in a network
"""
# classname will be something like:
# `Conv`, `BatchNorm2d`, `Linear`, etc.
classname = m.__class__.__name__
# TODO: Apply initial weights to convolutional and linear layers
if classname.find('Conv') != -1:
m.weight.data.normal_(0, 0.02)
if classname.find('Linear') != -1:
m.weight.data.normal_(0, 0.02)
Define your models' hyperparameters and instantiate the discriminator and generator from the classes defined above. Make sure you've passed in the correct input arguments.
 Here, we'll set this as a boolean variable train_on_gpu
. Later, you'll be responsible for making sure that
- Models,
- Model inputs, and
- Loss function arguments
Are moved to GPU, where appropriate.
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import torch
# Check for a GPU
train_on_gpu = torch.cuda.is_available()
if not train_on_gpu:
print('No GPU found. Please use a GPU to train your neural network.')
else:
print('Training on GPU!')
Now we need to calculate the losses for both types of adversarial networks.
- For the discriminator, the total loss is the sum of the losses for real and fake images,
d_loss = d_real_loss + d_fake_loss
.- Remember that we want the discriminator to output 1 for real images and 0 for fake images, so we need to set up the losses to reflect that.
The generator loss will look similar only with flipped labels. The generator's goal is to get the discriminator to think its generated images are real.
You may choose to use either cross entropy or a least squares error loss to complete the following real_loss
and fake_loss
functions.
def real_loss(D_out, smooth=False):
'''Calculates how close discriminator outputs are to being real.
param, D_out: discriminator logits
return: real loss'''
batch_size = D_out.size(0)
# label smoothing
if smooth:
# smooth, real labels = 0.9
labels = torch.ones(batch_size)*0.9
else:
labels = torch.ones(batch_size) # real labels = 1
# move labels to GPU if available
if train_on_gpu:
labels = labels.cuda()
# binary cross entropy with logits loss
criterion = nn.BCEWithLogitsLoss()
# calculate loss
loss = criterion(D_out.squeeze(), labels)
return loss
def fake_loss(D_out):
'''Calculates how close discriminator outputs are to being fake.
param, D_out: discriminator logits
return: fake loss'''
batch_size = D_out.size(0)
labels = torch.zeros(batch_size) # fake labels = 0
if train_on_gpu:
labels = labels.cuda()
criterion = nn.BCEWithLogitsLoss()
# calculate loss
loss = criterion(D_out.squeeze(), labels)
return loss
import torch.optim as optim
# params
lr = 0.00018 # 0.0005 too high, 0.0002 nominal
beta1 = 0.5
beta2 = 0.999 # default value
# Create optimizers for the discriminator and generator
d_optimizer = optim.Adam(D.parameters(), lr, [beta1, beta2])
g_optimizer = optim.Adam(G.parameters(), lr, [beta1, beta2])
Training will involve alternating between training the discriminator and the generator. You'll use your functions real_loss
and fake_loss
to help you calculate the discriminator losses.
You've been given some code to print out some loss statistics and save some generated "fake" samples.
Keep in mind that, if you've moved your models to GPU, you'll also have to move any model inputs to GPU.
def train(D, G, n_epochs, print_every=50):
'''Trains adversarial networks for some number of epochs
param, D: the discriminator network
param, G: the generator network
param, n_epochs: number of epochs to train for
param, print_every: when to print and record the models' losses
return: D and G losses'''
# move models to GPU
if train_on_gpu:
D.cuda()
G.cuda()
# keep track of loss and generated, "fake" samples
samples = []
losses = []
# Get some fixed data for sampling. These are images that are held
# constant throughout training, and allow us to inspect the model's performance
sample_size=16
fixed_z = np.random.uniform(-1, 1, size=(sample_size, z_size))
fixed_z = torch.from_numpy(fixed_z).float()
# move z to GPU if available
if train_on_gpu:
fixed_z = fixed_z.cuda()
# epoch training loop
for epoch in range(n_epochs):
# batch training loop
for batch_i, (real_images, _) in enumerate(celeba_train_loader):
batch_size = real_images.size(0)
real_images = scale(real_images)
d_optimizer.zero_grad()
# ===============================================
# YOUR CODE HERE: TRAIN THE NETWORKS
# ===============================================
# 1. Train the discriminator on real and fake images
if train_on_gpu:
real_images = real_images.cuda()
# train with real images
D_real = D(real_images)
d_real_loss = real_loss(D_real, True)
# train with fake images
z = np.random.uniform(-1, 1, size=(batch_size, z_size))
z = torch.from_numpy(z).float()
# move x to GPU, if available
if train_on_gpu:
z = z.cuda()
fake_images = G(z)
# Compute the discriminator losses on fake images
D_fake = D(fake_images)
d_fake_loss = fake_loss(D_fake)
# add up loss and perform backprop
d_loss = d_real_loss + d_fake_loss
d_loss.backward()
d_optimizer.step()
# 2. Train the generator with an adversarial loss
g_optimizer.zero_grad()
z = np.random.uniform(-1, 1, size=(batch_size, z_size))
z = torch.from_numpy(z).float()
# move x to GPU, if available
if train_on_gpu:
z = z.cuda()
fake_images = G(z)
D_fake = D(fake_images)
g_loss = real_loss(D_fake) # use real loss to flip labels
# perform backprop
g_loss.backward()
g_optimizer.step()
# ===============================================
# END OF YOUR CODE
# ===============================================
# Print some loss stats
if batch_i % print_every == 0:
# append discriminator loss and generator loss
losses.append((d_loss.item(), g_loss.item()))
# print discriminator and generator loss
print('Epoch [{:5d}/{:5d}] | d_loss: {:6.4f} | g_loss: {:6.4f}'.format(
epoch+1, n_epochs, d_loss.item(), g_loss.item()))
## AFTER EACH EPOCH##
# this code assumes your generator is named G, feel free to change the name
# generate and save sample, fake images
G.eval() # for generating samples
samples_z = G(fixed_z)
samples.append(samples_z)
G.train() # back to training mode
# Save training generator samples
with open('train_samples_1.pkl', 'wb') as f:
pkl.dump(samples, f)
# finally return losses
return losses
Set your number of training epochs and train your GAN!
# set number of epochs
n_epochs = 30
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
# call training function
losses = train(D, G, n_epochs=n_epochs)
Plot the training losses for the generator and discriminator, recorded after each epoch.
fig, ax = plt.subplots()
losses = np.array(losses)
plt.plot(losses.T[0], label='Discriminator', alpha=0.5)
plt.plot(losses.T[1], label='Generator', alpha=0.5)
plt.title("Training Losses")
plt.legend()
View samples of images from the generator, and answer a question about the strengths and weaknesses of your trained models.
# helper function for viewing a list of passed in sample images
def view_samples(epoch, samples):
fig, axes = plt.subplots(figsize=(16,4), nrows=2, ncols=8, sharey=True, sharex=True)
for ax, img in zip(axes.flatten(), samples[epoch]):
img = img.detach().cpu().numpy()
img = np.transpose(img, (1, 2, 0))
img = ((img + 1)*255 / (2)).astype(np.uint8)
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
im = ax.imshow(img.reshape((32,32,3)))
# train_samples.pkl #0.00022
# train_samples_1.pkl #0.00018
# Load samples from generator, taken while training
with open('train_samples_1.pkl', 'rb') as f:
samples = pkl.load(f)
_ = view_samples(-1, samples)
When you answer this question, consider the following factors:
Answer: Most of the faces appear to be realistic. However, some of them have distortions and kind of look like a combination of a couple of faces or blending. I think the generation of faces could be improved with a deeper network and maybe using larger initial images. The network seemed to train well around 0.0002 and didn't around 0.005 or higher.
When submitting this project, make sure to run all the cells before saving the notebook. Save the notebook file as "dlnd_face_generation.ipynb" and save it as a HTML file under "File" -> "Download as". Include the "problem_unittests.py" files in your submission.


Order your Pizza!
Select your pizza size below:
Large 15$
Medium 13$
Small 10$
Pepperoni
Bacon
Sausage
Pineapple
Mushrooms
Olives
u=Unions
Green peppers
Tomatoes
Extra cheese
Get price


Ideating, Designing, and Developing digital technologies that will merge the gap between SCIENCES and HUMANITIES
Find Out MoreMy journey began in 2012 at the University of Connecticut, building my mental and physical strength as a divison I athlete and leader on the men's tennis team. As I progressed, I developed a passion for computer science and digital design, and decided to pursue a degree in digital media strategies for business, as well as web/interactive media design. I now leave my schooling, looking to use my training as a means to fight against crime and corruption.
View Resume View BlogAlways ideating solutions to world problems.
Applying design-thinking to influence the masses.
Managing and inspiring people to make a change.
Learning to implement my ideas into reality.
Let's put our powers together and save the world. Give me a call or send me an email and I will get back to you as soon as possible!
203-605-6474


Natural Nipple Cream For Breastfeeding
Good morning world!
We’ve been in this hotel for 21 days now and with today being our last day, I realized our lives have been one big countdown lately.
1 day till we kiss this hotel goodbye forever (hotel tour)
2 days till we get our first shipment of our stuff in
1 week till I get my international drivers license
2 weeks till Caleb starts school
1 month till we get our car back
…and who knows when I go back to school and start teaching yoga again.
To say that I’m excited is an understatement. I can’t wait to make new memories in our little German home and I’m so excited to get started on decorating! I already have a whole shopping list planned out for Ikea and other stores here, haha. Sorry, hubs 😉
I’m also glad to have escaped the pesky bees at our hotel fairly unscathed. I didn’t mention it before, but we had a yellow jacket hive right outside of our window and since the Germans don’t use AC’s, we’ve had to keep our windows open 24/7. As a result, we’ve dealt with a number of bees buzzing around our faces our entire stay at the hotel, one morning I even woke up to 4 stings on my foot and poor Caleb got stung on his nose. Thank God we’re not allergic!
ANYWAY. Here’s a recipe I’ve been wanting to share for awhile. I know I have a few expectant moms reading and this literally saved my raw nipples when I first started my nursing adventure with Amelia. Remember how I mentioned she was tongue tied? Yeah. That was no fun but thanks to my stubbornness and a little bit of this slathered on my ta-ta’s every morning, we survived and now at 8 weeks later we’re still going strong with breastfeeding.
Obviously, you can go out and buy a $10.00 bottle of lanolin and that works just as well too. But I had these ingredients lying around, we were car-less since we had shipped our car overseas at the point, and I wanted to save money. So why not? Plus, it’s always fun to make my own products, like my favorite grapefruit scrub.
So here’s a homemade natural postpartum nipple cream for ya. <pretty sure I’ll get an influx of spammers for that. Isn’t it so nice of me to sacrifice a little bit of my blogging sanity for you guys? 😉
Nipple Cream Recipe
2 tbs Jojoba oil or cocoa butter – helps retain moisture
2 tbs Coconut oil – promotes healthy skin regeneration, moisturizes, and fights off thrush and infection
1 tsp Olive oil (not pictured) – acts as a moisturizer and is chock full of vitamins A and E
Pour all of your ingredients into a measuring cup, then melt for one minute. Mix everything together and then pour into your container of choice. I reused my old bottle of Earth Mama’s Angel Butter (which I loved) from my nursing days with Caleb. You can also get by with just coconut oil but again, I loved making my own.
So that’s it! Super easy and cheap. It’s also deliciously edible but I wiped off residue before nursing just to ensure there’s no harm done to my adorable little nipple nibbler, and so that I’m not slathering oil all over her face, haha.
Happy breastfeeding hot mommas! Wish us luck on our moving adventures 🙂
« Hello from Germany!


--- layout: default title: Images page-header: headline: "Images" alignment: left parent: label: "Content" url: "/content" page-navigation: - label: "Responsive Images" link: "#image-responsive" navigation: - label: "Fill Image" link: "#image-responsive-fill" - label: "Fluid Image" link: "#image-responsive-fluid" - label: "Image Shapes" link: "#image-shape" ---
Use one of the built-in CNVS classes to support responsive behavior for your images.
Images, denoted by the all-enduring <img>
tag, have been a starter in the markup playbook since the early days of the internet. However, they offer very little in form of responsive sizing or styling. CNVS attempts to solve this.


Cookbook/UsingKdb
Using kdb+
In this document, the terms 'tuple', 'row', and 'record' are used interchangeably. And similarly for 'column' and 'field'.
How do kdb+ tables differ from SQL relations ?
Relations in SQL are sets. That is, there are no duplicate rows and rows are not ordered. It is possible to define a cursor on a result set and then manipulate the cursor rows in order, but that can't be done in ANSI SQL. kdb+ tables are ordered and may contain duplicates. The order allows a class of very useful aggregates that are unavailable to the relational database programmer without the cumbersome and poorly performing temporal extensions. For instance, there is the concept of the first row and last row of kdb+ table. The functions first and last give open and close prices in financial calculations. For instance, in q you can write
q)first trade
and
q)last trade
where trade is a kdb+ table.
How do I create a table?
Following the SQL convention, tables are created by naming the items and initializing the items as empty lists. For example, the following expression creates a table with four columns (stock, price, amount and time), and assigns it to trade.
q)trade:([] stock:(); price:(); amount:(); time:())
Each of the table columns is defined to be an empty list, denoted as the parentheses pair () in kdb+.
In this table, the datatype of the columns is not defined. The first record that is inserted into the table determines the datatype of each column. Subsequents inserts may only insert values of this type, or else a type error is raised.
This creates a table in memory. You can read here how to store tables on disk.
Tables can also be created functionally with q primitive functions. Details are available in the Kdb+ Database and Language Primer.
Can I define the type of the columns when I create a table?
Yes. A type descriptor can be specified for each column:
q)trade:([] stock:`symbol$(); price:`float$(); amount:`int$(); time:`time$())
Types are discussed in more detail in the [/trac/browser/kx/kdb+/d/a/q1.htm?format=raw Q language reference manual].
Can I give the column values when creating a table?
Yes, you can give values to initialize the items. By default, item names are taken from corresponding noun names.
q)stock:`ibm`bac`usb q)price:121.3 5.76 8.19 q)amount:1000 500 800 q)time:09:03:06.000 09:03:23.000 09:04:01.000 q)trade:([]stock;price;amt:amount;time) q)trade stock price amt time ----------------------------- ibm 121.3 1000 09:03:06.000 bac 5.76 500 09:03:23.000 usb 8.19 800 09:04:01.000
How do I define a table with a primary key field?
Just write the field definition inside the square brackets. For instance, this is a simple table of financial markets and their addresses (such as the NYSE, the LSE, etc).
q)market:([name:`symbol$()] address:())
Can the primary key consist of more than one field?
Yes. For instance, if market names are not unique, the country name can be part of the primary key.
q)market:([name:`symbol$(); country:`symbol$()] address:())
An alternative to using multiple columns as a primary key is to add to the table a column of unique values (e.g. integers).
Can I specify foreign keys for a table?
Yes.
Foreign keys in SQL provide referential integrity. Namely, an attempt to insert a foreign key value that is not in the primary key will fail. This is also true in q.
Imagine that we want to record in our trades table the market (NYSE, LSE, etc) where each trade has been done.
The primary key of the markets table is a foreign key in the trades table.
q)trade:([] stock:`symbol$(); market:`market$(); price:`float$(); amount:`int$(); time:`time$())
How do I insert a record into a table?
q)`trade insert (`ibm; 122.5; 500; 09:04:59:000)
An alternative syntax for insertions is
q)insert [`trade](`ibm; 122.5; 500; 09:04:59:000)
and
q)insert [`trade; (`ibm; 122.5; 500; 09:04:59:000)]
Can I insert multiple records into a table?
Yes. This is called a bulk insert. The second argument to insert in the previous question is a q list. It can also be a table having the same column names as the first argument. For instance:
q)`trade insert trade
What is an upsert?
q)`trade upsert (`ibm; 122.5; 50; 09:04:59:000)
If the table is not keyed, the above is equivalent to an insert. For a keyed table, it's an update if the key exists in the table and an insert otherwise.
An alternative syntax for upsert is to use the operator ,:
q)trade ,: (`ibm; 122.5; 50; 09:04:59:000)
In the second alternative the table name (trade) is not preceded by a backtick.
upsert can also take a table as an argument.
trade ,: trade
Can a column contain non-scalar values?
Yes.
q)table:([stock:()] price:()) q)insert[`table; (`intel; enlist (123.2; 120.4; 131.0))] q)table stock| price -----| --------------- intel| 123.2 120.4 131
Notice the use of enlist.
How do I find out how many rows are in a table?
Use the function count.
q)count trade
How can access the ith row in a table?
This is complex in SQL, but easy in q. The keyword i represents the row index, which can be used in queries.
q)select from trade where i=17 stock price amount time --------------------------------------- ibm 122.5 50 09:04:59.000
An alternative is to use indexing.
q)trade[17] stock | `ibm price | 122.5 amount| 500 time | 09:04:59.000
The result of the first expression (using select) is a table with a single row, while the result of indexing on a table is a dictionary.
Indexing cannot be used on a keyed table, as the following example demonstrates.
q)tab: ([stock:()] price:()) q)insert[`tab; (`ibm; 109.5)] ,0 q)tab stock| price -----| ----- ibm | 109.5 q)tab[0] 'type
It's also easy to access, say, the second to last row.
q)trade[(count trade) - 2]
Indexing at depth can be used to read a column within a specific row
q)trade[17; `stock]
This is useful for updates too:
q)trade[17; `amount] : 15
When accessing the ith row in a table, what happens if the index is invalid?
If we use select, the result in a table with no rows.
q)select from trade where i = 300000 stock price amount time ---------------------------------------
If we use indexing, the result is a dictionary containing null values.
q)trade 300000 stock | ` market| `market$` price | 0n amount| 0N time | 0Nt
How can I access the first/last n rows in a table?
One way is to use the take operator (#). For instance,
q)3#trade stock market price amount time --------------------------------------- ibm nyse 122.5 50 09:04:59.000 ...
gives the first 3 rows, and
q)-3#trade stock market price amount time --------------------------------------- intel lse 130.3029 45 09:34:29.000 0 ...
gives the last 3 rows.
Note that the take operator treats a list as circular if the number of elements to take is longer than the list:
q)7#2 3 5 2 3 5 2 3 5 2
An alternative is to use sublist. This takes only as many rows as are available. For instance:
q)count trade 10 q)count 3 sublist trade 3 q)count 30 sublist trade 10
How do I get the rows in a table as a set (no duplicates)?
Use the function distinct.
q)distinct trade
And the following gives the number of distinct rows
q)count distinct trade
What is the syntax of select in kdb+?
select expressions have the following general form.
select [columns] [by columns] from table [where conditions]
The result of a select expression is a table. For instance:
q)select stock, amount from trade stock amount ------------ ibm 500 ...
In their simplest form, select expressions extract subtables. However, it is also possible for them to compute new columns or rename existing ones.
q)select stock,newamount:amount+10 from trade where price>100 stock newamount --------------- ibm 510 ...
How do I aggregate column values?
In SQL:
select stock, sum(amount) as total from trade group by stock
In q:
q)select total:sum amount by stock from trade stock| total -----| ----- ibm | 1550 intel| 75
The column stock is a key in the result table.
How can I add a column with the row number to a table?
The keyword i represents the row index.
q)select rowno:i, stock from trade rowno stock ----------- 0 intel 1 ibm 2 ibm ...
How do I delete rows from a table?
q)trade: delete from trade where stock=`ibm
delete returns a table, but does not modify the trade table in place. The assigment accomplishes that. An alternative that updates the table in place is the following:
q)delete from `trade where stock=`ibm
How do I update values in a table?
In SQL:
update trade set amount=42+amount where stock='ibm'
In kdb+:
q)trade: update amount:42+amount from trade where stock=`ibm
update returns a table, but does not modify the underlying table. The assigment accomplishes that.
Or more simply:
q)update amount+42 from `trade where stock=`ibm
update modifies the table in place like delete deletes in place if a symbol is given as tablename. Also note the default column names, for further information see http://kx.com/q/d/a/kdb+.htm.
How do I replace null values by something else?
Use the fill operator (^). For instance, the following replaces all nulls in column 'amount' by zeroes.
q)trade.amount: 0^trade.amount
What are parameterized queries?
Select, update and delete expressions can be evaluated in defined functions. For instance:
q)myquery:{[tbl; amt] select stock, time from tbl where amount > amt} q)myquery[trade; 100] stock time ------------------ ibm 09:04:59.000 ...
Column names cannot be parameters of a query.
Does kdb+ use stored procedures?
Any user-defined function (of the right type) can be used in a query. For instance:
q)f:{[x] x+42} q)select stock, f amount from trade stock amount ------------ ibm 542 ...
Can I write a query using SQL syntax against q tables?
Yes. kdb+ implements a translation layer from SQL to q. The syntax is to prepend s) to the SQL query. For instance:
q)s)select * from trade
Only a subset of SQL is supported.
How do I write a table to disk?
q)`:filename set trade
Or alternatively
q)save `:trade
You can also specify a directory:
q)`:../filename set trade
How do I read a table from disk?
q)trade: get `:filename
Or alternatively,
q)trade: value `:filename
How do I export a table to a CSV file?
q)save `:trade.csv
How do I import a CSV file into a table?
Assume a file data.csv with columns of type int, string and int.
a,b,c 0,hea,481 10,dfi,579 20,oil,77
Then, the following expression does the trick:
q)table: ("ISI"; enlist ",") 0:`data.csv q)table a b c ----------- 0 hea 481 10 dfi 579 20 oil 77
What if the CSV file contains data but no column names?
For instance:
0,hea,481 10,dfi,579 20,oil,77
We can read the columns like this:
q)Cols: ("ISI";",") 0:`data.csv q)Cols 0 10 20 hea dfi oil 481 579 77
And we can create the table by first creating a dictionary and flipping it:
q)table: flip `a`b`c!Cols
How do I export a table to a text file?
q)save `:trade.txt
How do I access a table from an MDB file via ODBC?
From windows, load odbc.k into your kdb+ session, and then load the MDB file.
q w32/odbc.k q)h: .odbc.load `mydb.mdb
This loads the entire database, which may consist of several tables. Use .odbc.tables to list the tables.
q).odbc.tables h `aa`bb`cc`dd`ii`nn
Use .odbc.eval to evaluate SQL commands via ODBC.
q).odbc.eval[h;"select * from aa"]


The cowboy_handler
middleware executes the handler passed through the environment values handler
and handler_opts
, and adds the result of this execution to the environment as the value result
, indicating that the request has been handled and received a response.
Environment input:
Environment output:
None.
None.


I am currently developing a novel CNV calling pipeline, currently in testing. Preliminary data (see figures below) suggest that the pipeline is working well and we have identified a ~10 MB deletion on chromosome 6 segregating in a wild population of maize (otherwise known as teosinte). Furthermore we note that estimates of Tajima's D over regions where CNV segregate differ from the background “genome-wide” level.
Previous work has examined gene loss following ancient whole genome duplication (WGD; sometimes called polyploidy) in the cotton lineage. I showed that gene loss (sometimes called fractionation) following WGD is ongoing and bias between the duplicate sub-genomes. I further suggested that this process is the result of differing recombination rates between sub-genomes. Read the full story here.
drift<-function(N=20,p=0.5,gen=20,reps=10, w=1) {
#set up a matrix to fill
m<-matrix(nrow = gen, ncol = reps, byrow = T)
#for each rep
for ( j in 1:reps ) {
p1<-p
#for each generation
for ( i in 1:gen) {
A<-rbinom(1,size=2*N,p1)
p1<-A/(2*N)
p1<-p1*w
if ( p1 > 1) {p1=1}
m[i,j]<-p1
}#
}#for
#for each column find if it's fixed or lost
lost<-do.call(pmin, lapply(1:nrow(m), function(i)m[i,]))
fixed<-do.call(pmax, lapply(1:nrow(m), function(i)m[i,]))
lost<-length(lost[lost==0])
fixed<-length(fixed[fixed==1])
xscale<-seq(0,dim(m)[1])
m<-rbind(rep(p,dim(m)[2]),m)
#pl<-qplot(x=xscale,y=m[,1], geom="point")
ave<-rowMeans(m)
pl<-plot(xscale,m[,1], ylim = c(0,1), type = "n", ylab = "Allele frequency",
xlab="generations", main = paste("f(A)=",p ,"; Population size=",N , "; lost=", lost, "; fixed=" , fixed, "; w = ", w), xlim =c(0,dim(m)[1]))+matlines(xscale, m, col = "black", lty = 1, lwd = 0.6)+lines(xscale, ave , col = "red", lwd = 2)
pl<-recordPlot()
#pl<-matlines(xscale, m, col = "black", lty = 1, lwd = 0.6)
#pl<-pl+lines(xscale, ave , col = "red", lwd = 2)
z<-list("m"=m,
"pl"=pl, "ave"=ave,"xscale"=xscale)
return(z)
}#drift
#inputPanel(
sliderInput("N", label = "Number of Individuals:",
min = 1, max = 100000, value = 20, step = 1)
sliderInput("p", label = "Starting frequency:",
min = 1/100000, max = 1, value = 0.5, step = 0.0001)
sliderInput("gen", label = "Number of Generations:",
min = 1, max = 100000, value = 100, step = 1)
sliderInput("reps", label = "Number of replicate populations:",
min = 1, max = 1000, value = 100, step = 1)
sliderInput("w", label = "Fitness of allele:",
min = 0, max = 100, value = 1, step = 0.001)
#input<-sliderInput("bw_adjust", label = "Bandwidth adjustment:",
# min = 0.2, max = 2, value = 1, step = 0.2)
#)
#a simple function to mimic genetic drift.
test<-reactive({
drift(N=as.numeric(input$N),p=as.numeric(input$p),reps=as.numeric(input$reps),
gen=as.numeric(input$gen),w=as.numeric(input$w))
})
renderPlot({
test()
})


Harvey Nathanson, father of MEMS, dies
by Steve BushThe creator if the first MEMS device, Harvey Nathanson, has died.
He built a resonant horizontal wand-like structure while working for Westinghouse in the 1960s.
“Working out of the Westinghouse Research Labs in 1965 he conceived of a microscopic device used as a tuner for microelectronic radios,” according to this obituary by Ralph Schugar Chapel in Pittsburgh. “The invention, known as the resonant-gate transistor, became the first device in the field of MEMS. “In his work developing similar devices, he pioneered a method of mass production that would later become a mainstay of MEMS manufacturing.”
In the 1968 patent (pictured) the rod is biased negatively, allowing it to be electrostatically driven by ac on the central capacitive plate, and also allowing its movement to be sensed through conduction modulation between two n-wells (dotted L-shaped) within the p-type substrate.
Although a circular cross-section resonator is shown in the diagram above, the patent later includes a method for building a ‘diving board’ style resonator using epitaxy, and then etching it free.
Images used above are taken from this Google patents page, and are of US patent 3,413,573 by Harvey Nathanson and Robert Wickstrom. Electronics Weekly will remove them immediately if it has used them inappropriately.


{{if not session.manager:}}{{=T('Below is a partial list of companies represented at the conference, who wished to make their attendance public. The list is sorted by company name.')}}{{else:}}{{=T(' Below is a complete list of companies representede at the conference. Some companies do not wish to make their attendance publie. This list is accessible by managers only.')}}{{pass}}


Computech-Electronics/ NEWS / LATEST NEWS / ASUS UNVEILS A REFRESHED RANGE OF TUF SERIES GAMING LAPTOPS, PRICE STARTS RS 79.000/=
ARTICLE | BY GEORGE SOROS | APRIL 4, 2019 8:34 PM PDT
Asus has expanded its TUF range of gaming laptops with FX505 and FX705 models. The FX505 and FX705 will be available across all channels, both online and offline, at a starting price of Rs 79,990 and Rs 1,24,990 respectively.
At 15.6” and 17.3” respectively, these gaming laptops draw their power from up to Intel Core i7-8750H processors and up to Nvidia GeForce GTX 1060 graphics with up to 144Hz high-refresh rate NanoEdge displays. The company claims that gamers will also appreciate the gigabit Ethernet and gigabit-class Wi-Fi and DTS surround-sound audio experience.
As per the company, both FX505 and FX705 have passed the MIL-810G military-grade tests for endurance. They feature the RGB keyboard in addition to WASD key cap design for intuitive controls. With the Overstroke technology, the keyboard, as per the company, registers keystrokes faster for precise and effortless control.
Asus TUF Desktop – FX10CP
The company also launched the FX10CP desktop, priced at Rs 91,990. It comes with GTX 1060 NVIDIA GPU, i7 Intel processor and isolated air chambers.
The desktop features i7-8700 processor, up to GTX1060 graphics card and up to 32GB DDR4 2666MHz RAM. It comes with a 128GB M.2 SSD primary storage and 1TB 7200RPM HDD secondary storage. The desktop is available in offline channels.
Speaking about the latest product launch, Arnold Su, ROG & PC Head, Asus India, said, “As one of the most trusted global tech brands, Asus has constantly endeavoured to empower its customers with innovative products which operate at the intersection of power and affordability. The launch of the latest TUF Gaming laptops is testimony to this vision. Both FX505 and FX705 have been designed to deliver unmatched performance, durability, and style, and are perfect for gamers who prefer an immersive gaming experience. We are confident that our latest offerings will meet and exceed the expectations of the Indian gaming community and will receive heartening market reception.”


Functional Composition
Functional Composition
-
Function composition refers to the application of one function to the
result of another function, producing a new composite function.
- Powerful method of abstraction
-
lodash
and
underscore
bring more compositional power to JavaScript.
-
Wikipedia.org - Function Composition
Functional Composition in JS


Chris Brown announces high-end garage sale at his Los Angeles home and invites fans
The American rapper is selling his possessions and has advertised the event to his social media followers
by Sara-Aisha Kent, https://www.mirror.co.uk/authors/sara-aisha-kent/Chris Brown is giving his fans a chance to buy his possessions after announcing he is having high-end garage sale.
The Look at Me Now hitmaker, 30, invited his fans to come to his Los Angeles home to purchase from his designer wardrobe on Instagram and Twitter .
He designed a cartoon advert that stated that the event started at 10am on Wednesday and will go on until 7pm.
The post boasted that there will be "significantly marked-down high-end designer items".
He captioned the posts: "DA CRIB ... 2 day event."
Proving it was a well organised affair, aerial shots shared onto his Instagram stories of the event showed a number of marquees set up as stalls in the ground of his mansion.
It comes after Chris has been accused of taking a graphic artist’s work without giving proper credit.
Artist Don Mupasi, 25, called out the singer for allegedly stealing one of his artistic pieces on Instagram and demanded he give him recognition.
Don, from Manchester, said it was a 'bittersweet feeling' to have Brown steal his work.
He said it while it proves that his art is 'pretty decent', it doesn't benefit him when 'people are willing to just grab it'.
The artist took to the Internet to criticise the singer, 31, after he discovered the post on Friday.
The rapper appeared to take the video of a man walking down a road with a starry sunset from Don's page and posted to his own Instagram for his 57.6million followers to watch.
Don posted the video tiled ' ANOMALY ' in September and admitted he was happy for viewers to re-share his visuals as long as they tagged him in the post.
He pointed out his requirements for people using his work in the caption: "Feel free to repost, tag us if you do. HD link in highlights."
It appears that Chris ignored this request and not only removed Don's song choice and replaced it with the Natural Disaster/ Aura song from his Indigo album but also wrote his own caption, posting: "Imagination vibrate wit me".
Don recently spoke to Radio 1 Newsbeat about the incident.
He said: "I want people to know it's me who created it. I think that's fair.
"When he posted it with some hip-hop song over it, it's really not the kind of vibe I wanted for that piece of work. But he just put some weird hip-hop song on it and then made some caption which doesn't really make any sense."
The artist added: "But if he had tagged me and just gave credit I would have been cool with that, and that would have brought a lot more eyes to my actual work."
After attempting and failing to get in touch with the singer and his management, The Manchester artist took to reddit to call out the singer publicly.
Aiming to 'bring some attention to it', Don placed the two videos side and by side and was shocked by the positive response when over 80,000 users supported him.


Computers that send requests to servers to access web pages. The server finds the HTML associated with the web page based on the request and sends it back to the originator. The user’s browser will then interpret the web page and display on the computer. This video explains the interaction.
World Wide Web uses HTML to connect the webpages. HTML is the heart of the web, its text content, markup (how it looks), references to documents (images and videos), and links to other web pages.
Tags are used to create the HTML code. Depending on the tag, you will have opening and/or closing tags, some tags we have used so far in module 0 are bold, emphasis, anchor, and linkable tags consisting both of websites or images.
There are 3 types of Code Language, HTML (Hypertext Markup Language) ,CSS (Cascading Style Sheet), and JS (Java Script). HTML controls the structure of the page while CSS controls the style of the page.
The DOM (Document Object Model) is what they call the tree like structure of the page. Both HTML and CSS both are languages that based on syntax and rules. It contains opening tag, content and closing tag. Each tag has a name (type) such as paragraph, image, or division. Content can be empty text or other element. Documents written in HTML defines the content and structure.
CSS is the language of style in coding. With CSS, you can define the font, color, border, position, etc. You can boxify a design, usually separated by header, body and footer.
There are 3 type of tools used for coding. Scratch Pad, Code Pen, and Sublime. On speed of feedback, Scratchpad is immediate, Code Pen is 2-3 seconds, and Sublime is on page refresh. On ease of sharing Scratchpad is impossible, Code Pen is easy but requires an account, Sublime is difficult. On power and professionalism, Scratch pad is low, Code Pen is very high, and Sublime is the highest. And on the number of languages, Scratchpad has 2 (HTML and CSS), Code pen has 3 (HTML, CSS, and JS), while Sublime does all the languages.
CSS is language to add style to your HTML. One key feature of CSS is inheritance. This the mechanism by which properties are applied to not only to the specified element, but also its descendants. Inheritance allows developers to write less CSS language.
The Box Model is what every programmer should focus on when creating language for CSS. The box model consists of starting from the inside out is the Content, Padding, Border and the Margins.
A good way to start thinking like a programmer is to use these 5 steps to achieve your webpage.
Repeat steps 3 to 5 to achieve the webpage you desire.


An accurate and easy tool for performing trajectory inference on single cells using single-cell RNA sequencing data. In addition, SCORPIUS provides functions for discovering the most important genes with respect to the reconstructed trajectory, as well as nice visualisation tools. Cannoodt et al. (2016) <doi:10.1101/079509>.
| Version: | 1.0.2 |
| Depends: | R (≥ 3.0.0) |
| Imports: | dplyr, dynutils, grDevices, ggplot2 (≥ 2.0), magrittr, MASS, mclust, pbapply, pheatmap, princurve (≥ 2.0.2), purrr, ranger, RColorBrewer, reshape2, splines, stats, tidyr, TSP, utils |
| Suggests: | knitr, rmarkdown, testthat |
| Published: | 2018-06-29 |
| Author: | Robrecht Cannoodt [aut, cre] (rcannood), Wouter Saelens [aut] (zouter) |
| Maintainer: | Robrecht Cannoodt <rcannood at gmail.com> |
| BugReports: | https://github.com/rcannood/SCORPIUS/issues |
| License: | GPL-3 |
| URL: | http://github.com/rcannood/SCORPIUS |
| NeedsCompilation: | no |
| CRAN checks: | SCORPIUS results |
| Reference manual: | SCORPIUS.pdf |
| Vignettes: |
Investigating dendritic cell maturation in dendritic cell progenitors Trajectory inference from simulated data |
| Package source: | SCORPIUS_1.0.2.tar.gz |
| Windows binaries: | r-devel: SCORPIUS_1.0.2.zip, r-release: SCORPIUS_1.0.2.zip, r-oldrel: SCORPIUS_1.0.2.zip |
| OS X binaries: | r-release: SCORPIUS_1.0.2.tgz, r-oldrel: SCORPIUS_1.0.2.tgz |
| Old sources: | SCORPIUS archive |
Please use the canonical form https://CRAN.R-project.org/package=SCORPIUS to link to this page.


Closed Weston-super-Mare doctor's surgery to become nursing home
“This facility is highly needed"
by Stephen SumnerPlans for a nursing home offering 24-hour support to up to 10 adults with mental health issues has been approved in Weston-super-Mare .
North Somerset Council has given the green light to Friend 4 Friend Ltd’s plans for the former site of Clarence Park practice, whose staff and 5,000 patients have relocated to Graham Road.
It will care for residents with stress, anxiety, thought disorders, depression and eating disorders.
Neighbours had expressed concerns they would be disturbed by the 24-hour facility and it would "compromise" the area.
But planning officers said: “The proposal involves an inevitable intensification of the use of the site, due to accommodating a 24-hour facility, as opposed to the time framed operation of the previous doctors’ surgery.
“This facility is highly needed and it will be provided under the 24-hour supervision of experienced nursing staff who will ensure that the operation of the nursing home will not lead to increasing noise disturbance.
“Sufficient levels of privacy will be maintained by the introduction of a two-metre fence and by fitting obscure glazed bottom halves within existing first floor windows.”
The home will be modelled on the Oaklands Nursing Home in Severn Road, which has space for 10 adults aged 18 to 65, and managed by the same team.
The applicants said in their plans: “Oaklands regularly receives requests from North Somerset Council to accept new residents but 'blockages' in the system means that the best Oaklands can offer is to add new residents to a waiting list.
“Inevitably, there will be concerns that this proposal seeks to 'get people with mental health issues out onto the streets of Weston'. This is not the case.”
The facility is primarily aimed at the people of Weston, who must be judged by professionals as able to move in. They will not be dependent on drugs or alcohol and will not have an active police record.
For the latest news in and around Bristol, visit and bookmark Bristol Live's homepage .


Ecom RefArch Shop
Home
Products
Cart
({{cartCount}})
Log In
Favorites
Account
Log Out
Loading…
Some of our services seem to be down right now, so you might see some odd behaviors. We're on it!


| Data Centers | |
|---|---|
| Number of Cores in Meyrin | 146,960 |
| Number of Drives in Meyrin | 83,609 |
| Number of 10G NIC in Meyrin | 8,845 |
| Number of 1G NIC in Meyrin | 22,365 |
| Number of Processors in Meyrin | 24,737 |
| Number of Servers in Meyrin | 13,170 |
| Total Disk Space in Meyrin(TB) | 163,982 |
| Total Memory Capacity in Meyrin(TB) | 597 |


General workers, on the day of the ball, will be assigned to one of these three departments.
Health and safety workers will need to be trained. Applications now open!
| Start | 7:30pm, 11th February 2017 |
| Finish | 3:30am, 12th February 2017 |
| Breaks | A single 1 hour break; or two 30 minute breaks. |
| Pay | £40.00 for under 21s; £48.65 for over 21s |
| Application Deadline | 27th November 2016 (Closed) |
| Start | 7:30pm, 11th February 2017 |
| Finish | 3:30am, 12th February 2017 |
| Breaks | A single 1 hour break; or two 30 minute breaks. |
| Pay | £55.00 |
| Application Deadline | 27th November 2016 (Closed) |
Area supervisors will be responsible for all the general workers in a certain area of the ball. Supervisors have a significant amount of responsibility and thus have a higher amount of pay. Some key jobs include: ensuring workers are doing their assigned jobs and that they take their breaks at the right time, making sure that workers are not consuming alcohol and reporting to the personnel or member of the committee if there any issues. Applications now open!


The display preferences are located at Tools -> Options -> CONSTELLATION.
The default display mode that new graphs open in.
3D mode allows graphs to be rotated around the x, y, and z axes. 2D mode only allows rotation around the z axis.
2D mode does not change graphs that have non-zero z values; three-dimensional graphs will remain three-dimensional. It is only rotation that is constrained.
If there are up to the maximum number of transactions between two nodes (by default eight), they will be drawn as individual transactions. If there are more than this, the transactions will be drawn as edges.
There are three options for drawing labels on graphs: Fast, mixed, and pretty.
When changing from one option to another, a restart of CONSTELLATION is required for the change to take effect.
As you open larger graphs, depending on your hardware specifications, CONSTELLATION will slow down. This threshold allows you to hide the graph entirely so that you can use other tools like the histogram or table view for instance to modify the graph before you visualise the data as a graph.
For this threshold to be used, you need to set the visibility button to hidden -> on the graph toolbar. To ignore this threshold value set the visibility button to visible ->


8 HEADS IN A DUFFEL BAG A film review by Martyn C. Winkler Copyright 1997 Martyn C. Winkler
*** (out of ****)
The directorial debut of screenwriter Tom Schulman can best be described as a dark, wacky comedy; a movie reminiscent of 'nouvelle violence' (think of PULP FICTION), filmed shamelessly in the style of a farcical sitcom. Schulman is probably most known for his Academy Award winning screenplay for DEAD POETS SOCIETY, but is also responsible for writing films ranging from HONEY, I SHRUNK THE KIDS to MEDICINE MAN. For somebody who has been in the movie business for several years already, Schulman is refreshingly energetic and original as a first-time director of his own screenplay. The cast of 8 HEADS IN A DUFFEL BAG consists of actors fitting the nouvelle violence theme (Joe Pesci, for example, in a terrific pastiche of his usual type-cast performances), as well as the sitcom style (David Spade, now starring in 'Just Shoot Me'; and the ever-so-familiar-face-but-nobody-remembers-his-name George Hamilton, from such TV-shows as 'Dynasty'). This mix of opposite worlds is a potentially unstable one, but Schulman manages to keep it together and delivers a highly enjoyable and at times even hilarious film.
The plot is as ridiculous as it is inevitable. Hit man/thug Tommy (Joe Pesci) is assigned to deliver the heads of eight dead mobsters to the Mafia-king who ordered their deaths. He neatly wraps up the heads in plastic bags, places them in, yes, a duffel bag and takes the next commercial flight to San Diego. On the plane he meets Charlie Pritchett (Andy Comeau), a flaky student from Baltimore. Charlie is on his way to Mexico, where he plans to spend the week with his girlfriend (Kristy Swanson) and her parents (George Hamilton and Dyan Cannon). It is not very surprising that Charlie turns out to have a similar duffel bag and that the two accidentally switch luggage at the airport, but hey, we'll forgive 'm. The switch is the start of Tommy's attempts to retrieve his heads and of Charlie's adventures in coping with the discoveries of the lost heads throughout the Mexican hotel. Wild chases ensue, not to mention unspeakable acts with cryogenically frozen bodies, or rather...their heads.
Please give the film the benefit of the doubt, though. It is much more intelligent than it sounds, greatly due to the fact that it acknowledges its farcical and contrived situations. It parodies those situations as much as it shamelessly exploits them for what they are: shallow and mostly physical humor. Take for example the scene where Charlie is trying to take one of the lost heads out of a washing machine, hindered by a blind (!) Mexican cleaning lady. It does not often happen that you can feel free to laugh aloud in the cinema, without guilt, at an obviously predictable and unbelievable scene. Again, this is greatly to the credit of the witty screenplay, as well as the light-hearted direction. Large portions of the film have been shot on studio sets, which inadvertently recreate the feeling of television shows, or even the (comic) theater. Furthermore, Schulman mainly uses wipes, from left to right or vice versa, for the cuts between scenes. Normally this is a no-no in modern day cinema, but the wipes give 8 HEADS... a traditional and easy-going television-look. On top of this farcical foundation, the film sporadically jabs at the viewer with darkly satirical moments. Only in a film like 8 HEADS... can an audience burst out in uncontrollable laughter when a thug throws a grandmother off a cliff...from a moving van. And adding to his obvious homage to traditional television (where nobody is killed on screen), Schulman reintroduces the grandmother at the final credits, suffering only from a broken arm and some bruises.
The acting is highly typecast and stereotypical.  However, the characters created and actors cast are purposely flat and unrealistic. They are a satirical reference to the GOODFELLAS and 'Friends' we have grown to know over the years and help to create the surreal setting of the film. They are essential in making the viewer accept the incredibility of it all.
Now, I must admit the film has its weak moments. Certain built-up scenes, screaming almost for a humorous resolution, are left dangling. Characters are introduced, then later ignored. And the 'grand finale' has promising potential, but is eventually disappointing. However, 8 HEADS IN A DUFFEL BAG easily makes up for those flaws in its off-beat and highly original concept. 8 HEADS is essentially a tribute to the golden age of television. It inserts stylistic elements of that medium into a twisted version of the modern gangster genre of American cinema. Thus, Schulman has created a surprising, intriguing and -heck, I can say it!- funny movie. It hardly ever happens that a film makes fun of...well...itself!
---------------------------------
* = Do NOT go see this film, or I'll have to shoot you!! ** = Not recommended *** = Recommended **** = Go see this film, or I'll shoot you!!
<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


The following variables will be replace at query time to their corresponding value. Seperate values with , (comma) to randomize between them
The following variables will be replace at query time to their corresponding value.


This is a project I have put together from the book Professional JS for Developers by Nicholas C Zakas
See One, Do One, Teach One
var message = "some string";
console.log(typeof (message)); //object
var num =10;
console.log( num.toString() );
var person = new Object();
person.name = "Nicholas";
person.age = 29;
var person = {
name: "Nicholas",
age: 29
}
Top
alert( person["name"] );
alert( person.name );
It's better to use bracket notation as you can substitute variables or use properties with spaces
TopArray Constructor Method
var colors = new Array();
Array Literal Notation
var colors = [];
Top
var colors = ["red", "blue", "yellow"];
colors2[2] = "black";
var colors = ["red", "green", "blue"];
alert( colors.join(", ") ); //red, green, blue
alert( colors.join("||") ); //red || green || blue
'join' method combines elements in array and inserts specified character to separate them.
Arrays have the ability to be converted to stack arrays that allow them to behave like other data structures. They are referred to as L-I-F-O, "Last In First Out".
The insertion is called a push and the removal is called a pop. Push() methods accept arguments and adds them to the end of the array and returns the array's length. The pop() method removes the last item in the array, updates the length, and returns the item.
var colors = new Array();
var count = colors.push( "red", "yellow" );
alert( count ); //2
var item = colors.pop();
alert( item ); //yellow
Just like stacks only allow for L-I-F-O, queues restrict access to F-I-F-O, First In First Out. This is achieved with the shift() method, which removes the first item in the array, returns it, and decreases the length by one.
var colors = new Array();
var count = colors.push( "yellow", "black" );
var item = colors.shift();
alert(item); //yellow
The opposite is the unshift() method which just adds item to the front of the array.
Two methods deal with the reordering of elements already in an array: reverse() and sort().
var values = [ 1, 2, 3, 4, 5 ];
values.reverse();
alert( values ); //5, 4, 3, 2, 1
When it comes to sort(), this will take the string value, not the numeric value. If you want it to sort from lowest to greatest by numerical value, you need to pass in the comparison argument.
var values = [ 0, 1, 5, 10, 15 ];
values.sort();
console.log(values) // 0, 1, 10, 15, 5
function compare(value1, value2){
if(value1 < value2){
return -1;
}else if( value2 < value1 ){
return 1;
}else{
return 0;
}
}
values.sort(compare);
console.log(values); //0, 1, 5, 10, 15
To return the values in descending order, just change the return value for the first two conditionals to their opposite.
The next method we will learn is called the concat() method, which copies the array, appends any items to the array that are passed as the argument, and returns the newly created array.
var colors = [ "red", "blue", "yellow" ];
var colors2 = colors.concat("blacK", "green");
alert(colors2); //red, blue, yellow, black, green
The next method to look at is the slice() method. The slice() method accepts one or two arguments and returns an array from elements already in the array. The arguments it accepts are the starting and ending points, not including the ending point. This does not effect the original array.
var colors = ["red", "blue", "green", "yellow", "purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);
alert( colors2 ); //blue, green, yellow, purple
alert( colors3 ); //blue, green, yellow
One of the most powerful array manipulation methods is splice() which allows you to inject items to the middle of an array. There are three distinct ways to use it:
There are two methods to find the location of an item in an array: indexOf() and lastIndexOf(). Both accept two arguments. The item to look for and an optional starting point in the array. indexOf() starts at the beginning and lastIndexOf() starts at the end. Both return the position of the item in the array or -1 if not found.
There are five methods for iterating through arrays. Each method accepts two arguments: a function to run on each item, and an optional scope object on which to run the function. The function passed into this method will receive three arguments: the array item value, the position, and the array object.


General Information Our School Emblem About DAV Aims and Objectives ISO Certification Main Features Students' Work Admission Form Suggestion-Box


We extend interfaces!
- utilize 24/7 metrics
- transform B2B convergence
- deliver strategic models
- brand killer users
- enhance bleeding-edge e-tailers
- strategize integrated ROI
- e-enable next-generation communities
- drive compelling ROI
- visualize open-source portals
- extend frictionless channels
- optimize cutting-edge convergence