In this notebook, some template code has already been provided for you, and you will need to implement additional functionality to successfully complete this project. You will not need to modify the included code beyond what is requested. Sections that begin with '(IMPLEMENTATION)' in the header indicate that the following block of code will require additional functionality which you must provide. Instructions will be provided for each section, and the specifics of the implementation are marked in the code block with a 'TODO' statement. Please be sure to read the instructions carefully!
Note: Once you have completed all of the code implementations, you need to finalize your work by exporting the Jupyter Notebook as an HTML document. Before exporting the notebook to html, all of the code cells need to have been run so that reviewers can see the final implementation and output. You can then export the notebook by using the menu above and navigating to File -> Download as -> HTML (.html). Include the finished document along with this notebook as your submission.
In addition to implementing code, there will be questions that you must answer which relate to the project and your implementation. Each section where you will answer a question is preceded by a 'Question X' header. Carefully read each question and provide thorough answers in the following text boxes that begin with 'Answer:'. Your project submission will be evaluated based on your answers to each of the questions and the implementation you provide.
Note: Code and Markdown cells can be executed using the Shift + Enter keyboard shortcut. Markdown cells can be edited by double-clicking the cell to enter edit mode.
The rubric contains optional "Stand Out Suggestions" for enhancing the project beyond the minimum requirements. If you decide to pursue the "Stand Out Suggestions", you should include the code in this Jupyter notebook.
In this notebook, you will make the first steps towards developing an algorithm that could be used as part of a mobile or web app. At the end of this project, your code will accept any user-supplied image as input. If a dog is detected in the image, it will provide an estimate of the dog's breed. If a human is detected, it will provide an estimate of the dog breed that is most resembling. The image below displays potential sample output of your finished project (... but we expect that each student's algorithm will behave differently!).
In this real-world setting, you will need to piece together a series of models to perform different tasks; for instance, the algorithm that detects humans in an image will be different from the CNN that infers dog breed. There are many points of possible failure, and no perfect algorithm exists. Your imperfect solution will nonetheless create a fun user experience!
We break the notebook into separate steps. Feel free to use the links below to navigate the notebook.
 Unzip the folder and place it in this project's home directory, at the location /dogImages
.
Download the human dataset. Unzip the folder and place it in the home directory, at location /lfw
.
Note: If you are using a Windows machine, you are encouraged to use 7zip to extract the folder.
In the code cell below, we save the file paths for both the human (LFW) dataset and dog dataset in the numpy arrays human_files
and dog_files
.
!wget -c https://s3-us-west-1.amazonaws.com/udacity-aind/dog-project/dogImages.zip
!wget -c https://s3-us-west-1.amazonaws.com/udacity-aind/dog-project/lfw.zip
!unzip -qq dogImages.zip
!unzip -qq lfw.zip
import numpy as np
from glob import glob
# load filenames for human and dog images
human_files = np.array(glob("lfw/*/*"))
dog_files = np.array(glob("dogImages/*/*/*"))
# print number of images in each dataset
print('There are %d total human images.' % len(human_files))
print('There are %d total dog images.' % len(dog_files))
In this section, we use OpenCV's implementation of Haar feature-based cascade classifiers to detect human faces in images.
OpenCV provides many pre-trained face detectors, stored as XML files on github. We have downloaded one of these detectors and stored it in the haarcascades
directory. In the next code cell, we demonstrate how to use this detector to find human faces in a sample image.
!wget -c https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# extract pre-trained face detector
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_alt.xml')
# load color (BGR) image
img = cv2.imread(human_files[0])
# convert BGR image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find faces in image
faces = face_cascade.detectMultiScale(gray)
# print number of faces detected in the image
print('Number of faces detected:', len(faces))
# get bounding box for each detected face
for (x,y,w,h) in faces:
# add bounding box to color image
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# convert BGR image to RGB for plotting
cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# display the image, along with bounding box
plt.imshow(cv_rgb)
plt.show()
Before using any of the face detectors, it is standard procedure to convert the images to grayscale. The detectMultiScale
function executes the classifier stored in face_cascade
and takes the grayscale image as a parameter.
In the above code, faces
is a numpy array of detected faces, where each row corresponds to a detected face. Each detected face is a 1D array with four entries that specifies the bounding box of the detected face. The first two entries in the array (extracted in the above code as x
and y
) specify the horizontal and vertical positions of the top left corner of the bounding box. The last two entries in the array (extracted here as w
and h
) specify the width and height of the box.
We can use this procedure to write a function that returns True
if a human face is detected in an image and False
otherwise. This function, aptly named face_detector
, takes a string-valued file path to an image as input and appears in the code block below.
# returns "True" if face is detected in image stored at img_path
def face_detector(img_path):
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray)
return len(faces) > 0
Question 1: Use the code cell below to test the performance of the face_detector
function.
human_files
have a detected human face? dog_files
have a detected human face?  You will see that our algorithm falls short of this goal, but still gives acceptable performance. We extract the file paths for the first 100 images from each of the datasets and store them in the numpy arrays human_files_short
and dog_files_short
.
Answer:
from tqdm import tqdm
human_files_short = human_files[:100]
dog_files_short = dog_files[:100]
#-#-# Do NOT modify the code above this line. #-#-#
## TODO: Test the performance of the face_detector algorithm
## on the images in human_files_short and dog_files_short.
faces_human_files = []
faces_dog_files = []
#humans = tqdm(total=100, desc='human_files_short', position=0)
#dogs = tqdm(total=100, desc='dog_files_short', position=1)
for human in human_files_short:
faces_human_files.append(face_detector(human))
#humans.update(1)
for dog in dog_files_short:
faces_dog_files.append(face_detector(dog))
#dogs.update(1)
print(np.mean(faces_human_files))
print(np.mean(faces_dog_files))
We suggest the face detector from OpenCV as a potential way to detect human images in your algorithm, but you are free to explore other approaches, especially approaches that make use of deep learning :). Please use the code cell below to design and test your own face detection algorithm. If you decide to pursue this optional task, report performance on human_files_short
and dog_files_short
.
### (Optional)
### TODO: Test performance of another face detection algorithm.
### Feel free to use as many code cells as needed.
In this section, we use a pre-trained model to detect dogs in images.
The code cell below downloads the VGG-16 model, along with weights that have been trained on ImageNet, a very large, very popular dataset used for image classification and other vision tasks. ImageNet contains over 10 million URLs, each linking to an image containing an object from one of 1000 categories.
import torch
import torchvision.models as models
# define VGG16 model
VGG16 = models.vgg16(pretrained=True)
# check if CUDA is available
use_cuda = torch.cuda.is_available()
# move model to GPU if CUDA is available
if use_cuda:
VGG16 = VGG16.cuda()
Given an image, this pre-trained VGG-16 model returns a prediction (derived from the 1000 possible categories in ImageNet) for the object that is contained in the image.
In the next code cell, you will write a function that accepts a path to an image (such as 'dogImages/train/001.Affenpinscher/Affenpinscher_00001.jpg'
) as input and returns the index corresponding to the ImageNet class that is predicted by the pre-trained VGG-16 model. The output should always be an integer between 0 and 999, inclusive.
Before writing the function, make sure that you take the time to learn how to appropriately pre-process tensors for pre-trained models in the PyTorch documentation.
from PIL import Image
img_path = dog_files[0]
im = Image.open(img_path)
im
from PIL import Image
import torchvision.transforms as transforms
def VGG16_predict(img_path):
'''
Use pre-trained VGG-16 model to obtain index corresponding to
predicted ImageNet class for image at specified path
Args:
img_path: path to an image
Returns:
Index corresponding to VGG-16 model's prediction
'''
## TODO: Complete the function.
## Load and pre-process an image from the given img_path
## Return the *index* of the predicted class for that image
#applying transformations for pre processing
transformations = transforms.Compose([transforms.RandomResizedCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])])
image = Image.open(img_path)
image = transformations(image).float()
image = image.unsqueeze(0)
if use_cuda:
image = image.cuda()
output = VGG16(image)
return output # predicted class index
While looking at the dictionary, you will notice that the categories corresponding to dogs appear in an uninterrupted sequence and correspond to dictionary keys 151-268, inclusive, to include all categories from 'Chihuahua'
to 'Mexican hairless'
. Thus, in order to check to see if an image is predicted to contain a dog by the pre-trained VGG-16 model, we need only check if the pre-trained model predicts an index between 151 and 268 (inclusive).
Use these ideas to complete the dog_detector
function below, which returns True
if a dog is detected in an image (and False
if not).
### returns "True" if a dog is detected in the image stored at img_path
def dog_detector(img_path):
## TODO: Complete the function.
output = VGG16_predict(img_path)
_, pred = torch.max(output, 1)
return (pred in range(151,269)) # true/false
Question 2: Use the code cell below to test the performance of your dog_detector
function.
human_files_short
have a detected dog? dog_files_short
have a detected dog?Answer:
### TODO: Test the performance of the dog_detector function
### on the images in human_files_short and dog_files_short.
dog_detection_humans = []
dog_detection_dogs = []
for human in human_files_short:
dog_detection_humans.append(dog_detector(human))
for dog in dog_files_short:
dog_detection_dogs.append(dog_detector(dog))
print(np.mean(dog_detection_humans), np.mean(dog_detection_dogs))
We suggest VGG-16 as a potential network to detect dog images in your algorithm, but you are free to explore other pre-trained networks (such as Inception-v3, ResNet-50, etc). Please use the code cell below to test other pre-trained PyTorch models. If you decide to pursue this optional task, report performance on human_files_short
and dog_files_short
.
### (Optional)
### TODO: Report the performance of another pre-trained network.
### Feel free to use as many code cells as needed.
Now that we have functions for detecting humans and dogs in images, we need a way to predict breed from images. In this step, you will create a CNN that classifies dog breeds. You must create your CNN from scratch (so, you can't use transfer learning yet!), and you must attain a test accuracy of at least 10%. In Step 4 of this notebook, you will have the opportunity to use transfer learning to create a CNN that attains greatly improved accuracy.
We mention that the task of assigning breed to dogs from images is considered exceptionally challenging. To see why, consider that even a human would have trouble distinguishing between a Brittany and a Welsh Springer Spaniel.
| Brittany | Welsh Springer Spaniel |
|---|---|
It is not difficult to find other dog breed pairs with minimal inter-class variation (for instance, Curly-Coated Retrievers and American Water Spaniels).
| Curly-Coated Retriever | American Water Spaniel |
|---|---|
Likewise, recall that labradors come in yellow, chocolate, and black. Your vision-based algorithm will have to conquer this high intra-class variation to determine how to classify all of these different shades as the same breed.
| Yellow Labrador | Chocolate Labrador | Black Labrador |
|---|---|---|
We also mention that random chance presents an exceptionally low bar: setting aside the fact that the classes are slightly imabalanced, a random guess will provide a correct answer roughly 1 in 133 times, which corresponds to an accuracy of less than 1%.
Remember that the practice is far ahead of the theory in deep learning. Experiment with many different architectures, and trust your intuition. And, of course, have fun!
Use the code cell below to write three separate data loaders for the training, validation, and test datasets of dog images (located at dogImages/train
, dogImages/valid
, and dogImages/test
, respectively). You may find this documentation on custom datasets to be a useful resource. If you are interested in augmenting your training and/or validation data, check out the wide variety of transforms!
import os
from torchvision import datasets, transforms
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
### TODO: Write data loaders for training, validation, and test sets
## Specify appropriate transforms, and batch_sizes
data_transforms = transforms.Compose([transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.RandomRotation(20),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
#choosing the training, validation and test datasets
train_set = datasets.ImageFolder('dogImages/train/', transform=data_transforms)
valid_set = datasets.ImageFolder('dogImages/valid/', transform=data_transforms)
test_set = datasets.ImageFolder('dogImages/test/', transform=data_transforms)
#preparing the data loaders
train_loader = torch.utils.data.DataLoader(train_set, batch_size=20, shuffle=True)
valid_loader = torch.utils.data.DataLoader(valid_set, batch_size=20, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_set, batch_size=20, shuffle=True)
#preparing a common loader for training, validation and testing
loaders_scratch = {
'train' : train_loader,
'valid' : valid_loader,
'test' : test_loader
}
loaders_scratch
Question 3: Describe your chosen procedure for preprocessing the data.
Answer:
Create a CNN to classify dog breed. Use the template in the code cell below.
import torch.nn as nn
import torch.nn.functional as F
# define the CNN architecture
class Net(nn.Module):
### TODO: choose an architecture, and complete the class
def __init__(self):
super(Net, self).__init__()
## Define layers of a CNN
#convolution layer, sees a (224x224x3) tensor
self.conv1 = nn.Conv2d(3, 16, 3, padding=1)
#convolution layer, sees a (112x112x16) tensor
self.conv2 = nn.Conv2d(16, 32, 3, padding=1)
#convolution layer, sees a (56x56x32) tensor
self.conv3 = nn.Conv2d(32, 64, 3, padding=1)
#convolution layer, sees a (28x28x64) tensor
self.conv4 = nn.Conv2d(64, 128, 3, padding=1)
# max pooling layer
self.pool = nn.MaxPool2d(2, 2)
# fully connected layers
#linear layer (14*14*128 -> 5000)
self.fc1 = nn.Linear(128 * 14 * 14, 5000)
#linear layer (5000 -> 133)
self.fc2 = nn.Linear(5000, 133)
#dropout layer (p = 0.2)
self.dropout = nn.Dropout(p=0.2)
def forward(self, x):
## Define forward behavior
# sequence of convolution and max pooling layers
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = self.pool(F.relu(self.conv3(x)))
x = self.pool(F.relu(self.conv4(x)))
#flatten the image input for fully connected layers
x = x.view(-1, 128 * 14 * 14)
# add dropout
x = self.dropout(x)
#adding 1st hidden layer with Relu activation
x = F.relu(self.fc1(x))
#add dropout
x = self.dropout(x)
#adding 2nd hidden layer with Relu activation
x = self.fc2(x)
#add dropout
x = self.dropout(x)
return x
#-#-# You so NOT have to modify the code below this line. #-#-#
# instantiate the CNN
model_scratch = Net()
# move tensors to GPU if CUDA is available
if use_cuda:
model_scratch.cuda()
print(model_scratch)
Question 4: Outline the steps you took to get to your final CNN architecture and your reasoning at each step.
Answer:
Use the next code cell to specify a loss function and optimizer. Save the chosen loss function as criterion_scratch
, and the optimizer as optimizer_scratch
below.
import torch.optim as optim
### TODO: select loss function
criterion_scratch = nn.CrossEntropyLoss()
### TODO: select optimizer
optimizer_scratch = optim.SGD(model_scratch.parameters(), lr=0.1)
Train and validate your model in the code cell below. Save the final model parameters at filepath 'model_scratch.pt'
.
def train(n_epochs, loaders, model, optimizer, criterion, use_cuda, save_path):
"""returns trained model"""
# initialize tracker for minimum validation loss
valid_loss_min = np.Inf
for epoch in range(1, n_epochs+1):
# initialize variables to monitor training and validation loss+
train_loss = 0.0
valid_loss = 0.0
###################
# train the model #
###################
model.train()
for batch_idx, (data, target) in enumerate(loaders['train']):
# move to GPU
if use_cuda:
data, target = data.cuda(), target.cuda()
## find the loss and update the model parameters accordingly
## record the average training loss, using something like
## train_loss = train_loss + ((1 / (batch_idx + 1)) * (loss.data - train_loss))
#clear the gradients
optimizer.zero_grad()
#forward pass: computing the predictions for our images
output = model(data)
#calculating the loss
loss = criterion(output, target)
#backpropagation: calculating the gradients
loss.backward()
#updating the weights
optimizer.step()
#updating the training loss
train_loss = train_loss + ((1 / (batch_idx + 1)) * (loss.data - train_loss))
######################
# validate the model #
######################
model.eval()
for batch_idx, (data, target) in enumerate(loaders['valid']):
# move to GPU
if use_cuda:
data, target = data.cuda(), target.cuda()
#forward pass: computing the predictions of our model
output = model(data)
loss = criterion(output, target)
## update the average validation loss
valid_loss = valid_loss + (1/ (batch_idx + 1) * (loss.data - valid_loss))
# print training/validation statistics
print('Epoch: {} \tTraining Loss: {:.6f} \tValidation Loss: {:.6f}'.format(
epoch,
train_loss,
valid_loss
))
## TODO: save the model if validation loss has decreased
if valid_loss < valid_loss_min:
print('Validation loss decreased... {:.6f} -> {:.6f}. Saving model...'.format(
valid_loss_min,
valid_loss))
torch.save(model.state_dict(), save_path)
valid_loss_min = valid_loss
# return trained model
return model
# train the model
model_scratch = train(40, loaders_scratch, model_scratch, optimizer_scratch,
criterion_scratch, use_cuda, 'model_scratch.pt')
# load the model that got the best validation accuracy
model_scratch.load_state_dict(torch.load('model_scratch.pt'))
Try out your model on the test dataset of dog images. Use the code cell below to calculate and print the test loss and accuracy. Ensure that your test accuracy is greater than 10%.
def test(loaders, model, criterion, use_cuda):
# monitor test loss and accuracy
test_loss = 0.
correct = 0.
total = 0.
model.eval()
for batch_idx, (data, target) in enumerate(loaders['test']):
# move to GPU
if use_cuda:
data, target = data.cuda(), target.cuda()
# forward pass: compute predicted outputs by passing inputs to the model
output = model(data)
# calculate the loss
loss = criterion(output, target)
# update average test loss
#test_loss = test_loss + ((1 / (batch_idx + 1)) * (loss.data - test_loss))
test_loss += loss.item()*data.size(0)
# convert output probabilities to predicted class
pred = output.data.max(1, keepdim=True)[1]
# compare predictions to true label
correct += np.sum(np.squeeze(pred.eq(target.data.view_as(pred))).cpu().numpy())
total += data.size(0)
test_loss = test_loss/len(test_loader.dataset)
print('Test Loss: {:.6f}\n'.format(test_loss))
print('\nTest Accuracy: %2d%% (%2d/%2d)' % (
100. * correct / total, correct, total))
# call test function
test(loaders_scratch, model_scratch, criterion_scratch, use_cuda)
You will now use transfer learning to create a CNN that can identify dog breed from images. Your CNN must attain at least 60% accuracy on the test set.
Use the code cell below to write three separate data loaders for the training, validation, and test datasets of dog images (located at dogImages/train
, dogImages/valid
, and dogImages/test
, respectively).
If you like, you are welcome to use the same data loaders from the previous step, when you created a CNN from scratch.
## TODO: Specify data loaders
loaders_transfer = loaders_scratch
Use transfer learning to create a CNN to classify dog breed. Use the code cell below, and save your initialized model as the variable model_transfer
.
import torchvision.models as models
import torch.nn as nn
## TODO: Specify model architecture
model_transfer = models.vgg16(pretrained=True)
#freezing the weights of the trained model
for params in model_transfer.features.parameters():
params.requires_grad = False
num_classes = 133
#adding a new fully connected layer for classifier
model_transfer.classifier[6] = nn.Linear(model_transfer.classifier[6].in_features, num_classes)
print(model_transfer)
if use_cuda:
model_transfer = model_transfer.cuda()
Question 5: Outline the steps you took to get to your final CNN architecture and your reasoning at each step. Describe why you think the architecture is suitable for the current problem.
Answer:
Use the next code cell to specify a loss function and optimizer. Save the chosen loss function as criterion_transfer
, and the optimizer as optimizer_transfer
below.
criterion_transfer = nn.CrossEntropyLoss()
optimizer_transfer = optim.SGD(model_transfer.classifier.parameters(), lr=0.01)
Train and validate your model in the code cell below. Save the final model parameters at filepath 'model_transfer.pt'
.
# train the model
model_transfer = train(30, loaders_transfer, model_transfer, optimizer_transfer, criterion_transfer, use_cuda, 'model_transfer.pt')
# load the model that got the best validation accuracy (uncomment the line below)
model_transfer.load_state_dict(torch.load('model_transfer.pt'))
Try out your model on the test dataset of dog images. Use the code cell below to calculate and print the test loss and accuracy. Ensure that your test accuracy is greater than 60%.
test(loaders_transfer, model_transfer, criterion_transfer, use_cuda)
Write a function that takes an image path as input and returns the dog breed (Affenpinscher
, Afghan hound
, etc) that is predicted by your model.
### TODO: Write a function that takes a path to an image as input
### and returns the dog breed that is predicted by the model.
data_transfer = {'train': train_set, 'valid' : valid_set, 'test': test_set}
# list of class names by index, i.e. a name can be accessed like class_names[0]
class_names = [item[4:].replace("_", " ") for item in data_transfer['train'].classes]
def predict_breed_transfer(img_path):
# load the image and return the predicted breed
#applying transformations for pre processing
transformations = transforms.Compose([transforms.RandomResizedCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])])
image = Image.open(img_path)
image = transformations(image).float()
image = image.unsqueeze(0)
if use_cuda:
image = image.cuda()
output = model_transfer(image)
_, pred = torch.max(output, 1)
return class_names[pred]
Write an algorithm that accepts a file path to an image and first determines whether the image contains a human, dog, or neither. Then,
You are welcome to write your own functions for detecting humans and dogs in images, but feel free to use the face_detector
and dog_detector
functions developed above. You are required to use your CNN from Step 4 to predict dog breed.
Some sample output for our algorithm is provided below, but feel free to design your own user experience!
### TODO: Write your algorithm.
 Please try your luck again :)")
In this section, you will take your new algorithm for a spin! What kind of dog does the algorithm think that you look like? If you have a dog, does it predict your dog's breed accurately? If you have a cat, does it mistakenly think that your cat is a dog?
Test your algorithm at least six images on your computer. Feel free to use any images you like. Use at least two human and two dog images.
Question 6: Is the output better than you expected :) ? Or worse :( ? Provide at least three possible points of improvement for your algorithm.
Answer: The output is better than I had expected!
## TODO: Execute your algorithm from Step 6 on
## at least 6 images on your computer.
## Feel free to use as many code cells as needed.
## suggested code, below
img_path = human_files[0]
run_app(img_path)
im = Image.open(img_path)
plt.imshow(im)
img_path = human_files[93]
run_app(img_path)
im = Image.open(img_path)
plt.imshow(im)
img_path = dog_files[54]
run_app(img_path)
im = Image.open(img_path)
plt.imshow(im)
img_path = dog_files[697]
run_app(img_path)
im = Image.open(img_path)
plt.imshow(im)
img_path = dog_files[999]
run_app(img_path)
im = Image.open(img_path)
plt.imshow(im)
img_path = dog_files[80]
run_app(img_path)
im = Image.open(img_path)
plt.imshow(im)


Vue.js 1.0.0 Released
Oct 26, 2015
Hi HN! If you are not familiar with Vue.js, you might want to read this blog post for a higher level overview.
After 300+ commits, 8 alphas, 4 betas and 2 release candidates, today I am very proud to announce the release of Vue.js 1.0.0 Evangelion! Many thanks to all those who participated in the API re-design process - it would not have been possible without all the input from the community.
Improved Template Syntax
The 1.0 template syntax resolves a lot of subtle consistency issues and makes Vue templates more concise and more readable in general. The most notable new feature is the shorthand syntax for v-on
and v-bind
:
|
When used on a child component, v-on
listens for custom events and v-bind
can be used to bind props. The shorthands using child components very succinct:
|
API Cleanup
The overall goal for Vue.js 1.0 is to make it suitable for larger projects. This is why there are many API deprecations. Except for ones that are barely used, the most common reason for a deprecation is that the feature leads to patterns that damages maintainability. Specifically, we are deprecating features that make it hard to maintain and refactor a component in isolation without affecting the rest of the project.
For example, the default asset resolution in 0.12 has implicit fallbacks to parents in the component tree. This makes the assets available to a component non-deterministic and subject how it is used at runtime. In 1.0, all assets are now resolved in strict mode and there are no longer implicit fallbacks to parent. The inherit
option is also removed, because it too often leads to tightly coupled components that are hard to refactor.
Faster Initial Rendering
1.0 replaces the old v-repeat
directive with v-for
. In addition to providing the same functionality and more intuitive scoping, v-for
provides up to 100% initial render performance boost when rendering large lists and tables!
More Powerful Tooling
There are also exciting things going on outside of Vue.js core - vue-loader and vueify have received major upgrades including:
Hot component reloading. When a
*.vue
component is edited, all of its active instances are hot swapped without reloading the page. This means when making small changes, e.g. tweaking the styles or the template, your app doesn’t need to fully reload; the state of the app the swapped component can be preserved, drastically improving the development experience.Scoped CSS. By simply adding a
scoped
attribute to your*.vue
component style tags, the component’s template and final generated CSS are magically re-written to ensure a component’s styles are only applied to its own elements. Most importantly, the styles specified in a parent component does not leak down to child components nested within it.ES2015 by default. JavaScript is evolving. You can write much cleaner and expressive code using the latest syntax.
vue-loader
andvueify
now transpiles the JavaScript in your*.vue
components out of the box, without the need for extra setup. Write future JavaScript today!
Combined with vue-router, Vue.js is now more than a library - it provides a solid foundation for building complex SPAs.
What’s Next?
As what 1.0.0 usually suggests, the core API will stay stable for the foreseeable future and the library is ready for production use. Future development will focus on:
Improving
vue-router
and make it production ready.Streamlining the developer experience, e.g. a better devtool and a CLI for scaffolding Vue.js projects and components.
Providing more learning resources such as tutorials and examples.


Hello! My name is Jason Park and I am currently studying Geography: Data Science at the University of Washington. About 6 months ago, I had lost my interest in technology, and thought I was done pursuing a career in the industry. However, with the help of a technology mentorship group led by Noah Addy, the current Director of Engineer at SAP Concur, I re-discovered my interest in an IT career. My goal now is to find a position in the tech industry, and grow my skillset from that point forwards! I believe my diverse work experiences and drive to learn would make me an asset any software team. Feel free to reach out to me for any questions or interest!
Company name - C21 at University of Washington's College of Arts & Sciences
Link to my portfolio work
Contact Information


--- layout: post date: 2010-12-30 time: "09:00:00" authors: ["Greg Wilson"] title: More Detailed Outline for HPC Lecture tags: ["Content"] ---
I've added a more detailed outline for a lecture on high-performance computing to the site; feedback on the content and order would be very welcome, as would pointers to tools that are easy to teach with (as opposed to being powerful in the hands of experienced users).


We are pleased to announce that we have a new application in OsmAnd family. This application helps to see your contacts on the map in OsmAnd. It has a social aspect; you need to have contacts, that's why it was challenging for us to choose the platform to build it on.
We have chosen Telegram as the most open social platform since it has an Open API, Open SDK and, moreover, it will eventually have an Open Server implementation (Blockchain).
It is important that we have a great level of interoperability between the applications. You can easily exchange your location with your contacts without having 'Telegram mobile app' (OsmAnd Telegram is an independent telegram client) and, the other way around, your contacts should not necessarily have OsmAnd Telegram in order to see your location. We designed OsmAnd Telegram so you could still use your Telegram app and OsmAnd app naturally without flaws.
The application sends the Live Location messages to the selected chats for the time you specified, displays a list of your contacts and groups, and checks the chats for the presence of the messages with a location, which are then displayed on the map in OsmAnd. The application does not send or view your text messages.
Log in using your phone number registered in Telegram to enable the following:There are several settings for managing the frequency of sharing locations and controlling the display of the locations sent to you.
Send my location — allows you to set the interval for sending your position from once per second (for increasing accuracy) to once in 5 minutes (for reducing power consumption).
Stale location — allows you to set the time (from 1 minute to 1 hour) after which the location of your contact will be considered outdated. If the location becomes outdated, the position becomes gray.
Location history — allows setting the time (from 5 minutes to 24 hours) after which the contact with the deleted location will be hidden from the list and the OsmAnd map.
The OsmAnd Connect setting allows you to select the version of OsmAnd in which your contacts with the position will be displayed on the map.
We have also prepared a Telegram bot called 'OsmAnd Assistant,' so you can integrate OsmAnd Telegram with 3rd party trackers or APIs. Hence, you can not only share your location but also the locations of your bicycle or a group of individuals taking part in racing which is available via API, and OsmAnd Telegram will make sure you have a nice presentation of locations on the map in OsmAnd itself.
OsmAnd Telegram represents the idea that we are not trying to lock-in our users into a single app, and we are in line with our mission to bring the value to end-users by focusing on the strong side of our app, meanwhile integrating with others. Recently we have also expanded a lot of our OsmAnd APIs, so you can fine-tune or write another app that will seamlessly integrate with OsmAnd. Please share with us what you think about this new app on Twitter and other social channels.
To view the GPS positions of contacts on the map, you need the latest version of OsmAnd or OsmAnd+. The minimum supported version of OsmAnd or OsmAnd + is 3.0.4.
Get OsmAnd Telegram - Location Sharing Google Play.


The instructions below assume that you are installing the ArcGIS JavaScript API library in the following location on an Apache Tomcat Web Server, "http://<myserver>:8080/arcgis_js_api/library/3.17/" where <myserver> is the domain name of your Web site and '8080' is the default Web server port. This port number, of course, can be changed for your instance if you choose to not use this default port. After copying files to your Web server, you will need to edit some files to include the URL to the server and directory that you are planning to install to.
For instructions on deploying the library on IIS for Windows, please go to the installation notes for Windows.
\arcgis_js_api\library
and all its contents from the zip file to your Web server. In this example the files are copied to:<apache_tomcat_home>/webapps/arcgis_js_api/library
ArcGIS JSAPI 3.17 contains two builds--a normal build and a compact build. The compact build removes the Dojo Dijit dependancy and minimizes the non-essential ArcGIS JSAPI classes. Please see the documentation for more details.
Your directions may differ depending on your server configuration or Web server, but the process is the same.
Configuration options for normal build:<apache_tomcat_home>\webapps\arcgis_js_api\library\3.17\3.17\init.js
in a text editor and search for the text '[HOSTNAME_AND_PATH_TO_JSAPI]'
, and replace this text with "<myserver>:8080/arcgis_js_api/library/3.17/3.17/"
<apache_tomcat_home>\webapps\arcgis_js_api\library\3.17\dojo\dojo.js
in a text editor and search for the text '[HOSTNAME_AND_PATH_TO_JSAPI]'
, and replace this text with '<myserver>:8080/arcgis_js_api/library/3.17/3.17/'
<apache_tomcat_home>\webapps\arcgis_js_api\library\3.17\3.17compact\init.js
in a text editor and search for the text '[HOSTNAME_AND_PATH_TO_JSAPI]'
, and replace this text with "<myserver>:8080/arcgis_js_api/library/3.17/3.17compact/"
<apache_tomcat_home>\webapps\arcgis_js_api\library\3.17\3.17compact\dojo\dojo.js
in a text editor and search for the text '[HOSTNAME_AND_PATH_TO_JSAPI]'
, and replace this text with '<myserver>:8080/arcgis_js_api/library/3.17/3.17compact/'
The steps below outline what to do if accessing non-default (80/443) HTTP/HTTPS ports in a single local API install.
Assuming init.js
is accessible at the following URL: http://xyz.company.com/jsapi/init.js
and the web server uses a non-standard port for HTTPS, the baseUrl
value below would work:
baseUrl: (location.protocol === "file:" ? "http:" : location.protocol) + "//" + "xyz.company.com:" + (location.protocol === "https:" ? 8443 : 9090) + "/jsapi/dojo"
"[HOSTNAME_AND_PATH_TO_JSAPI]/dojo"
"xyz.company.com:" + (location.protocol === "https:" ? "8443" : "9090") + "/jsapi/dojo"
If the HTTP port is standard 80, but HTTPS port is non-standard.
"xyz.company.com:" + (location.protocol === "https:" ? "8443" : "") + "/jsapi/dojo"
Now you should be able to access the ArcGIS JavaScript library from your Web server using the following URL(s):
http://<myserver>:8080/arcgis_js_api/library/3.17/3.17compact/ http://<myserver>:8080/arcgis_js_api/library/3.17/3.17/
Test your install. You can use the following test code to validate your JSAPI library install.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Simple Map</title> <link rel="stylesheet" type="text/css" href="http://<myserver>:8080/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css"> <link rel="stylesheet" type="text/css" href="http://<myserver>:8080/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" />

The Services Directory allows you to view Map and Image services using the JavaScript API. Set the following values in the rest-config.properties file to use the local install:
#JS API URLs jsapi.arcgis=http://<myserver>:8080/arcgis_js_api/library/3.17/3.17/ jsapi.arcgis.sdk=http://<myserver>:8080/arcgis_js_sdk/sdk/ jsapi.arcgis.css=http://<myserver>:8080/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css
View the Configuring the Rest API help topic for more details.


public static class Protocol.Server
extends java.lang.Object
| Modifier and Type | Class and Description |
|---|---|
static class |
Protocol.Server.Features
The constants for the feature names.
|
static class |
Protocol.Server.Settings
Settings of the server.
|
| Modifier and Type | Field and Description |
|---|---|
static java.lang.String |
ADDTOHAND
Server sends stones to the player hand.
|
static java.lang.String |
CHAT
Send a chat message to the clients.
|
static java.lang.String |
DECLINEINVITE |
static java.lang.String |
ERROR
All error messages that are send to the client.
|
static java.lang.String |
GAME_END
Message the clients that the game has finished.
|
static java.lang.String |
HALLO
Responds to a hallo from the server to a client.
|
static java.lang.String |
INVITE
Command to invite a player.
|
static java.lang.String |
LEADERBOARD
Server sends the leader board to the clients.
|
static java.lang.String |
MOVE
Message that a move has been made and who is the next message.
|
static java.lang.String |
OKWAITFOR
Sends the amount of players we are waiting for.
|
static java.lang.String |
STARTGAME
Message the clients that the game is starting
and who they are playing with.
|
static java.lang.String |
STONESINBAG
Server sends the amount of stones in the bag.
|
| Constructor and Description |
|---|
Server() |
public static final java.lang.String HALLO
public static final java.lang.String ERROR
public static final java.lang.String OKWAITFOR
public static final java.lang.String STARTGAME
public static final java.lang.String GAME_END
public static final java.lang.String MOVE
public static final java.lang.String CHAT
public static final java.lang.String ADDTOHAND
public static final java.lang.String STONESINBAG
public static final java.lang.String LEADERBOARD
public static final java.lang.String INVITE
public static final java.lang.String DECLINEINVITE


|
Clingo C API
C API for clingo providing high level functions to control grounding and solving.
|
Functions and data structures to inspect programs.
Classes | |
| struct | clingo_ground_program_observer |
| An instance of this struct has to be registered with a solver to observe ground directives as they are passed to the solver. More... | |
Typedefs | |
| typedef int | clingo_heuristic_type_t |
| Corresponding type to clingo_heuristic_type_e. | |
| typedef int | clingo_external_type_t |
| Corresponding type to clingo_external_type_e. | |
| typedef struct clingo_ground_program_observer | clingo_ground_program_observer_t |
| An instance of this struct has to be registered with a solver to observe ground directives as they are passed to the solver. More... | |
Enumerations | |
| enum | clingo_heuristic_type_e { clingo_heuristic_type_level = 0, clingo_heuristic_type_sign = 1, clingo_heuristic_type_factor = 2, clingo_heuristic_type_init = 3, clingo_heuristic_type_true = 4, clingo_heuristic_type_false = 5 } |
| Enumeration of different heuristic modifiers. More... | |
| enum | clingo_external_type_e { clingo_external_type_free = 0, clingo_external_type_true = 1, clingo_external_type_false = 2, clingo_external_type_release = 3 } |
| Enumeration of different external statements. More... | |
| typedef struct clingo_ground_program_observer clingo_ground_program_observer_t |
An instance of this struct has to be registered with a solver to observe ground directives as they are passed to the solver.
Not all callbacks have to be implemented and can be set to NULL if not needed. If one of the callbacks in the struct fails, grounding is stopped. If a non-recoverable clingo API call fails, a callback must return false. Otherwise clingo_error_unknown should be set and false returned.
Enumeration of different heuristic modifiers.


acl acl2013 acl2013-180 acl2013-180-reference knowledge-graph by maker-knowledge-mining
Source: pdf
Author: Feifei Zhai ; Jiajun Zhang ; Yu Zhou ; Chengqing Zong
Abstract: Predicate-argument structure (PAS) has been demonstrated to be very effective in improving SMT performance. However, since a sourceside PAS might correspond to multiple different target-side PASs, there usually exist many PAS ambiguities during translation. In this paper, we group PAS ambiguities into two types: role ambiguity and gap ambiguity. Then we propose two novel methods to handle the two PAS ambiguities for SMT accordingly: 1) inside context integration; 2) a novel maximum entropy PAS disambiguation (MEPD) model. In this way, we incorporate rich context information of PAS for disambiguation. Then we integrate the two methods into a PASbased translation framework. Experiments show that our approach helps to achieve significant improvements on translation quality. 1


|
||||||||||
| PREV NEXT | FRAMES NO FRAMES |
| Packages that use WorkspaceElement | |
|---|---|
| domosaics.model.workspace | |
| domosaics.ui | |
| domosaics.ui.workspace | |
| domosaics.ui.workspace.components |
| Uses of WorkspaceElement in domosaics.model.workspace |
|---|
| Subclasses of WorkspaceElement in domosaics.model.workspace | |
|---|---|
class |
CategoryElement
CategoryElement describes Workspace elements, representing categories for views respectively datasets. |
class |
ProjectElement
ProjectElement describes Workspace elements, representing hole projects. |
class |
ViewElement
ViewElement describes workspace elements, representing views which were loaded. |
class |
Workspace
Workspace is the top level hierarchy from all workspace elements. |
| Methods in domosaics.model.workspace that return WorkspaceElement | |
|---|---|
WorkspaceElement |
WorkspaceElement.addChild(WorkspaceElement newChild)
Adds a new child to the element |
WorkspaceElement |
WorkspaceElement.getChildAt(int index)
Return the child element at the specified index |
WorkspaceElement |
WorkspaceElement.getParent()
Returns parent element |
| Methods in domosaics.model.workspace that return types with arguments of type WorkspaceElement | |
|---|---|
java.util.List<WorkspaceElement> |
WorkspaceElement.getChildren()
Return a list of all children as array |
java.util.List<WorkspaceElement> |
Workspace.getProjects()
Return all projects |
java.util.List<WorkspaceElement> |
CategoryElement.getViews()
Returns a list of all assigned views to this element |
| Methods in domosaics.model.workspace with parameters of type WorkspaceElement | |
|---|---|
WorkspaceElement |
WorkspaceElement.addChild(WorkspaceElement newChild)
Adds a new child to the element |
void |
Workspace.changeElementName(WorkspaceElement element,
java.lang.String newName)
Changes an elements name within the workspace |
int |
WorkspaceElement.getIndex(WorkspaceElement child)
Returns the index of a child |
void |
WorkspaceElement.removeChild(WorkspaceElement c)
Removes a child from the element |
ViewElement[] |
Workspace.removeElement(WorkspaceElement element)
When removing an element from the workspace the procedure has to vary based on the elements type, because the views also have to be removed from the ViewHandler and if active from the AngstdDesktop. |
void |
WorkspaceElement.setParent(WorkspaceElement parent)
Sets the parent element for this element |
| Uses of WorkspaceElement in domosaics.ui |
|---|
| Methods in domosaics.ui that return WorkspaceElement | |
|---|---|
WorkspaceElement |
WorkspaceManager.getFirstProject()
Return the first project within the workspace. |
| Methods in domosaics.ui with parameters of type WorkspaceElement | |
|---|---|
void |
WorkspaceManager.changeElementName(WorkspaceElement element,
java.lang.String newName)
Changes the name of a workspace element. |
void |
WorkspaceManager.removeFromAngstd(WorkspaceElement element)
Gets only called when view elements are deleted by the workspace context menu option "delete". |
| Uses of WorkspaceElement in domosaics.ui.workspace |
|---|
| Methods in domosaics.ui.workspace that return WorkspaceElement | |
|---|---|
WorkspaceElement |
WorkspaceSelectionManager.getSelectedElement()
Returns the actual selected element |
| Methods in domosaics.ui.workspace with parameters of type WorkspaceElement | |
|---|---|
void |
WorkspaceSelectionManager.setSelectedElement(WorkspaceElement element)
Manually selects an element. |
| Uses of WorkspaceElement in domosaics.ui.workspace.components |
|---|
| Methods in domosaics.ui.workspace.components that return WorkspaceElement | |
|---|---|
WorkspaceElement |
WorkspaceChangeEvent.getNode()
Returns the modified element within the workspace tree |
| Methods in domosaics.ui.workspace.components with parameters of type WorkspaceElement | |
|---|---|
void |
WorkspaceChangeEvent.setNode(WorkspaceElement node)
Sets the modified workspace element |
| Constructors in domosaics.ui.workspace.components with parameters of type WorkspaceElement | |
|---|---|
WorkspaceChangeEvent(WorkspaceElement source)
Constructor for a new WorkspaceChangeEvenet, where only the changed element is specified, but not the way it was changed. |
|
WorkspaceChangeEvent(WorkspaceElement source,
boolean added,
boolean changed,
boolean removed)
Constructor for a new WorkspaceChangeEvenet, where also the Change is specified. |
|
||||||||||
| PREV NEXT | FRAMES NO FRAMES |


One night a friend of mine and I had nothing to do, we were just sitting around smoking a j when we had the idea to try smoking mushrooms.
I had a few grams that i had picked up ealier and decided to throw a G in for an experiment. Either of us have tried smoking mushrooms so we weren't all that sure what to expect. We broke up about a gram of mushrooms with about 3/4 of a gram of weed and rolled two nice fattys. I have done mushrooms before and felt all the normal effect of eating shrooms but never smoking.
We lit up the first reefer and started puffing on it. not a bad taste, not nearly as bad as eating them. I didn't think that much would happen so i would be satisfied with pretty much anything.
I was already pretty stoned, but about half way through the first joint, i looked down at the floor just to see an ant run in front of me. i thought it was real so i brushed it with my hand to get it out of the way but vanished when i did so. I also saw the regular visuals of a light shroom buzz, moving color patters, objects breathing etc etc. One other thing that was interesting was that when i went home, in my bed i was hearing punk music that was playing quite loud, i worried that it would wake up the rest of my family so i got up to turn it off, when i did i realized that i didn't even but any music on and that it was crazy to think that there would be music playing full blast in the middle of the night. then it was gone. it was pretty cool. I also experienced closed eye visuals and got some quite cool thoughts about life and everything that you would usually ponder while on shrooms and to a lesser effect weed.
All in all it was a good experience, in short i would describe it as a very intense weed high. I would suggest trying it to people if you like trying new ways of trying things, but if you really like to get screwed on mushrooms, just go with the traditional method of scarfing them down.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


#include "ruby/ruby.h"
#include "version.h"
#include <stdio.h>
Go to the source code of this file.
Defines | |
| #define | PRINT(type) puts(ruby_##type) |
| #define | MKSTR(type) rb_obj_freeze(rb_usascii_str_new(ruby_##type, sizeof(ruby_##type)-1)) |
| #define | RUBY_ARCH RUBY_PLATFORM |
| #define | RUBY_SITEARCH RUBY_ARCH |
| #define | RUBY_LIB_PREFIX RUBY_EXEC_PREFIX"/lib/ruby" |
| #define | RUBY_SITE_LIB RUBY_LIB_PREFIX"/site_ruby" |
| #define | RUBY_VENDOR_LIB RUBY_LIB_PREFIX"/vendor_ruby" |
| #define | RUBY_LIB RUBY_LIB_PREFIX "/"RUBY_LIB_VERSION |
| #define | RUBY_SITE_LIB2 RUBY_SITE_LIB "/"RUBY_LIB_VERSION |
| #define | RUBY_VENDOR_LIB2 RUBY_VENDOR_LIB "/"RUBY_LIB_VERSION |
| #define | RUBY_ARCHLIB RUBY_LIB "/"RUBY_ARCH |
| #define | RUBY_SITE_ARCHLIB RUBY_SITE_LIB2 "/"RUBY_SITEARCH |
| #define | RUBY_VENDOR_ARCHLIB RUBY_VENDOR_LIB2 "/"RUBY_SITEARCH |
Functions | |
| void | Init_version (void) |
| void | ruby_show_version (void) |
| void | ruby_show_copyright (void) |
Variables | |
| const int | ruby_api_version [] |
| const char | ruby_version [] = RUBY_VERSION |
| const char | ruby_release_date [] = RUBY_RELEASE_DATE |
| const char | ruby_platform [] = RUBY_PLATFORM |
| const int | ruby_patchlevel = RUBY_PATCHLEVEL |
| const char | ruby_description [] = RUBY_DESCRIPTION |
| const char | ruby_copyright [] = RUBY_COPYRIGHT |
| const char | ruby_engine [] = "ruby" |
| VALUE | ruby_engine_name = Qnil |
| const char | ruby_initial_load_paths [] |
Definition at line 17 of file version.c.
Referenced by Init_version().
Definition at line 16 of file version.c.
Referenced by BSD_vfprintf(), ruby_show_copyright(), and ruby_show_version().
| #define RUBY_VENDOR_ARCHLIB RUBY_VENDOR_LIB2 "/"RUBY_SITEARCH |
| #define RUBY_VENDOR_LIB2 RUBY_VENDOR_LIB "/"RUBY_LIB_VERSION |
| void Init_version | ( | void | ) |
Definition at line 99 of file version.c.
References INT2FIX, MKSTR, rb_define_global_const(), ruby_engine_name, RUBY_PATCHLEVEL, RUBY_REVISION, and version().
| void ruby_show_copyright | ( | void | ) |
| void ruby_show_version | ( | void | ) |
Definition at line 137 of file version.c.
References PRINT.
Referenced by proc_options(), and process_options().
| const int ruby_api_version[] |
| const char ruby_copyright[] = RUBY_COPYRIGHT |
| const char ruby_description[] = RUBY_DESCRIPTION |
Definition at line 62 of file version.c.
Referenced by rb_async_bug_errno(), and report_bug().
| const char ruby_engine[] = "ruby" |
Definition at line 65 of file version.c.
Referenced by Init_version(), and vm_backtrace_each().
| const char ruby_initial_load_paths[] |
| const int ruby_patchlevel = RUBY_PATCHLEVEL |
| const char ruby_platform[] = RUBY_PLATFORM |
| const char ruby_release_date[] = RUBY_RELEASE_DATE |
| const char ruby_version[] = RUBY_VERSION |


Isar735.github.io
Buy products related to kids' creative writing products and see what customers say about kids' creative writing products on Amazon.com FREE DELIVERY possible.
BibMe Free Bibliography Citation Maker - MLA, APA, Chicago, Harvard.
Scholastic creative writing generator - IearnDaily.com. Story Starters: Creative Writing Prompts for - Scholastic. Scholastic s Adventure Story Starters writing activity for kids generates fun creative writing prompts for students to use in writing stories of adventure. Parents Magazine and Scholastic, typing games and much scholastic creative writing generator! Als u akkoord bent — a word cloud is a graphical representation.
Scholastic creative writing generator to write about thesis introduction writer. Colombias biodiversity biodiversity means variety of aesthetic education non western.
THE SECRET DOCTRINE: THE SYNTHESIS OF SCIENCE, RELIGION, AND PHILOSOPHY. by H. P. BLAVATSKY, Author of "ISIS UNVEILED." "There is no Religion higher than Truth.". Scholastic creative writing - Professionally written and HQ academic writings. Dissertations and resumes at most attractive prices. Entrust your essays Use quotes from outside sources to help illustrate and expand on your own points, but the majority of your paper should be your own writing and ideas. MLA Formatting and Style Guide // Purdue Writing. Adventure Story Starters: Writing Prompts for - Scholastic. Maybe you ve been here before. It s writing time in your classroom. You spot a student exhibiting these behaviors: First sign: The deer in the headlights.
ABCya! Educational Computer Games A picture of the character is then added. The kids get very creative with these and the more we do it, the better they get! For fun, have your kids try Templeton. Examples of Materials That Can Be Adapted For Therapy a collection of resources by Judith Maginnis Kuster. The following is one section of Judith Kuster's.
Pat McNees - Telling Your Story. Abbreviations List by FakeNewspapers.com. Home Page for SuperKids. SuperKids provides educational resources for parents, teachers, and kids, including impartial reviews of children's software, math worksheets. Few of the activities accessed by these links have been made by Mr. Ferlazzo. Most of these links will take you to websites created by companies, public institutions. ABCya.com word clouds for kids! A word cloud is a graphical representation of word frequency. Type or paste text into the box below and press the arrow button
Free Language Arts Lesson Plans and Teaching Ideas.
Fake News Papers Fake News Videos A Few Abbreviations. Writing Prompt Generator. Generate your next creative writing prompt with this little tool. Don’t forget to dive deeper into your characters with the character. Scholastic's Adventure Story Starters writing activity for kids generates fun creative writing prompts for students to use in writing stories of adventure. Scholastic creative writing - Tastefulventure. Scholastic creative writing generator. From selected from selected stic’s interactive “myths brainstorming machine” tool (grades 4–9) helps students Scholastic creative writing generator - stanleylocksmiths.com. Writing Prompt Generator – Your story idea generator. Dear Twitpic Community - thank you for all the wonderful photos you have taken over the years. We have now placed Twitpic in an archived state.
Scholastic creative writing generator. SuperKids Educational Software Review. Ashley River Creative Arts Elementary School, in partnership with families and community, provides students with a strong academic curriculum infused Poetry Poets - Aussie Educator. The Purdue University Online Writing Lab serves writers from around the world and the Purdue University Writing Lab helps writers on Purdue's campus. Puzzlemaker: Game Based Learning Discovery Education. MLA Format Citation Generator Guide. Help writing speech good. scholastic creative writing. 101 Websites for Elementary Teachers That You Should. Fast Essays: Scholastic creative writing generator A list of 101 websites for elementary teachers that you should know if you teach PreK through 5th grade. Tons of great resources for the core subjects.
Personal site of author-editor Pat McNees, personal historian and medical historian, bringing a light touch to heavy subjects, helping people and organizations. Best professional online essay writer company is at your service. We help students write academic essays and papers from scratch in just a few clicks, offering. Help writing speech good. scholastic creative writing generator. Write my essay on policy issue, 10 slides powerpoint aking guro aking bayani essay writing. A bibliography, by definition, is the detailed listing of the books, journals, magazines, or online sources that an author has used in researching and writing their. ANOVO, an Ingram Micro company, has been awarded Three’s Reverse Logistics business. Three, who are part of CK Hutchison and have 337 retail stores across
EasyBib: Free Bibliography Generator - MLA, APA, Chicago. Scholastic creative writing generator. Cards can alized with a writer s own words and art, then sent for trip: the colossus writing advantage of the world
René Descartes. Descartes often wrote of the meaning of idea as an image or representation, often but not necessarily "in the mind", which was well known
Scholastic's Story Starters kids' writing activity generates creative writing prompts, from general fiction to adventure, fantasy, and science fiction. Technology rocks. seriously.: The 100th Day of School. BibMe: Free Bibliography Citation Maker Therapy materials - Minnesota State. The 100th day of school is quickly approaching. How is that possible? Didn't we just start school the other. Poetry, including styles of poetry, writing poetry, poetry elements and poets. Creative Writing for Kids: Amazon.com. ABCya is the leader in free educational computer games and mobile apps for kids. The innovation of a grade school teacher, ABCya is an award-winning destination. How to Write a Bibliography - Examples in MLA Style. Discovery Education helps incorporate game-based learning into the classroom with puzzlemaker. Create a new puzzle.
EasyBib — your online writing hub All the tools to submit your paper with confidence. We provide after-sales support solutions for high-tech products – from their sale through to ownership and disposal. Find out more about. Creative Writing Tool: Scholastic Story Generator - Blogger. Home - Ashley River Creative Arts Elementary School. The Secret Doctrine Volume I - Theosophy.


Edit me
Visualizing and monitoring your application
The Quarks application console is a web application that enables you to visualize your application topology and monitor the tuples flowing through your application. The kind of oplets used in the topology, as well as the stream tags included in the topology, are also visible in the console.
Adding the console web app to your application
To use the console, you must use the Quarks classes that provide the service to access the console web application or directly call the HttpServer
class itself, start the server and then obtain the console URL.
The easiest way to include the console in your application is to use the the DevelopmentProvider
class. DevelopmentProvider
is a subclass of DirectProvider
and adds services such as access to the console web application and counter oplets used to determine tuple counts. You can get the URL for the console from the DevelopmentProvider
using the getService
method as shown in a hypothetical application shown below:
import java.util.concurrent.TimeUnit;
import quarks.console.server.HttpServer;
import quarks.providers.development.DevelopmentProvider;
import quarks.topology.TStream;
import quarks.topology.Topology;
public class TempSensorApplication {
public static void main(String[] args) throws Exception {
TempSensor sensor = new TempSensor();
DevelopmentProvider dp = new DevelopmentProvider();
Topology topology = dp.newTopology();
TStream<Double> tempReadings = topology.poll(sensor, 1, TimeUnit.MILLISECONDS);
TStream<Double> filteredReadings = tempReadings.filter(reading -> reading < 50 || reading > 80);
filteredReadings.print();
System.out.println(dp.getServices().getService(HttpServer.class).getConsoleUrl());
dp.submit(topology);
}
}
Note that the console URL is being printed to System.out. The filteredReadings are as well, since filteredReadings.print() is being called in the application. You may need to scroll your terminal window up to see the output for the console URL.
Optionally, you can modify the above code in the application to have a timeout before submitting the topology, which would allow you to see the console URL before any other output is shown. The modification would look like this:
// print the console URL and wait for 10 seconds before submitting the topology
System.out.println(dp.getServices().getService(HttpServer.class).getConsoleUrl());
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
//do nothing
}
dp.submit(topology);
The other way to embed the console in your application is shown in the HttpServerSample.java
example. It gets the HttpServer instance, starts it, and prints out the console URL. Note that it does not submit a job, so when the console is displayed in the browser, there are no running jobs and therefore no Topology graph. The example is meant to show how to get the HttpServer
instance, start the console web app and get the URL of the console.
Accessing the console
The console URL has the following format:
http://host_name:port_number/console
Once it is obtained from System.out
, enter it in a browser window.
If you cannot access the console at this URL, ensure there is a console.war
file in the webapps
directory. If the console.war
file cannot be found, an exception will be thrown (in std.out) indicating console.war
was not found.
ConsoleWaterDetector sample
To see the features of the console in action and as a way to demonstrate how to monitor a topology in the console, let's look at the ConsoleWaterDetector
sample.
Prior to running any console applications, the console.war
file must be built as mentioned above. If you are building quarks from a Git repository, go to the top level Quarks directory and run ant
.
Here is an example in my environment:
Susans-MacBook-Pro-247:quarks susancline$ pwd
/Users/susancline/git/quarks
Susans-MacBook-Pro-247:quarks susancline$ ant
Buildfile: /Users/susancline/git/quarks/build.xml
setcommitversion:
init:
suball:
init:
project.component:
compile:
...
[javadoc] Constructing Javadoc information...
[javadoc] Standard Doclet version 1.8.0_71
[javadoc] Building tree for all the packages and classes...
[javadoc] Generating /Users/susancline/git/quarks/target/docs/javadoc/quarks/analytics/sensors/package-summary.html...
[javadoc] Copying file /Users/susancline/git/quarks/analytics/sensors/src/main/java/quarks/analytics/sensors/doc-files/deadband.png to directory /Users/susancline/git/quarks/target/docs/javadoc/quarks/analytics/sensors/doc-files...
[javadoc] Generating /Users/susancline/git/quarks/target/docs/javadoc/quarks/topology/package-summary.html...
[javadoc] Copying file /Users/susancline/git/quarks/api/topology/src/main/java/quarks/topology/doc-files/sources.html to directory /Users/susancline/git/quarks/target/docs/javadoc/quarks/topology/doc-files...
[javadoc] Building index for all the packages and classes...
[javadoc] Building index for all classes...
all:
BUILD SUCCESSFUL
Total time: 3 seconds
This command will let you know that console.war
was built and is in the correct place, under the webapps
directory.
Susans-MacBook-Pro-247:quarks susancline$ find . -name console.war -print
./target/java8/console/webapps/console.war
Now we know we have built console.war
, so we're good to go.
To run this sample from the command line:
Susans-MacBook-Pro-247:quarks susancline$ pwd
/Users/susancline/git/quarks
Susans-MacBook-Pro-247:quarks susancline$ java -cp target/java8/samples/lib/quarks.samples.console.jar:. quarks.samples.console.ConsoleWaterDetector
If everything is successful, you'll start seeing output. You may have to scroll back up to get the URL of the console:
Susans-MacBook-Pro-247:quarks susancline$ java -cp target/java8/samples/lib/quarks.samples.console.jar:. quarks.samples.console.ConsoleWaterDetector
Mar 07, 2016 12:04:52 PM org.eclipse.jetty.util.log.Log initialized
INFO: Logging initialized @176ms
Mar 07, 2016 12:04:53 PM org.eclipse.jetty.server.Server doStart
INFO: jetty-9.3.6.v20151106
Mar 07, 2016 12:04:53 PM org.eclipse.jetty.server.handler.ContextHandler doStart
INFO: Started o.e.j.s.ServletContextHandler@614c5515{/jobs,null,AVAILABLE}
Mar 07, 2016 12:04:53 PM org.eclipse.jetty.server.handler.ContextHandler doStart
INFO: Started o.e.j.s.ServletContextHandler@77b52d12{/metrics,null,AVAILABLE}
Mar 07, 2016 12:04:53 PM org.eclipse.jetty.webapp.StandardDescriptorProcessor visitServlet
INFO: NO JSP Support for /console, did not find org.eclipse.jetty.jsp.JettyJspServlet
Mar 07, 2016 12:04:53 PM org.eclipse.jetty.server.handler.ContextHandler doStart
INFO: Started o.e.j.w.WebAppContext@2d554825{/console,file:///private/var/folders/0c/pb4rznhj7sbc886t30w4vpxh0000gn/T/jetty-<IP_ADDRESS>-0-console.war-_console-any-3101338829524954950.dir/webapp/,AVAILABLE}{/console.war}
Mar 07, 2016 12:04:53 PM org.eclipse.jetty.server.AbstractConnector doStart
INFO: Started ServerConnector@66480dd7{HTTP/1.1,[http/1.1]}{<IP_ADDRESS>:57964}
Mar 07, 2016 12:04:53 PM org.eclipse.jetty.server.Server doStart
INFO: Started @426ms
http://localhost:57964/console
Well1 alert, ecoli value is 1
Well1 alert, temp value is 48
Well3 alert, ecoli value is 1
Now point your browser to the URL displayed above in the output from running the Java command to launch the ConsoleWaterDetector
application. In this case, the URL is http://localhost:57964/console
.
Below is a screen shot of what you should see if everything is working properly:
ConsoleWaterDetector application scenario
The application is now running in your browser. Let's discuss the scenario for the application.
A county agency is responsible for ensuring the safety of residents well water. Each well they monitor has four different sensor types:
- Temperature
- Acidity
- Ecoli
- Lead
The sample application topology monitors 3 wells:
For the hypothetical scenario, Well1 and Well3 produce 'unhealthy' values from their sensors on occasion. Well2 always produces 'healthy' values.
Each well that is to be measured is added to the topology. The topology polls each sensor (temp, ecoli, etc) for each well as a unit. A TStream<Integer> is returned from polling the toplogy and represents a sensor reading. Each sensor reading for the well has a tag added to it with the reading type i.e, "temp", and the well id. Once all of the sensor readings are obtained and the tags added, each sensor reading is 'unioned' into a single TStream<JsonObject>. Look at the waterDetector
method for details on this.
Now, each well has a single stream with each of the sensors readings as a property with a name and value in the TStream<JsonObject>. Next the alertFilter
method is called on the TStream<JsonObject> representing each well. This method checks the values for each well's sensors to determine if they are 'out of range' for healthy values. The filter
oplet is used to do this. If any of the sensor's readings are out of the acceptable range the tuple is passed along. Those that are within an acceptable range are discarded.
Next the applications splitAlert
method is called on each well's stream that contains the union of all the sensor readings that are out of range. The splitAlert
method uses the split
oplet to split the incoming stream into 5 different streams. Only those tuples that are out of range for each stream, which represents each sensor type, will be returned. The object returned from splitAlert
is a list of TStream<JsonObject> objects. The splitAlert
method is shown below:
```
public static List> splitAlert(TStream alertStream, int wellId) {
List<TStream<JsonObject>> allStreams = alertStream.split(5, tuple -> {
if (tuple.get("temp") != null) {
JsonObject tempObj = new JsonObject();
int temp = tuple.get("temp").getAsInt();
if (temp <= TEMP_ALERT_MIN || temp >= TEMP_ALERT_MAX) {
tempObj.addProperty("temp", temp);
return 0;
} else {
return -1;
}
} else if (tuple.get("acidity") != null){
JsonObject acidObj = new JsonObject();
int acid = tuple.get("acidity").getAsInt();
if (acid <= ACIDITY_ALERT_MIN || acid >= ACIDITY_ALERT_MAX) {
acidObj.addProperty("acidity", acid);
return 1;
} else {
return -1;
}
} else if (tuple.get("ecoli") != null) {
JsonObject ecoliObj = new JsonObject();
int ecoli = tuple.get("ecoli").getAsInt();
if (ecoli >= ECOLI_ALERT) {
ecoliObj.addProperty("ecoli", ecoli);
return 2;
} else {
return -1;
}
} else if (tuple.get("lead") != null) {
JsonObject leadObj = new JsonObject();
int lead = tuple.get("lead").getAsInt();
if (lead >= LEAD_ALERT_MAX) {
leadObj.addProperty("lead", lead);
return 3;
} else {
return -1;
}
} else {
return -1;
}
});
return allStreams;
}
```
Next we want to get the temperature stream from the first well and put a rate meter on it to determine the rate at which the out of range values are flowing in the stream.
```
List> individualAlerts1 = splitAlert(filteredReadings1, 1);
// Put a rate meter on well1's temperature sensor output
Metrics.rateMeter(individualAlerts1.get(0));
* Next all the sensors for well 1 have tags added to the stream indicating the stream is out of range for that sensor and the well id. Next a sink is added, passing the tuple to a `Consumer` that formats a string to `System.out` containing the well Id, alert type (sensor type) and value of the sensor.
// Put a rate meter on well1's temperature sensor output
Metrics.rateMeter(individualAlerts1.get(0));
individualAlerts1.get(0).tag(TEMP_ALERT_TAG, "well1").sink(tuple -> System.out.println("\n" + formatAlertOutput(tuple, "1", "temp")));
individualAlerts1.get(1).tag(ACIDITY_ALERT_TAG, "well1").sink(tuple -> System.out.println(formatAlertOutput(tuple, "1", "acidity")));
individualAlerts1.get(2).tag(ECOLI_ALERT_TAG, "well1").sink(tuple -> System.out.println(formatAlertOutput(tuple, "1", "ecoli")));
individualAlerts1.get(3).tag(LEAD_ALERT_TAG, "well1").sink(tuple -> System.out.println(formatAlertOutput(tuple, "1", "lead")));
Output in the terminal window from the `formatAlertOutput` method will look like this:
Well1 alert, temp value is 86
Well3 alert, ecoli value is 2
Well1 alert, ecoli value is 1
Well3 alert, acidity value is 1
Well1 alert, lead value is 12
Well1 alert, ecoli value is 2
Well3 alert, lead value is 10
Well3 alert, acidity value is 10
```
Notice how only those streams that are out of range for the temperature sensor type show output.
Detecting zero tuple counts
At the end of the ConsoleWaterDetector
application is this snippet of code, added after the topology has been submitted:
dp.submit(wellTopology);
while (true) {
MetricRegistry metricRegistry = dp.getServices().getService(MetricRegistry.class);
SortedMap<String, Counter> counters = metricRegistry.getCounters();
Set<Entry<String, Counter>> values = counters.entrySet();
for (Entry<String, Counter> e : values) {
if (e.getValue().getCount() == 0) {
System.out.println("Counter Op:" + e.getKey() + " tuple count: " + e.getValue().getCount());
}
}
Thread.sleep(2000);
}
What this does is get all the counters in the MetricRegistry
class and print out the name of the counter oplet they are monitoring along with the tuple count if it is zero. Here is some sample output:
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_44 has a tuple count of zero!
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_45 has a tuple count of zero!
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_46 has a tuple count of zero!
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_47 has a tuple count of zero!
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_89 has a tuple count of zero!
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_95 has a tuple count of zero!
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_96 has a tuple count of zero!
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_97 has a tuple count of zero!
Counter Op:TupleCounter.quarks.oplet.JOB_0.OP_98 has a tuple count of zero!
To summarize what the application is doing:
- Unions all sensor type readings for a single well.
- Filters all sensor type readings for a single well, passing on an object that only contains tuples for the object that have at least one sensor type with out of range values.
- Splits the object that contained name/value pairs for sensor type and readings into individual sensor types returning only those streams that contain out of range values.
- Outputs to the command line the well id, sensor type and value that is out of range.
- Tags are added at various points in the topology for easier identification of either the well or some out of range condition.
- The topology contains counters to measure tuple counts since
DevelopmentProvider
was used.
- Individual rate meters were placed on well1 and well3's temperature sensors to determine the rate of 'unhealthy' values.
- Prints out the name of the counter oplets whose tuple counts are zero.
Topology graph controls
Now that you have an understanding of what the application is doing, let's look at some of the controls in the console, so we can learn how to monitor the application. Below is a screen shot of the top controls: the controls that affect the Topology Graph.
- Job: A drop down to select which job is being displayed in the Topology Graph. An application can contain multiple jobs.
- State: Hovering over the 'State' icon shows information about the selected job. The current and next states of the job, the job id and the job name.
- View by: This select is used to change how the topology graph is displayed. The three options for this select are:
- Static flow
- Tuple count
- Oplet kind
- Currently it is set to 'Static flow'. This means the oplets (represented as circles in the topology graph) do not change size, nor do the lines or links (representing the edges of the topology graph) change width or position. The graph is not being refreshed when it is in 'Static flow' mode.
- Refresh interval: Allows the user to select an interval between 3 - 20 seconds to refresh the tuple count values in the graph. Every X seconds the metrics for the topology graph are refreshed. More about metrics a little bit later.
- Pause graph: Stops the refresh interval timer. Once the 'Pause graph' button is clicked, the user must push 'Resume graph' for the graph to be updated, and then refreshed at the interval set in the 'Refresh interval' timer. It can be helpful to pause the graph if multiple oplets are occupying the same area on the graph, and their names become unreadable. Once the graph is paused, the user can drag an oplet off of another oplet to better view the name and see the edge(s) that connect them.
- Show tags: If the checkbox appears in the top controls, it means:
- The 'View by' layer is capable of displaying stream tags.
- The topology currently shown in the topology graph has stream tags associated with it.
- Show all tags: Selecting this checkbox shows all the tags present in the topology. If you want to see only certain tags, uncheck this box and select the button labeled 'Select individual tags ...'. A dialog will appear, and you can select one or all of the tags listed in the dialog which are present in the topology.
The next aspect of the console we'll look at are the popups available when selecting 'View all oplet properties', hovering over an oplet and hovering over an edge (link).
The screen shot below shows the output from clicking on the 'View all oplet properties' link directly below the job selector:
Looking at the sixth line in the table, where the Name is 'OP_5', we can see that the Oplet kind is a Map, a (quarks.oplet.functional.Map), the Tuple count is 0 (this is because the view is in Static flow mode - the graph does not show the number of tuples flowing in it), the source oplet is 'OP_55', the target oplet is 'OP_60', and there are no stream tags coming from the source or target streams. Relationships for all oplets can be viewed in this manner.
Now, looking at the graph, if we want to see the relationships for a single oplet, we can hover over it. The image below shows the hover when we are over 'OP_5'.
You can also hover over the edges of the topology graph to get information. Hover over the edge (link) between 'OP_0' and 'OP_55'. The image shows the name and kind of the oplet as the source, and the name and kind of oplet as the target. Again the tuple count is 0 since this is the 'Static flow' view. The last item of information in the tooltip is the tags on the stream.
One or many tags can be added to a stream. In this case we see the tags 'temperature' and 'well1'.
The section of the code that adds the tags 'temperature' and 'well1' is in the waterDetector
method of the ConsoleWaterDetector
class.
public static TStream<JsonObject> waterDetector(Topology topology, int wellId) {
Random rNum = new Random();
TStream<Integer> temp = topology.poll(() -> rNum.nextInt(TEMP_RANDOM_HIGH - TEMP_RANDOM_LOW) + TEMP_RANDOM_LOW, 1, TimeUnit.SECONDS);
TStream<Integer> acidity = topology.poll(() -> rNum.nextInt(ACIDITY_RANDOM_HIGH - ACIDITY_RANDOM_LOW) + ACIDITY_RANDOM_LOW, 1, TimeUnit.SECONDS);
TStream<Integer> ecoli = topology.poll(() -> rNum.nextInt(ECOLI_RANDOM_HIGH - ECOLI_RANDOM_LOW) + ECOLI_RANDOM_LOW, 1, TimeUnit.SECONDS);
TStream<Integer> lead = topology.poll(() -> rNum.nextInt(LEAD_RANDOM_HIGH - LEAD_RANDOM_LOW) + LEAD_RANDOM_LOW, 1, TimeUnit.SECONDS);
TStream<Integer> id = topology.poll(() -> wellId, 1, TimeUnit.SECONDS);
// add tags to each sensor
temp.tag("temperature", "well" + wellId);
Legend
The legend(s) that appear in the console depend on the view currently displayed. In the static flow mode, if no stream tags are present, there is no legend. In this example we have stream tags in the topology, so the static flow mode gives us the option to select 'Show tags'. If selected, the result is the addition of the Stream tags legend:
This legend shows all the tags that have been added to the topology, regardless of whether or not 'Show all tags' is checked or specific tags have been selected from the dialog that appears when the 'Select individual tags ...' button is clicked.
Topology graph
Now that we've covered most of the ways to modify the view of the topology graph and discussed the application, let's look at the topology graph as a way to understand our application.
When analyzing what is happening in your application, here are some ways you might use the console to help you understand it:
- Topology of the application - how the edges and vertices of the graph are related
- Tuple flow - tuple counts since the application was started
- The affect of filters or maps on the downstream streams
- Stream tags - if tags are added dynamically based on a condition, where the streams with tags are displayed in the topology
Let's start with the static flow view of the topology. We can look at the graph, and we can also hover over any of the oplets or streams to better understand the connections. Also, we can click 'View all oplet properties' and see the relationships in a tabular format.
The other thing to notice in the static flow view are the tags. Look for any colored edges (the links between the oplets).
All of the left-most oplets have streams with tags. Most of them have the color that corresponds to 'Multiple tags'. If you hover over the edges, you can see the tags. It's obvious that we have tagged each sensor with the sensor type and the well id.
Now, if you look to the far right, you can see more tags on streams coming out of a split
oplet. They also have multiple tags, and hovering over them you can determine that they represent out of range values for each sensor type for the well. Notice how the split
oplet, OP_43, has no tags in the streams coming out of it. If you follow that split oplet back, you can determine from the first tags that it is part of the well 2 stream.
If you refer back to the ConsoleWaterDetector
source, you can see that no tags were placed on the streams coming out of well2's split because they contained no out of range values.
Let's switch the view to Oplet kind now. It will make more clear which oplets are producing the streams with the tags on them.
Below is an image of how the graph looks after switching to the Oplet kind view.
In the Oplet kind view the links are all the same width, but the circles representing the oplets are sized according to tuple flow. Notice how the circles representing OP_10, OP_32 and OP_21 are large in relation to OP_80, OP_88 and OP_89. As a matter of fact, we can't even see the circle representing OP_89. Looking at OP_35 and then the Oplet kind legend, you can see by the color that it is a Filter oplet. This is because the filter that we used against well2, which is the stream that OP_35 is part of returned no tuples. This is a bit difficult to see. Let's look at the Tuple count view.
The Tuple count view will make it more clear that no tuples are following out of OP_35, which represents the filter for well2 and only returns out of range values. You may recall that in this example well2 returned no out of range values. Below is the screen shot of the graph in 'Tuple count' view mode.
The topology graph oplets can sometimes sit on top of each other. If this is the case, pause the refresh and use your mouse to pull down on the oplets that are in the same position. This will allow you to see their name. Alternately, you can use the 'View all properties' table to see the relationships between oplets.
Metrics
If you scroll the browser window down, you can see a Metrics section. This section appears when the application contains the following:
- A
DevelopmentProvider
is used; this automatically inserts counters on the streams of the topology.
- A
quarks.metrics.Metric.Counter
or quarks.metrics.Metric.RateMeter
is added to an individual stream.
Counters
In the ConsoleWaterDetector
application we used a DevelopmentProvider
. Therefore, counters were added to most streams (edges) with the following exceptions (from the javadoc for quarks.metrics.Metric.Counter
):
Oplets are only inserted upstream from a FanOut oplet.
If a chain of Peek oplets exists between oplets A and B, a Metric oplet is inserted after the last Peek, right upstream from oplet B.
If a chain of Peek oplets is followed by a FanOut, a metric oplet is inserted between the last Peek and the FanOut oplet.
The implementation is not idempotent; previously inserted metric oplets are treated as regular graph vertices. Calling the method twice will insert a new set of metric oplets into the graph.
Also, the application inserts counters on well2's streams after the streams from the individual sensors were unioned and then split:
List<TStream<JsonObject>> individualAlerts2 = splitAlert(filteredReadings2, 2);
TStream<JsonObject> alert0Well2 = individualAlerts2.get(0);
alert0Well2 = Metrics.counter(alert0Well2);
alert0Well2.tag("well2", "temp");
TStream<JsonObject> alert1Well2 = individualAlerts2.get(1);
alert1Well2 = Metrics.counter(alert1Well2);
alert1Well2.tag("well2", "acidity");
TStream<JsonObject> alert2Well2 = individualAlerts2.get(2);
alert2Well2 = Metrics.counter(alert2Well2);
alert2Well2.tag("well2", "ecoli");
TStream<JsonObject> alert3Well2 = individualAlerts2.get(3);
alert3Well2 = Metrics.counter(alert3Well2);
alert3Well2.tag("well2", "lead");
When looking at the select next to the label 'Metrics', make sure the 'Count, oplets OP_37, OP_49 ...' is selected. This select compares all of the counters in the topology visualized as a bar graph. An image is shown below:
Hover over individual bars to get the value of the number of tuples flowing through that oplet since the application was started. You can also see the oplet name. You can see that some of the oplets have zero tuples flowing through them.
The bars that are the tallest and therefore have the highest tuple count are OP_76, OP_67 and OP_65. If you look back up to the topology graph, in the Tuple count view, you can see that the edges (streams) surrounding these oplets have the color that corresponds to the highest tuple count (in the pictures above that color is bright orange in the Tuple count legend).
RateMeters
The other type of metric we can look at are RateMeter
metrics. In the ConsoleWaterDetector
application we added two rate meters here with the objective of comparing the rate of out of range readings between well1 and well3:
List<TStream<JsonObject>> individualAlerts1 = splitAlert(filteredReadings1, 1);
// Put a rate meter on well1's temperature sensor output
Metrics.rateMeter(individualAlerts1.get(0));
...
List<TStream<JsonObject>> individualAlerts3 = splitAlert(filteredReadings3, 3);
// Put a rate meter on well3's temperature sensor output
Metrics.rateMeter(individualAlerts3.get(0));
RateMeters contain the following metrics for each stream they are added to:
- Tuple count
- The rate of change in the tuple count. The following rates are available for a single stream:
- 1 minute rate change
- 5 minute rate change
- 15 minute rate change
- Mean rate change
Now change the Metrics select to the 'MeanRate'. In our example these correspond to oplets OP_37 and OP_49:
Hovering over the slightly larger bar, the one to the right, the name is OP_49. Looking at the topology graph and changing the view to 'Static flow', follow the edges back from OP_49 until you can see an edge with a tag on it. You can see that OP_49's source is OP_51, whose source is OP_99. The edge between OP_99 and it's source OP_48 has multiple tags. Hovering over this stream, the tags are 'TEMP out of range' and 'well3'.
If a single Rate Meter is placed on a stream, in addition to plotting a bar chart, a line chart over the last 20 measures can be viewed. For example, if I comment out the addition of the rateMeter for well1 and then rerun the application, the Metrics section will look like the image below. I selected the OneMinuteRate and 'Line chart' for Chart type:
Summary
The intent of the information on this page is to help you understand the following:
- How to add the console application to a Quarks application
- How to run the
ConsoleWaterDetector
sample
- The design/architecture in the
ConsoleWaterDetector
application
- The controls for the Topology graph are and what they do, including the different views of the graph
- The legend for the graph
- How to interpret the graph and use the tooltips over the edges and vertices, as well as the 'View all properties' link
- How to add counters and rate meters to a topology
- How to use the metrics section to understand tuple counters and rate meters
- How to correlate values from the metrics section with the topology graph
The Quarks console will continue to evolve and improve. Please open an issue if you see a problem with the existing console, but more importantly add an issue if you have an idea of how to make the console better.
The more folks write Quarks applications and view them in the console, the more information we can gather from the community about what is needed in the console. Please consider making a contribution if there is a feature in the console that would really help you and others!


Health, education and care services legally required to work together
Parents are to get a new legal right to buy in specialist special educational needs (SEN) and disabled care for their children, under plans set out today by Children’s Minister Sarah Teather.
For the first time ever, parents will be given the power to control personal budgets for their children with severe, profound or multiple health and learning - meaning they can choose the expert support that is right for their child, instead of local authorities (LAs) being the sole provider.
The biggest reform of SEN for 30 years will also force education, health and social care services to plan services together by law - so when their children are assessed, parents will be assured they will get full provision to address their children’s needs.
Often it is not clear to parents, and to local services, who is responsible for delivering on the statement of special needs. Services such as speech and language therapy may appear in the statement but are funded and commissioned by local health services.
Sarah Teather said that would stop the ‘agonising’ battle many parents fight to get the support for their families, as they are forced to go from ‘pillar to post’ between different authorities and agencies.
She said it would end the delays children face by undergoing multiple check-ups over many months, sweeping away the current outdated, slow and complex system.
The reforms are set out in the Government’s formal response to the public consultation on its green paper, Support and Aspiration published today.
The main elements are:
-
Replacing SEN statements and separate learning difficulty assessments (for older children) with a single, simpler birth to 25 years assessment process and education, health and care plan from 2014. Parents with the plans would have the right to a personal budget for their support.
-
Providing statutory protections comparable to those currently associated with a statement of SEN to up to 25-years-old in further education - instead of there being a ‘cliff edge’ when it is cut off at 16, to help young people into employment and independent living.
-
LAs and health services will be required to link up services for disabled children and young people - so they are jointly planned and commissioned.
-
Requiring LAs to publish a local offer showing the support available to disabled children and young people and those with SEN, and their families.
-
Introducing mediation for disputes and trialling giving children the right to appeal if they are unhappy with their support.
-
Children would have a new legal right to seek a place at state academies and Free Schools - currently it is limited to maintained mainstream and special schools. LAs would have to name the parent’s preferred school so long it was suitable for the child.
The consultation had a huge response - with around 2,400 formal responses giving broad support for the reforms. The changes are already being piloted in 20 local pathfinders. The interim evaluation reports are due in summer and late autumn this year with a final report in 2013.
The Children and Families Bill announced in last week’s Queen’s Speech will now put legislation in place for the reforms.
Children’s Minister Sarah Teather said:
The current system is outdated and not fit for purpose. Thousands of families have had to battle for months, even years, with different agencies to get the specialist care their children need. It is unacceptable they are forced to go from pillar to post, facing agonising delays and bureaucracy to get support, therapy and equipment.
These reforms will put parents in charge. We trust parents to do the right thing for their own child because they know what is best. The right to a personal budget will give them real choice and control of care, instead of councils and health services dictating how they get support.
It is a huge step forward to require health, education and care services work together. The reforms will give parents better information and a comprehensive package of support that meets their needs.
Christine Lenehan, Director of the Council for Disabled Children, the Government’s strategic partner on its SEN reforms, said:
We are delighted that the Government continues to support disabled children and those with special educational needs. Tackling the battleground for families by ensuring joined-up local services and clear local information is to be warmly welcomed.
The green paper response also confirms a £3 million supported internships trial will be launched in 15 further education colleges this autumn, for 16- to 25-year-olds with the most complex learning difficulties or disabilities; and the possibility for all colleges to offer supported internships from September 2013.
The programme will provide structured study, based at an employer, which is tailored to the individual needs of the young person and will equip them with the skills they need for the workplace. This will include on-the-job training, backed by expert ‘job coaches’ to support interns and employers, and the chance to study for relevant qualifications - where appropriate.
Notes to editors
-
Today’s response and next steps document to the
Support and Aspiration green paper
is published
-
The
green paper
was published and consulted in March 2011.
-
The Government is piloting the reforms in 20 pathfinders, covering 31 LAs. It
announced the details
in September 2011.
-
The interim evaluation will be published in autumn 2012 and final evaluation in 2013. The work of the pathfinders will continue to inform the changes we make to legislation through the Bill.
-
The
Children and Families Bill
announced in the Queen’s Speech set out legislation to transform the SEN system.
-
The Bill’s SEN provisions will apply to England.
-
The key measures set out in today’s next steps document are:
-
Education, health and care plans: SEN statements (for under 16s) and learning difficulty assessments (for over 16s) will be replaced with a single, integrated education, health and care plan from 2014 from birth to 25 years. This means that children, young people and families will have a single assessment process, covering education, health and care, and ensuring that families have confidence that all of the different local agencies - across education, health and social care are working to together to meet their needs. This will stop parents having to have to undergo repeated assessments with different agencies. It will end the dramatic ‘cliff edge’ young people face when they leave school at 16 or 18, losing statutory rights when SEN statements stop and triggering a completely new reassessment which carries far less protection.
-
Personal budgets: all families with an approved education, health and care plan will have a legal right to request a personal budget, if they choose. Parents can directly buy in the support identified in the plan - currently they rely on LAs and other services to pay for services. Parents will be given a choice of whether to take control of the personal budget by agencies managing the funds on their behalf or, where appropriate, by receiving direct payments, if they are suitable, to purchase and manage the provision themselves.
-
Joint commissioning: LAs and clinical commissioning groups would have to put arrangements in place to ensure that services for disabled children and young people, and those with SEN are planned and commissioned jointly. This would help ensure that agencies work together to agree the best package of support as well as avoiding lengthy disputes over who should pay for services. The Department of Health will, subject to consultation, use the mandate to the NHS Commissioning Board to ensure that the NHS commissioning system and, in particular, clinical commissioning groups, are focused on improved outcomes for disabled children and those with SEN.
-
School choice: parents whose children have an education, health and care plan would have the legal right to seek a place at any state-funded school of their choice - whether maintained, academy, Free School or special. LAs would have to name the parent’s preferred school so long it was suitable for the child, did not prejudice the education of other children or did not mean an inefficient use of funds.
-
Local offer: all LAs would publish a ‘local offer’ of support, so parents would know exactly what is available instead of having to fight for basic information. It is envisaged that all parents would be given details of: early years, school and colleges provision and transport to and from it; social care services available, including short breaks; health services, including speech and language therapy; how to access specialist support; and special and specialist school provision available - including training providers and apprenticeships.
-
Mediation and the tribunal and children’s right to appeal to a tribunal: introducing mediation before Tribunal for disputes and trialling giving children the right to appeal if they are unhappy with their support.
-
Ofsted reported in September 2010
that many children, particularly those in the school action category, were wrongly identified as having SEN when their needs were capable of being met from good teaching and pastoral support.
We propose to introduce a new single category of SEN to make sure the right support to raise attainment is given to the right children - replace the existing complicated school action and school action plus systems and we will provide tighter guidance on which children should be identified as having SEN.
To support schools we have made the highly successful Achievement for All model available to any school that wants it. 780 schools are involved in the programme and a Quality Mark has been developed and awarded to 164 schools, to recognise excellence in schools that improve outcomes for pupils who have SEN or are disabled.


Methods
-
downloadRenderedOutput(obj)
-
downloads preview pane as flat html file
Parameters:
Name Type Description obj
object a way to pass the current manuscript instance object
- Source:
-
saveManuscriptFile(obj)
-
save manuscript file, overwriteable for other save options like wordpress or periodic
Parameters:
Name Type Description obj
object a way to pass the current manuscript instance object
- Source: