Generic pipeline
Reasons to use Generic Pipeline
Generic Pipeline was developed with a focus of enabling to make fast and simply-declared experiments, which can be easily stored, reproduced and compared to each other.
It provides the following features:
- Allows to describe experiments in a compact and expressive way
- Provides a way to store and compare experiments in order to methodically find the best deap learning solution
- Easy to share experiments and their results to work in a team
- Experiment configurations are separated from model definitions
- Allows to define custom neural networks in a declarative style, by building it from blocks
- Provides great flexibility and extensibility via support of custom substances
- Common blocks like an architecture, callbacks, model metrics, predictions vizualizers and others should be written once and be a part of a common library
All experiments are declared in YAML dialect with lots of defaults, allowing to describe an initial experiment in several lines and then set more details if needed.
Here is a relatively complex example, most of the statements can be omitted:
imports: [ layers, preprocessors ]
declarations:
collapseConv:
parameters: [ filters,size, pool]
body:
- conv1d: [filters,size,relu ]
- conv1d: [filters,size,relu ]
- batchNormalization: {}
- collapse: pool
net:
- repeat(2):
- collapseConv: [ 20, 7, 10 ]
- cudnnlstm: [40, true ]
- cudnnlstm: [40, true ]
- attention: 718
- dense: [3, sigmoid]
preprocess:
- rescale: 10
- get_delta_from_average
- cache
preprocessing: preprocess
testSplit: 0.4
architecture: net
optimizer: Adam #Adam optimizer is a good default choice
batch: 12 #Our batch size will be 16
metrics: #We would like to track some metrics
- binary_accuracy
- matthews_correlation
primary_metric: val_binary_accuracy #and the most interesting metric is val_binary_accuracy
callbacks: #Let's configure some minimal callbacks
EarlyStopping:
patience: 100
monitor: val_binary_accuracy
verbose: 1
ReduceLROnPlateau:
patience: 8
factor: 0.5
monitor: val_binary_accuracy
mode: auto
cooldown: 5
verbose: 1
loss: binary_crossentropy #We use simple binary_crossentropy loss
stages:
- epochs: 100 #Let's go for 100 epochs
- epochs: 100 #Let's go for 100 epochs
- epochs: 100 #Let's go for 100 epochs
Installation
Prerequisites
The package has many prerequisites, but some of them are recommended to be installed manually.
Tensorflow package of versions of 1.14 and below split into CPU and GPU ones. Moreover, Tensorflow may be more or less compatible with the version of CUDA/CUDNN installed.
Here is the repository containing lots of pre-built Tensorflow wheels for Windows: tensorflow-windows-wheel. It can be used to choose the wheel depending on system architecture, CUDA/CUDNN version, CPU/GPU and Python version.
Read more in Tensorflow installation guide.
Keras has no strong dependency on Tensorflow, but in our common setup they run in pair. We used the 2.2.4 one.
Shapely requires compilation on install on Linux/MacOS or pre-built version on Windows. Here are the pre-built Shapely wheels for Windows.
Choosing your installation type
It is recommended to install to a virtual environment in order to avoid dependency version conflicts.
Global pip installation
Install Tensorflow, Keras and Shapely as described in pre-requisites.
In example, if you have downloaded particular
Tensorflow wheel into C:\downloads\tensorflow_gpu-1.12.0-cp36-cp36m-win_amd64.whl
and particular Shapely wheel into C:\downloads\Shapely-1.6.4.post1-cp36-cp36m-win_amd64.whl
, run:
pip install C:\downloads\tensorflow_gpu-1.12.0-cp36-cp36m-win_amd64.whl
pip install Keras==2.2.4
pip install C:\downloads\Shapely-1.6.4.post1-cp36-cp36m-win_amd64.whl
pip install musket_ml
Virtual environment installation (recommended)
virtualenv installation (recommended)
This type of installation uses virtualenv manager for creating your virtual environment.
Create a new virtual environment:
virtualenv ./musket
This will create musket
folder and place a copy of your python, pip and wheel inside.
Activate the new virtual environment:
On Posix systems:
source ./musket/bin/activate
On Windows:
.\musket\Scripts\activate
Install Tensorflow, Keras and Shapely as described in pre-requisites.
In example, if you have downloaded particular
Tensorflow wheel into C:\downloads\tensorflow_gpu-1.12.0-cp36-cp36m-win_amd64.whl
and particular Shapely wheel into C:\downloads\Shapely-1.6.4.post1-cp36-cp36m-win_amd64.whl
, run:
pip install C:\downloads\tensorflow_gpu-1.12.0-cp36-cp36m-win_amd64.whl
pip install Keras==2.2.4
pip install C:\downloads\Shapely-1.6.4.post1-cp36-cp36m-win_amd64.whl
Now install musket:
pip install musket_ml
Experiment launches and other activity should be performed when this environment is activated.
When you are done working with musket, you can deactivate the environment by launching:
virtualenv deactivate
pipenv installation
This type of installation uses pipenv manager for creating your virtual environment.
Install pipenv if needed:
pip install --user pipenv
Create new environment by launching:
mkdir musket
cd musket
pipenv --python 3.6
Install Tensorflow, Keras and Shapely as described in pre-requisites.
In example, if you have downloaded particular
Tensorflow wheel into C:\downloads\tensorflow_gpu-1.12.0-cp36-cp36m-win_amd64.whl
and particular Shapely wheel into C:\downloads\Shapely-1.6.4.post1-cp36-cp36m-win_amd64.whl
, run:
pipenv install C:\downloads\tensorflow_gpu-1.12.0-cp36-cp36m-win_amd64.whl
pipenv install Keras==2.2.4
pipenv install C:\downloads\Shapely-1.6.4.post1-cp36-cp36m-win_amd64.whl
Now install musket:
pipenv install musket_ml
Experiment launches and other activity should be performed when this environment is activated or using pipenv.
So, the first approach is to activate the environment by launching
pipenv shell
while inside musket
folder.
Or, alternativelly, prefix all experiment management commands with
pipenv run
,
in example, instead of running
musket fit --project "D:\work\salt" --name "exp01" --num_gpus=1 --gpus_per_net=1 --num_workers=1 --cache "D:\work\salt\data\cache"
run
pipenv run musket fit --project "D:\work\salt" --name "exp01" --num_gpus=1 --gpus_per_net=1 --num_workers=1 --cache "D:\work\salt\data\cache"
Other packages
musket_ml
joins all mainstream pipelines that belong to Musket-ML framework.
In particular, besides musket_core
generic pipeline, it includes
classification_pipeline
classification pipeline,
segmentation_pipeline
segmentation pipeline
and musket_text
text support.
To install only the generic pipeline, follow the same instructions,
but use musket_core
wheel instead of musket_ml
.
Project structure
Each experiment is simply a folder with YAML file inside, it is easy to store and run experiment.
Project is a folder with the following structure inside:
- project_name
- experiments
- experiment1
- config.yaml
- experiment2
- config.yaml
- summary.yaml
- metrics
- metrics-0.0.csv
- metrics-1.0.csv
- metrics-2.0.csv
- metrics-3.0.csv
- metrics-4.0.csv
- modules
- main.py
- arbitrary_module.py
- common.yaml
The only required part is experiments
folder with at least one arbitrary-named experiment subfolder having config.yaml
file inside.
Each experiment starts with its configuration, other files are being added by the pipeline during th training.
common.yaml
file may be added to set instructions, which will be applied to all project experiments.
modules
folder may be added to set python files in project scope, so custom yaml declarations can be mapped
onto python classes and functions defined inside such files. all modules in this folder will be always executed, other modules require imports instruction.
summary.yaml
and metrics
folders inside each experiment appear after the experiment training is executed.
There are more potential files, like intermediate results cache files etc.
Launching
Launching experiments
fit.py
script is designed to launch experiment training.
In order to run the experiment or a number of experiments,
A typical command line may look like this:
musket fit --project "path/to/project" --name "experiment_name" --num_gpus=1 --gpus_per_net=1 --num_workers=1 --cache "path/to/cache/folder"
--project points to the root of the project
--name is the name of the project sub-folder containing experiment yaml file.
--num_gpus sets number of GPUs to use during experiment launch.
--gpus_per_net is a maximum number of GPUs to use per single experiment.
--num_workers sets number of workers to use.
--cache points to a cache folder to store the temporary data.
Other parameters can be found in the fit script reference
Launching tasks
task.py
script is designed to launch experiment training.
Tasks must be defined in the project python scope and marked by an annotation like this:
from musket_core import tasks, model
@tasks.task
def measure2(m: model.ConnectedModel):
return result
In order to run the experiment or a number of experiments,
A typical command line may look like this:
python -m musket_core.task --project "path/to/project" --name "experiment_name" --task "task_name" --num_gpus=1 --gpus_per_net=1 --num_workers=1 --cache "path/to/cache/folder"
--project points to the root of the project
--name is the name of the project sub-folder containing experiment yaml file.
--task is the name of the task function.
--num_gpus sets number of GPUs to use during experiment launch.
--gpus_per_net is a maximum number of GPUs to use per single experiment.
--num_workers sets number of workers to use.
--cache points to a cache folder to store the temporary data.
Other parameters can be found in the task script reference
Launching project analysis
analize.py
script is designed to launch project-scope analysis.
Note that only experiments, which training is already finished will be covered.
musket analize --inputFolder "path/to/project"
--inputFolder points to a folder to search for finished experiments in. Typically, project root.
Other parameters can be found in the analyze script reference
General train properties
Lets take our standard example and check the following set of instructions:
imports: [ layers, preprocessors ]
testSplit: 0.4
optimizer: Adam #Adam optimizer is a good default choice
batch: 12 #Our batch size will be 16
metrics: #We would like to track some metrics
- binary_accuracy
- matthews_correlation
primary_metric: val_binary_accuracy #and the most interesting metric is val_binary_accuracy
loss: binary_crossentropy #We use simple binary_crossentropy loss
imports imports python files that are not located in modules
folder of the project and make their properly annotated contents to be available to be referred from YAML. Files from the modules folder are imported automatically
testSplit Splits the train set into two parts, using one part for train and leaving the other untouched for a later testing. The split is shuffled.
optimizer sets the optimizer.
batch sets the training batch size.
metrics sets the metrics to track during the training process. Metric calculation results will be printed in the console and to metrics
folder of the experiment.
primary_metric Metric to track during the training process. Metric calculation results will be printed in the console and to metrics
folder of the experiment.
Besides tracking, this metric will be also used by default for metric-related activity, in example, for decision regarding which epoch results are better.
loss sets the loss function. if your network has multiple outputs, you also may pass a list of loss functions (one per output)
Framework supports composing loss as a weighted sum of predefined loss functions. For example, following construction
loss: binary_crossentropy+0.1*dice_loss
will result in loss function which is composed from binary_crossentropy
and dice_loss
functions.
There are many more properties to check in Reference of root properties
Definining networks
Lets check the next part of our example:
declarations:
collapseConv:
parameters: [ filters,size, pool]
body:
- conv1d: [filters,size,relu ]
- conv1d: [filters,size,relu ]
- batchNormalization: {}
- collapse: pool
net:
- repeat(2):
- collapseConv: [ 20, 7, 10 ]
- cudnnlstm: [40, true ]
- cudnnlstm: [40, true ]
- attention: 718
- dense: [3, sigmoid]
architecture: net
Here, declarations
instruction set up network blocks collapseConv
and net
.
collapseConv
block defines its input parameters (those are YAML-level parameters, not actual network tensors),
and body
defines the sub-blocks of the block.
net
block has no parameters, so its sub-blocks come right inside the net
.
Following are built-in layers used inside both blocks:
And data / control-flow instructions:
Also, net
block uses collapseConv
block by stating collapseConv: [ 20, 7, 10 ]
, where collapseConv
ordered parameters [ 20, 7, 10 ]
come in YAML array.
architecture instruction sets net
block as the entry point for the whole experiment.
Built-in NN layers
There are a lot of built-in NN layers, basically, we support all layers that are supported by Keras.
Here are just a few:
More can be found here: Layer types
Control layers
Utility layers can be used to set control and data flow inside their bodies. Here are some examples:
Simple Data Flow constructions
inceptionBlock:
parameters: [channels]
with:
padding: same
body:
- split-concatenate:
- Conv2D: [channels,1]
- seq:
- Conv2D: [channels*3,1]
- Conv2D: [channels,3]
- seq:
- Conv2D: [channels*4,1]
- Conv2D: [channels,1]
- seq:
- Conv2D: [channels,2]
- Conv2D: [channels,1]
Repeat and With
declarations:
convBlock:
parameters: [channels]
with:
padding: same
body:
- repeat(5):
- Conv2D: [channels*_,1]
net:
- convBlock: [120]
Conditional layers
declarations:
c2d:
parameters: [size, pool,mp]
body:
- Conv1D: [100,size,relu]
- Conv1D: [100,size,relu]
- Conv1D: [100,size,relu]
- if(mp):
MaxPool1D: pool
net:
- c2d: [4,4,False]
- c2d: [4,4,True]
- Dense: [4, sigmoid]
Shared Weights
#Basic example with sequencial model
declarations:
convBlock:
parameters: [channels]
shared: true
with:
padding: same
body:
- Conv2D: [channels,1]
- Conv2D: [channels,1]
net:
- convBlock: [3] #weights of convBlock will be shared between invocations
- convBlock: [3] #weights of convBlock will be shared between invocations
Wrapper layers
net:
#- gaussianNoise: 0.0001
#- collapseConv: [ 20, 7, 10 ]
#- collapseConv: [ 20, 7, 10 ]
- bidirectional:
- cudnnlstm: [30, true ]
- bidirectional:
- cudnnlstm: [50, true ]
- attention: 200
- dense: [64, relu]
- dense: [3, sigmoid]
Manually controlling data flow
net:
inputs: [i1,i2]
outputs: [d1,d2]
body:
- c2d:
args: [4,4]
name: o1
inputs: i1
- c2d:
args: [4,4]
name: o2
inputs: i2
- dense:
units: 4
activation: sigmoid
inputs: o1
name: d1
- dense:
units: 4
activation: sigmoid
inputs: o2
name: d2
Full list can be found here
Datasets
Datasets allow to define the ways to load data for this particular project. As this pipeline is designed to support an arbitrary data, the only way to add dataset is to put in some custom python code and then refer it from YAML:
class DischargeData(datasets.DataSet):
def __init__(self,ids,normalize=True, flatten=False):
self.normalize=normalize
self.flatten = flatten
self.cache={}
self.ids=list(set(list(ids)))
def __getitem__(self, item):
item=self.ids[item]
if item in self.cache:
return self.cache[item]
ps= PredictionItem(item,getX(item,self.normalize),getY(item,self.flatten))
#self.cache[item]=ps
return ps
def __len__(self):
return len(self.ids)
def getTrain(normalize=True,flatten=False)->datasets.DataSet:
return DischargeData(ids,normalize,flatten)
def getTest(normalize=True,flatten=False)->datasets.DataSet:
return DischargeData(test_ids,normalize,flatten)
Now, if this python code sits somewhere in python files located in modules
folder of the project, and that file is referred by imports instruction, following YAML can refer it:
dataset:
getTrain: [false,false]
datasets:
test:
getTest: [false,false]
dataset sets the main training dataset.
datasets sets up a list of available data sets to be referred by other entities.
Callbacks
Lets check the following block from out main example:
callbacks: #Let's configure some minimal callbacks
EarlyStopping:
patience: 100
monitor: val_binary_accuracy
verbose: 1
ReduceLROnPlateau:
patience: 8
factor: 0.5
monitor: val_binary_accuracy
mode: auto
cooldown: 5
verbose: 1
We set up two callback, which are being invoked during the training time:
EarlyStopping that monitors metrics and stops training if results doesnt get better, and val_binary_accuracy
and ReduceLROnPlateau, which reduces learning rate for the same reason.
The list of callbacks can be found here
Stages
Sometimes you need to split your training into several stages. You can easily do it by adding several stage entries in your experiment configuration file.
stages instruction allows to set up stages of the train process, where for each stage it is possible to set some specific training options like the number of epochs, learning rate, loss, callbacks, etc. Full list of stage properties can be found here.
stages:
- epochs: 100 #Let's go for 100 epochs
- epochs: 100 #Let's go for 100 epochs
- epochs: 100 #Let's go for 100 epochs
stages:
- epochs: 6 #Train for 6 epochs
negatives: none #do not include negative examples in your training set
validation_negatives: real #validation should contain all negative examples
- lr: 0.0001 #let's use different starting learning rate
epochs: 6
negatives: real
validation_negatives: real
- loss: lovasz_loss #let's override loss function
lr: 0.00001
epochs: 6
initial_weights: ./fpn-resnext2/weights/best-0.1.weights #let's load weights from this file
Balancing your data
One common case is the situation when part of your images does not contain any objects of interest, like in Airbus ship detection challenge. More over your data may be to heavily inbalanced, so you may want to rebalance it. Alternatively you may want to inject some additional images that do not contain objects of interest to decrease amount of false positives that will be produced by the framework.
These scenarios are supported by negatives and validation_negatives settings of training stage configuration, these settings accept following values:
- none - exclude negative examples from the data
- real - include all negative examples
- integer number(1 or 2 or anything), how many negative examples should be included per one positive example
stages:
- epochs: 6 #Train for 6 epochs
negatives: none #do not include negative examples in your training set
validation_negatives: real #validation should contain all negative examples
- lr: 0.0001 #let's use different starting learning rate
epochs: 6
negatives: real
validation_negatives: real
- loss: lovasz_loss #let's override loss function
lr: 0.00001
epochs: 6
initial_weights: ./fpn-resnext2/weights/best-0.1.weights #let's load weights from this file
if you are using this setting your dataset class must support isPositive
method which returns true for indexes
which contain positive examples:
def isPositive(self, item):
pixels=self.ddd.get_group(self.ids[item])["EncodedPixels"]
for mask in pixels:
if isinstance(mask, str):
return True;
return False
Advanced learning rates
Dynamic learning rates
As told in Cyclical learning rates for training neural networks CLR policies can provide quicker converge for some neural network tasks and architectures.
We support them by adopting Brad Kenstler CLR callback for Keras.
If you want to use them, just add CyclicLR in your experiment configuration file as shown below:
callbacks:
EarlyStopping:
patience: 40
monitor: val_binary_accuracy
verbose: 1
CyclicLR:
base_lr: 0.0001
max_lr: 0.01
mode: triangular2
step_size: 300
There are also ReduceLROnPlateau and LRVariator options to modify learning rate on the fly.
LR Finder
Estimating optimal learning rate for your model is an important thing, we support this by using slightly changed version of Pavel Surmenok - Keras LR Finder
cfg= segmentation.parse(people-1.yaml)
ds=SimplePNGMaskDataSet("./train","./train_mask")
finder=cfg.lr_find(ds,start_lr=0.00001,end_lr=1,epochs=5)
finder.plot_loss(n_skip_beginning=20, n_skip_end=5)
plt.show()
finder.plot_loss_change(sma=20, n_skip_beginning=20, n_skip_end=5, y_lim=(-0.01, 0.01))
plt.show()
will result in this couple of helpful images:
Preprocessors
Preprocessors are the custom python functions that transform dataset.
Such functions should be defined in python files that are in a project scope (modules
) folder and imported.
Preprocessing functions should be also marked with @preprocessing.dataset_preprocessor
annotation.
preprocess instruction then can be used to chain preprocessors as needed for this particular experiment, and even cache the result on disk to be reused between experiments.
preprocess:
- rescale: 10
- get_delta_from_average
- disk-cache
import numpy as np
from musket_core import preprocessing
def moving_average(input, n=1000) :
ret = np.cumsum(input, dtype=float, axis=0)
ret[n:] = ret[n:] - ret[:-n]
ret[0:n] = ret[-n:]
return ret / n
@preprocessing.dataset_preprocessor
def get_delta_from_average(input):
m = moving_average(input[:, :])
m1 = moving_average(input[:, :],100)
#m2 = moving_average(input[:, :], 10000)
d = input[:, :] - m
d1 = input[:, :] - m1
#d2 = input[:, :] - m2
input=input/input.max()
d1 = d1 / d1.max()
# d2 = d2 / d2.max()
d = d / d.max()
return np.concatenate([d,d1,input])
@preprocessing.dataset_preprocessor
def rescale(input,size):
mean=np.mean(np.reshape(input, (input.shape[0] // size ,size, 3)), axis=1)
max=np.max(np.reshape(input, (input.shape[0] // size, size, 3)), axis=1)
min = np.min(np.reshape(input, (input.shape[0] // size, size, 3)), axis=1)
return np.concatenate([mean,max,min])
How to check training results
In experiment folder metrics
subfolder contain a CSV report file for each fold and stage.
summary.yaml
file in the experiment folder contain the statistics for the whole experiment.


Sylvanian Families Slydale Fox Family (Epoch)
UK Biography Information
Father Slick Slydale is a mine of information and very clever. He'll know the answer to any question you ask him.
Mother Velvette Slydale is always on the lookout for a bargain. She has been known to travel for miles and miles and queue for hours and hours just for the spring sales.
Brother Buster Slydale is a real handful. Everyone says his middle name is trouble. He's not a bad boy, he's just a bit wayward and naughty.
Sister Scarlet Slydale spends hours brushing her tail and is very proud of its glossy, healthy condition.


Symbol Index for "Instantiated Activity"
Symbol Index for diagram
"Instantiated Activity"
Abandoned Activity (Class)
Activity State (Class)
Activity To Be Done (Class)
Activity Under Consideration (Class)
Activity/State (Generalization Node)
Completed Activity (Class)
Decomposed Activity (Class)
Instantiated Activity (Class)
Not Required Activity (Class)
Performance Rejected Activity (Class)
Performance Suspended Activity (Class)
Performer Accepted Activity (Class)
Performer Rejected Activity (Class)
Performer Selected Activity (Class)
Scheduled Activity (Class)
source for (Association)
Started Activity (Class)


Pizza Nostra
Your Dose of Tasty
Proceed to Order
Today's Flavors
Margherita Pizza
Hawaiian Pizza
Pepperoni Pizza
Pick Your Size
Large $12
Medium $7.5
Small $5
Crusts
Cheese Stuffed
Flatbread
Neapolitan
Get Any Topping For an Additionl 1$
Add Topping
Achovile
Gorgonzola
Potato
First Name
Last Name
Phone Number
Quantity of Order
Preference
Takeaway
Home Delivery
Sit n' Eat
Home Delivery ?
Confirm!


Uh oh! Looks like the Heroku instance is either recharging or has crashed.
If the dyno is recharging it will be available in ~6 hours. If this persists you can contact me via e-mail to get things sorted


Grail is a library which allows test script creation based on steps.
Library usage brings the following benefits to your tests:
The simple test demonstrating basic usage:
from grail import BaseTest, step class MyFirstGrailTest(BaseTest): def test_some_feature(self): self.login_to_application() @step def login_to_application(self): pass
Such test output will be:
PASSED login to application
When step method takes some params or return value: all the information will be logged.
Example:
from grail import BaseTest, step from nose.tools import eq_ class MyLoggingParametersAndOutputTest(BaseTest): def test_some_feature(self): result = self.do_some_calculation(2, second_param=3) self.verify_result(result) @step def do_some_calculation(self, first_param, second_param): return first_param + second_param @step def verify_result(self, actual_data): eq_(actual_data, 5)
Output will contain all execution details:
By default step name is method name split by underscores. In the majority of cases it's enough if you are writing readable code. But there are situations where step description is not so easy to put into method name. For such cases there is a description parameter.
from grail import BaseTest, step class MyTestWithDescription(BaseTest): def test_some_feature(self): self.login_to_application() self.complex_step() @step def login_to_application(self): pass @step(description='Some tricky actions with the application which I can\'t put to method name') def complex_step(self): pass
Such test script will generate the following:
If step method is created but not implemented you can specify pending property. It will fail corresponding test execution but at the same time you can have full test case description (e.g. for manual execution).
Example:
from grail import BaseTest, step class MyNotFinishedTest(BaseTest): def test_some_feature(self): self.first_implemented_step() self.second_pending_step() self.some_third_step() @step def first_implemented_step(self): print 'Some implemented actions' @step(pending=True) def second_pending_step(self): print 'This is not final implementation' @step def some_third_step(self): print 'This step is implemented but will be Ignored and you will not see this message'
Test execution output:
Example below also shows that there is no limitation where you should store your steps. It could be any class method, function. You can also call the same step multiple times.
from grail import BaseTest, step class SomeClassWithSteps(object): @step def step_from_another_class(self): pass @step def some_simple_action_one(): pass class MyTestWithGroup(BaseTest): external_steps = SomeClassWithSteps() def test_some_feature(self): self.complex_step_based_on_other_steps() @step(step_group=True) def complex_step_based_on_other_steps(self): self.external_steps.step_from_another_class() some_simple_action_one() self.external_steps.step_from_another_class()
The output:
There are cases when you want to format your step description special way:
If you want to do this you should set format_description=True. In this case description.format(*args, **kwargs) will be used as step description.
from grail import BaseTest, step class MyVeryFormattedTest(BaseTest): def test_some_feature(self): self.some_tricky_formatting('value', kwarg_to_format='kw_value', skip_this=100500) @step(description='Some info: {0}, another info: {kwarg_to_format}', format_description=True) def some_tricky_formatting(self, arg_to_format, kwarg_to_format, skip_this): print arg_to_format print kwarg_to_format print skip_this
Output will be like this:
It's forbidden to call steps from each other if it's not step group. But if you really need it you can tell caller to ignore @step functionality within itself.
from grail import BaseTest, step class DoItInVerySpecialCases(BaseTest): def test_its_not_recommended_to_do_this(self): self.external_step() @step(treat_nested_steps_as_methods=True) def external_step(self): self.this_is_not_a_step_anymore() @step def this_is_not_a_step_anymore(self): pass
Output will not contain description for the internal step:
There are cases when method output is too huge or it not interested in logging at all. You can switch off output logging for step.
from grail import BaseTest, step class MyDisableLogOutputTest(BaseTest): def test_some_feature(self): self.log_output() self.do_not_log_output() @step def log_output(self): return 'Important output' @step(log_output=False) def do_not_log_output(self): return 'Some invisible in logs data'
Output:
Regular test automation process assumes some manual test cases that should be automated. With Grail you can do vise versa - write code and get manual test cases. In order to generate test description from the code you should set grail.settings.export_mode=True. With this setting tests will be executed but steps' internal will not be called. So you can have your test description when your scripts are not implemented yet or automated test execution is blocked due to any other reasons.
In export_mode only setUp and tests are executed. All the fixtures are skipped. It's important to have your setUp and tests be implemented fully with @step-annotated methods and functions. For other fixtures it's up-to-you to use steps or not.
All @step features are enabled during export.
Empty params are not included to step description in export_mode.
This test output could be used as manual test case. E.g. you can store it in your favorite test management system.
from grail import BaseTest, step import grail.settings grail.settings.export_mode = True class MyTestForExport(BaseTest): def test_some_feature(self): self.login_to_application() self.one_more_step('Step input 1') self.pending_step() self.step_group() @step def login_to_application(self): pass @step def one_more_step(self, step_input): print 'You will not see next line print' print step_input @step(description='Some step that will be implemented') def pending_step(self): pass @step(step_group=True) def step_group(self): self.one_more_step('Step input 2') self.one_more_step(None)
Output which can be used as manual test case:


Automated Code Review
Codacy
Codacy automates code reviews and monitors code quality on every commit and pull request. It gives visibility into the technical debt and it can track code style and security issues, code coverage, code duplication, cyclomatic complexity and enforce best practices. Codacy is static analysis without the hassle.
With Codacy you have PMDJava analysis out-of-the-box, and it is free for open source projects.
- Homepage: https://www.codacy.com/
- Source code: https://github.com/codacy/codacy-pmdjava
- Maintainer: Codacy
IDE Integrations
Summary
| IDE | Homepage | Source Code | Maintainers |
|---|---|---|---|
| BlueJ | pmd-bluej | Tom Copeland | |
| CodeGuide | N/A | Austin Moore | |
| Eclipse | github: pmd/pmd-eclipse | Philippe Herlin | |
| qa-Eclipse | qa-Eclipse | Christian Wulf | |
| eclipse-pmd | http://acanda.github.io/eclipse-pmd/ | github: acanda/eclipse-pmd | Philip Graf |
| Emacs | github: pmd/pmd-emacs | Nascif Abousalh Neto | |
| Gel | github: pmd/pmd-misc/pmd-gel | Andrei Lumianski | |
| Gradle | Gradle: The PMD Plugin | github: gradle/gradle | Gradle.org |
| IntelliJ IDEA | github: amitdev/PMD-Intellij | Amit Dev | |
| IntelliJ IDEA - QAPlug | http://qaplug.com/ | N/A | Jakub Sławiński |
| JBuilder | github: pmd/pmd-misc/pmd-jbuilder | Tom Copeland | |
| JCreator | N/A | Brant Gurganus | |
| JDeveloper | github: pmd/pmd-jdeveloper | Torsten Kleiber | |
| JEdit | jEdit - PMD Plugin | sourceforge: jedit/PMDPlugin | Jiger Patel, Dale Anson |
| NetBeans | SQE | github: sqe-team/sqe | N/A |
| TextPad | N/A | Jeff Epstein | |
| WebLogic Workshop 8.1.x | N/A | Kevin Conaway |
General comments
A general note - most plugins include the PMD jar files, which has the rulesets inside it. So even though the rulesets parameter that some plugins use (i.e., “rulesets/java/unusedcode.xml”) looks like a filesystem reference, it’s really being used by a getResourceAsStream() call to load it out of the PMD jar files.
BlueJ
BlueJ is a teaching IDE. To install the PMD extension for BlueJ, download
the PMDExtension jar file
and place it in your bluej/lib/extensions/
directory.
Code Guide
Here’s how to set up PMD with Omnicore’s CodeGuide:
- Download the PMD zip file from here
- Unpack the zip file to your local disk. I put it in /Applications/
- Add the following tool to CodeGuide (Tools->Configure Tools->New):
- Name: PMD
- Kind: Tool for directories
- Executable: /Applications/pmd-bin-/bin/run.sh
- Arguments: pmd -d $DIRECTORY_PATH$ -f emacs $USER_ARGUMENTS$
Now you can right click on a source directory, select the PMD tool and a dialog box will appear. Type in the name of a rule set (e.g. unusedcode). PMD is then executed on the directory you selected with the rule set you specified. Since CodeGuide understands the emacs syntax you can click on the file name and CodeGuide will jump to that file and line number.
Note: I set this up on Mac OS X. It should work on other unix variations just the same. Of course you need to change the “Executable” setting above to where your PMD is installed. On Windows you need to use the pmd.bat file instead of pmd.sh.
If you haven’t heard of CodeGuide before, check it out. It’s a great IDE.
Eclipse
To install the PMD plugin for Eclipse:
- Start Eclipse and open a project
- Select “Help”->”Software Updates”->”Find and Install”
- Click “Next”, then click “New remote site”
- Enter “PMD” into the Name field and https://dl.bintray.com/pmd/pmd-eclipse-plugin/updates/ into the URL field
- Click through the rest of the dialog boxes to install the plugin
Alternatively, you can download the latest zip file and follow the above procedures except for using “New local site” and browsing to the downloaded zip file.
To configure PMD, select “Windows”->”Preferences”, then select PMD.
To run PMD, right-click on a project node and select “PMD”->”Check code with PMD”.
To run the duplicate code detector, right-click on a project node and select “PMD”->”Find suspect cut and paste”. The report will be placed in a “reports” directory in a file called “cpd-report.txt”.
To find additional help for other features, please read included help by selecting Help->Help Contents and browse the “How to…” section in the “PMD Plugin Documentation” book.
After installing an update, if you get an Exception such as “java.lang.RuntimeException: Couldn’t find that class xxxxx”, try deleting the ruleset.xml file in the .metadata/plugins/net.sourceforge.pmd.eclipse directory in your workspace.
To get Eclipse to not flag the @SuppressWarnings(“PMD”) annotation, look under the menu headings Java -> Compiler -> Errors/Warnings -> Annotations -> Unhandled Warning Token.
Emacs
Integration with GNU Emacs is performed through an ELisp package, pmd.el. It supports two commands, “pmd-current-buffer” and “pmd-current-dir”. The output is captured in a compilation buffer which allows the user to “jump” directly to the source code position associated with the PMD warnings.
Gel
Here’s how to set up the Gel plugin:
- Download the pmd-gel-[version].zip file
- Close Gel
- Remove any old plugin versions from your gel\plugins directory
- Unzip the new zip file into your gel\plugins directory
- Start Gel
- Go to Tools->Options->Plugin
- Select the PMD plugin and click “Remove”
- Click “Add” and select “net.sourceforge.pmd.gel.PMDPlugin”
- Restart Gel
That’s pretty much it. Now you can open a Java project and click on Plugins->PMD and a configuration panel will pop up. You can pick which ruleset you want to run and you can also pick whether you want to run PMD on the current file or on every source file in your project.
IDEA
You can use an integrated plugin or just use it as an IDEA “External Tool”.
Amit Dev wrote an integrated plugin for IDEA; you can download that from the IntelliJ plugins site.
Here’s how to set it up as an “External Tool”:
- Open IDEA and go to File->Settings
- Click on the “External Tools” icon
- Click on the Add button
- Fill in the blocks
- Name: PMD
- Description: PMD, good for what ails you.
- Menu: Select the “Main menu”, “Project views”, “Editor menu”, and “Search results” checkboxes.
- Program: $JDKPath$\bin\java.exe
- For the next parameter you’ll need to plug in the location of your PMD installation and the rulesets you want to use
- Parameters:
-cp %CLASSPATH%;c:\pmd\lib\pmd-.jar;c:\pmd\lib\asm-3.2.jar;c:\pmd\lib\jaxen-1.1.1.jar net.sourceforge.pmd.PMD "$FilePath$" ideaj unusedcode,imports "$Sourcepath$" $FileClass$.method $FileName$
That’s pretty much it. Now you can right click on a source directory and select PMD, it’ll run recursively on the source files, and the results should be displayed in a window and hyperlinked into the correct file and line of code. I usually right-click on the message window title bar and unselect “autohide” so the window doesn’t go away every time I fix something in the code window.
IDEA - QAPlug
QAPlug is an Intellij IDEA plugin to manage code quality. It integrates no less than Checkstyle, FindBugs, and PMD.
The plugin is available at http://www.qaplug.com/.
Also available at the JetBrains site, QAPlug-PMD and QAPlug.
JBuilder
To enable this OpenTool in JBuilder:
- Download the latest binary release
- Unzip it into your
jbuilder/lib/ext/
directory - Restart JBuilder
What you can do:
- Check a single file by bringing up the context menu from the file tab and selecting PMDCheck
- Configure the rulesets that the PMD OpenTool will use by selecting Tools->PMD->Configure PMD
- Check all the files in a project by bringing up the context menu for the project node and selecting PMD Check Project
- Locate duplicate code by right clicking on a package and selection “Check with CPD”
When running PMD, the results will be displayed in the MessageView under a tab called PMD Results. If you click on a violation message within this view, you will be taken to the line in the source code where the violation was detected.
Things still to do:
- Enable selection of individual rules within a rule set (maybe)
- Optional insertion of @todo comments at the point of a violation
- Possibly provide configurable ability to limit the number of violations per rule per file
JCreator
- Open Configure > Options
- Go to the Tools panel
- Click New > Program
- Browse for PMD’s pmd.bat
- Put quotations around the path if it has spaces.
- Set the initial directory to PMD’s \bin directory
- Check capture output
- Put ‘”$[PrjDir]” emacs’ followed by desired rulesets in the arguments
To run PMD on a project, just pick pmd from the Tools menu.
JDeveloper
To install the PMD plugin for JDeveloper:
- JDeveloper 10.1.2: Download the binary release and unzip it into your jdev/lib/ext directory
- JDeveloper 10.1.3 upwards: Click “Help”, click “Check for Updates”
- JDeveloper 10.1.3:
- Press “Add” to add a new update center
- Name: PMD Update Center
- Location: http://pmd.sourceforge.net/center.xml
- Select Update Center: PMD Update Center
- JDeveloper 11 upwards: Select Update Center: Open Source and Partner Extensions
- Press Next and select the actual PMD Plugin and install it
- JDeveloper 10.1.3:
- Restart JDeveloper
To run the PMD plugin for JDeveloper:
- Open the Tools-&Preferences menu
- Click on the PMD option
- Select a couple of rules to try
- To run PMD, right click on either a file, folder, package, project or workspace and select PMD via Toolbar Icon, Context Menu or File Menu
- Any rule violations should show up in a LogWindow tab at the bottom of the screen
JEdit
The way I use the JEdit plugin is:
- Dock the ErrorList by going to Utilities->Global Options->Docking and putting ErrorList at the bottom of the screen
- Open the File Browser if it isn’t already open
- Double-click on a source directory
- Select Plugins->PMD->Check directory recursively
Note that you can select individual rules by going to Utilities->Global Options->Plugin Options->PMD. Also, you can change the plugin to prompt you for a directory to check by going to that same menu and selecting the “Ask for Directory” checkbox.
NetBeans
The SQE project includes PMD integration for NetBeans.
TextPad
Assumptions
- The Java Development Kit, version 1.4.2 (versions 1.4 and higher are acceptable) is properly installed
into your machine, and exists in
D:\java\jdk\_142\
. This means thatD:\java\jdk\_142\bin\java.exe
exists. - PMD version 5.0 exists in
D:\java\pmd-bin-\
. This means thatD:\java\pmd-bin-\lib\pmd-.jar
(among other jar files in the same directory) exist.
To integrate into TextPad
- In the Configure menu, choose Preferences…. This opens the Preferences dialog
- In the left pane of the Preferences dialog, choose the Tools branch by clicking on the word “Tools”.
- On the far right of the dialog, click on the Add button, and then select Program… from the drop-down. This opens the standard Windows Open File dialog.
- Type
D:\java\jdk_142\bin\java.exe
and click the Open button. In the center pane of the Preferences dialog, an item “Java” has now been added, and is currently selected. - Click the word Java, which makes the word editable. Select the entire word, and type “PMD directory”. Press Return.
- Repeat steps three through five, but type “PMD file”, instead of “PMD directory”.
- Click Apply.
- Expand the Tools branch (if not already) by clicking on the ‘
+
’ directly to its left. - In the expanded list, select PMD directory. This changes the right side of this dialog to the “tool” form.
- In the “tool” form, enter these parameters:
- Parameters:
-classpath D:\java\pmd-bin-\lib\pmd-.jar;D:\java\pmd-bin-\lib\asm-3.2.jar;D:\java\pmd-bin-\lib\jaxen-1.1.1.jar net.sourceforge.pmd.PMD -d $FileDir -f net.sourceforge.pmd.renderers.TextPadRenderer -R E:\directory\my_pmd_ruleset.xml -debug
- Initial Folder:
$FileDir
- Save all documents first:
Checked
- Capture output:
Checked
- All other checkboxes: Unchecked
- Regular expression to match output:
^\([^(]+\)(\([0-9]+\),
- Registers/File:
1
- Registers/Line:
2
- Parameters:
- In the expanded list, select PMD file.
- In the “tool” form, enter the same parameters as above, except replace ‘
$FileDir
’ with ‘$File
’, in the Parameters textbox. - To save your work (truly, given a quirk of TextPad), click on OK, which closes the Preferences dialog. Restart TextPad and re-open the Preferences dialog.
- Go back to both the “PMD directory” and “PMD file” Tools branches, and replace ‘
E:\directory\my_pmd_ruleset.xml
’ with the ruleset of your choice. For example,basic
. - Go to the Keyboard branch in the left pane (above Tools), which changes the right side to the “keyboard configuration” form.
- In the Categories list box, select Tools.
- In the Command list box, select PMD directory.
- Put your cursor into the Press new shortcut key, and type your desired key command.
For example
Ctrl+Page Up
- Click Assign.
- In the Command list box, select PMD file.
- Put your cursor into the Press new shortcut key, and type your desired key command.
For example
Ctrl+Page Down
- Click Assign.
- Save your work again: Click on OK, which closes the Preferences dialog, and then restart TextPad.
To run PMD against a single Java file
- In TextPad, open any Java file.
- Click
Ctrl+Page Down
. This opens an empty, read-only text document (titled “Command Results”). When PMD completes its analysis, this document will be populated with a listing of violated rules (or “Command completed successfully” indicating no violations). - Double click any line to go to it.
To run PMD against a directory of Java files
- In TextPad, open any file in the root directory you wish to analyze. Unfortunately, you’ll need to create a dummy file, if no file exists there.
- Click
Ctrl+Page Up
. This opens an empty, read-only text document (titled “Command Results”). When PMD completes its analysis, this document will be populated with a listing of violated rules (or “Command completed successfully” indicating no violations). - Double click any line to go to it.
Because directory analysis may take a while, you may choose to cancel this operation. Do so by closing the (blank Command Results) document, and then confirming that, “yes, I do really want to exit the tool”.
WebLogic Workshop 8.1.x
Please see the WebLogic Workshop plugin project home page for more information.


Press n or j to go to the next uncovered block, b, p or k for the previous block.
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| ace.js | 94.48% | 154/163 | 87.96% | 95/108 | 83.33% | 5/6 | 94.38% | 151/160 | |
| editorOptions.js | 100% | 10/10 | 100% | 0/0 | 100% | 3/3 | 100% | 9/9 | |
| split.js | 97.33% | 182/187 | 89.22% | 91/102 | 100% | 10/10 | 97.28% | 179/184 |


GitHub repos and Contact Information
Welcome, and thanks for visiting! I’m Tyler Moeller.
This is a collection of front-end development and NodeSchool projects I have worked on. Everything is on GitHub - feedback and issue reports are more than welcome! To learn more about me, see my social media links at the bottom of this page.
View more repos on my GitHub Profile.


Riley Patterson's Web120 BIG Website
WEB120 Portal
Contact
Responsive VS Native
Galleries
Google Tools
Youtube
Calendar
Map
Shopping Carts
Flexbox
Web Cam
Seattle Central College (SCC)


---
layout: post
mathjax: true
comments: true
date: 2012-12-14
title: [Project Euler] #14 Solution
excerpt: |
This page presents solutions to Project Euler Problem 14 in Java and Ruby.
tags:
- project euler problem 14 solution
- project euler problem 14 answer
- project euler problem 14 java
- project euler problem 14 ruby
---
Overview
Question
The following iterative sequence is defined for the set of positive integers:
$$
n \rightarrow
\begin{cases}
\tfrac{n}{2} & \text{if } n \text{ is even} \\\\
3n+1 & \text{if } n \text{ is odd} \\\\
\end{cases}
$$
Using the rule above and starting with 13, we generate the following sequence:
\[13, 40, 20, 10, 5, 16, 8, 4, 2, 1\]
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10
terms. Although it has not been proved yet (Collatz Problem), it is thought that all
starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
click for answer
837799
Solutions
Java
{% highlight java %} collatz.java https://raw.github.com/addamh/euler/master/014/collatz.java download
public class collatz {
public static void main(String[] args) {
int p;
long a = 0;
long b = 0;
long c;
for (int i =0;i<1000000;i++){
p=1;
c=i;
while(c>1){
if(c%2==0){
c=c/2;
p++;
} else {
c=3*c+1;
p++;
}
}
if(p>a){
a=p;
b=i;
}
}
// Debug output
// System.out.println(a+" -> "+b);
System.out.println(b);
}
}
{% endhighlight %}
{% highlight console %}
$ time bash collatz.java
real 0m1.167s
user 0m1.698s
sys 0m0.097s
{% endhighlight %}
Ruby
{% highlight ruby %} collatz.rb https://raw.github.com/addamh/euler/master/014/collatz.rb download
#!/usr/bin/env ruby
def collatz(stack, n)
stack.push(n)
if n > 1
if(n % 2 == 0)
collatz(stack, n/2)
else
collatz(stack, 3*n+1)
end
end
return stack
end
sequence = Enumerator.new do |yielder|
number = 0
loop do
number += 1
yielder.yield number
end
end
max = {:i => 1, :l => 0}
sequence.each do |i|
a = collatz([], i)
l = a.length
if max[:l] < l
max[:i] = i
max[:l] = l
end
break if i > 1000000
end
p max[:i]
{% endhighlight %}
{% highlight console %}
$ time ruby collatz.rb
real 1m6.439s
user 1m6.334s
sys 0m0.070s
{% endhighlight %}


{% trans "Sign Up Closed" %}
{% trans "We are sorry, but the sign up is currently closed." %}
{% extends "base-without-menu.html" %} {% load static i18n %} {% block title %}{% trans "Sign Up Closed" %}{% endblock title %} {% block body %}
{% trans "We are sorry, but the sign up is currently closed." %}


Your browser does not support the video tag.
Your browser does not support the audio element.
Your browser does not support the canvas element.
dfsf


In this project, you'll use generative adversarial networks to generate new images of faces.
You'll be using two datasets in this project:
Since the celebA dataset is complex and you're doing GANs in a project for the first time, we want you to test your neural network on MNIST before CelebA. Running the GANs on MNIST will allow you to see how well your model trains sooner.
If you're using FloydHub, set data_dir
to "/input" and use the FloydHub data ID "R5KrjnANiKVhLWAkpXhNBe".
data_dir = './data'
# FloydHub - Use with data ID "R5KrjnANiKVhLWAkpXhNBe"
#data_dir = '/input'
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import helper
helper.download_extract('mnist', data_dir)
helper.download_extract('celeba', data_dir)
show_n_images = 25
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
%matplotlib inline
import os
from glob import glob
from matplotlib import pyplot
mnist_images = helper.get_batch(glob(os.path.join(data_dir, 'mnist/*.jpg'))[:show_n_images], 28, 28, 'L')
pyplot.imshow(helper.images_square_grid(mnist_images, 'L'), cmap='gray')
The CelebFaces Attributes Dataset (CelebA) dataset contains over 200,000 celebrity images with annotations. Since you're going to be generating faces, you won't need the annotations. You can view the first number of examples by changing show_n_images
.
show_n_images = 25
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
mnist_images = helper.get_batch(glob(os.path.join(data_dir, 'img_align_celeba/*.jpg'))[:show_n_images], 28, 28, 'RGB')
pyplot.imshow(helper.images_square_grid(mnist_images, 'RGB'))
Since the project's main focus is on building the GANs, we'll preprocess the data for you. The values of the MNIST and CelebA dataset will be in the range of -0.5 to 0.5 of 28x28 dimensional images. The CelebA images will be cropped to remove parts of the image that don't include a face, then resized down to 28x28.

You'll build the components necessary to build a GANs by implementing the following functions below:
model_inputs
discriminator
generator
model_loss
model_opt
train
This will check to make sure you have the correct version of TensorFlow and access to a GPU
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
from distutils.version import LooseVersion
import warnings
import tensorflow as tf
# Check TensorFlow Version
assert LooseVersion(tf.__version__) >= LooseVersion('1.0'), 'Please use TensorFlow version 1.0 or newer. You are using {}'.format(tf.__version__)
print('TensorFlow Version: {}'.format(tf.__version__))
# Check for a GPU
if not tf.test.gpu_device_name():
warnings.warn('No GPU found. Please use a GPU to train your neural network.')
else:
print('Default GPU Device: {}'.format(tf.test.gpu_device_name()))
Implement the model_inputs
function to create TF Placeholders for the Neural Network. It should create the following placeholders:
image_width
, image_height
, and image_channels
.z_dim
.Return the placeholders in the following the tuple (tensor of real input images, tensor of z data)
import problem_unittests as tests
def model_inputs(image_width, image_height, image_channels, z_dim):
"""
Create the model inputs
:param image_width: The input image width
:param image_height: The input image height
:param image_channels: The number of image channels
:param z_dim: The dimension of Z
:return: Tuple of (tensor of real input images, tensor of z data, learning rate)
"""
real = tf.placeholder(tf.float32, (None, image_width, image_height, image_channels), name='input_real')
z = tf.placeholder(tf.float32, (None, z_dim), name='input_z')
is_training = tf.placeholder(tf.bool)
return real, z, is_training
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_model_inputs(model_inputs)
Implement discriminator
to create a discriminator neural network that discriminates on images
. This function should be able to reuse the variabes in the neural network. Use tf.variable_scope
with a scope name of "discriminator" to allow the variables to be reused. The function should return a tuple of (tensor output of the discriminator, tensor logits of the discriminator).
def discriminator(images, reuse=False, alpha=0.2):
"""
Create the discriminator network
:param image: Tensor of input image(s)
:param reuse: Boolean if the weights should be reused
:return: Tuple of (tensor output of the discriminator, tensor logits of the discriminator)
"""
with tf.variable_scope('discriminator', reuse=reuse):
# Input layer is 28x28x?
x = tf.layers.conv2d(images, 64, 5, strides=2, padding='same')
x = tf.maximum(alpha*x, x)
# Input now 14x14x64
c2 = tf.layers.conv2d(x, 128, 5, strides=2, padding='same')
c2 = tf.layers.batch_normalization(c2, training=True)
c2 = tf.maximum(alpha * c2, c2)
# Input now 7x7x128
c3 = tf.layers.conv2d(x, 256, 5, strides=2, padding='same')
c3 = tf.layers.batch_normalization(c3, training=True)
c3 = tf.maximum(alpha * c3, c3)
# Input now 4x4x256
logits = tf.layers.dense(tf.reshape(c3, (-1, 4*4*256)), 1, activation=None)
out = tf.sigmoid(logits)
return logits, out
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_discriminator(discriminator, tf)
Implement generator
to generate an image using z
. This function should be able to reuse the variabes in the neural network. Use tf.variable_scope
with a scope name of "generator" to allow the variables to be reused. The function should return the generated 28 x 28 x out_channel_dim
images.
def generator(z, out_channel_dim, is_train=True, alpha=0.2):
"""
Create the generator network
:param z: Input z
:param out_channel_dim: The number of channels in the output image
:param is_train: Boolean if generator is being used for training
:return: The tensor output of the generator
"""
with tf.variable_scope('generator', reuse=(not is_train)):
# First fully connected layer
x = tf.layers.dense(z, 4*4*256)
xr = tf.reshape(x, (-1, 4, 4, 256))
xr = tf.layers.batch_normalization(xr, training=is_train)
xr = tf.maximum(alpha * xr, xr)
# Should be 4x4x256
# First convolutional layer
c1 = tf.layers.conv2d_transpose(xr, 128, 4, 1, padding='valid')
c1 = tf.layers.batch_normalization(c1, training=is_train)
c1 = tf.maximum(alpha * c1, c1)
# Should be 7x7x128
# Second convolutional layer
c2 = tf.layers.conv2d_transpose(c1, 64, 5, 2, padding='same')
c2 = tf.layers.batch_normalization(c2, training=is_train)
c2 = tf.maximum(alpha * c2, c2)
# Should be 14x14x64
logits = tf.layers.conv2d_transpose(c2, out_channel_dim, 5, 2, padding='same')
# Output layer, 28x28xocd
out = tf.tanh(logits)
return out
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_generator(generator, tf)
Implement model_loss
to build the GANs for training and calculate the loss. The function should return a tuple of (discriminator loss, generator loss). Use the following functions you implemented:
discriminator(images, reuse=False)
generator(z, out_channel_dim, is_train=True)
def model_loss(input_real, input_z, out_channel_dim, alpha=0.2):
"""
Get the loss for the discriminator and generator
:param input_real: Images from the real dataset
:param input_z: Z input
:param out_channel_dim: The number of channels in the output image
:return: A tuple of (discriminator loss, generator loss)
"""
g_model = generator(input_z, out_channel_dim, alpha=alpha)
d_model_real, d_logits_real = discriminator(input_real, alpha=alpha)
d_model_fake, d_logits_fake = discriminator(g_model, reuse=True, alpha=alpha)
d_loss_real = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_real, labels=tf.ones_like(d_model_real)))
d_loss_fake = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_fake, labels=tf.zeros_like(d_model_fake)))
g_loss = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_fake, labels=tf.ones_like(d_model_fake)))
d_loss = d_loss_real + d_loss_fake
return d_loss, g_loss
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_model_loss(model_loss)
Implement model_opt
to create the optimization operations for the GANs. Use tf.trainable_variables
to get all the trainable variables. Filter the variables with names that are in the discriminator and generator scope names. The function should return a tuple of (discriminator training operation, generator training operation).
def model_opt(d_loss, g_loss, learning_rate, beta1):
"""
Get optimization operations
:param d_loss: Discriminator loss Tensor
:param g_loss: Generator loss Tensor
:param learning_rate: Learning Rate Placeholder
:param beta1: The exponential decay rate for the 1st moment in the optimizer
:return: A tuple of (discriminator training operation, generator training operation)
"""
t_vars = tf.trainable_variables()
d_vars = [var for var in t_vars if var.name.startswith('discriminator')]
g_vars = [var for var in t_vars if var.name.startswith('generator')]
# Optimize
with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)):
d_train_opt = tf.train.AdamOptimizer(learning_rate, beta1=beta1).minimize(d_loss, var_list=d_vars)
g_train_opt = tf.train.AdamOptimizer(learning_rate, beta1=beta1).minimize(g_loss, var_list=g_vars)
return d_train_opt, g_train_opt
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_model_opt(model_opt, tf)
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import numpy as np
def show_generator_output(sess, n_images, input_z, out_channel_dim, image_mode):
"""
Show example output for the generator
:param sess: TensorFlow session
:param n_images: Number of Images to display
:param input_z: Input Z Tensor
:param out_channel_dim: The number of channels in the output image
:param image_mode: The mode to use for images ("RGB" or "L")
"""
cmap = None if image_mode == 'RGB' else 'gray'
z_dim = input_z.get_shape().as_list()[-1]
example_z = np.random.uniform(-1, 1, size=[n_images, z_dim])
samples = sess.run(
generator(input_z, out_channel_dim, False),
feed_dict={input_z: example_z})
images_grid = helper.images_square_grid(samples, image_mode)
pyplot.imshow(images_grid, cmap=cmap)
pyplot.show()
Implement train
to build and train the GANs. Use the following functions you implemented:
model_inputs(image_width, image_height, image_channels, z_dim)
model_loss(input_real, input_z, out_channel_dim)
model_opt(d_loss, g_loss, learning_rate, beta1)
Use the show_generator_output
to show generator
output while you train. Running show_generator_output
for every batch will drastically increase training time and increase the size of the notebook. It's recommended to print the generator
output every 100 batches.
def train(epoch_count, batch_size, z_dim, learning_rate, beta1, get_batches, data_shape, data_image_mode):
"""
Train the GAN
:param epoch_count: Number of epochs
:param batch_size: Batch Size
:param z_dim: Z dimension
:param learning_rate: Learning Rate
:param beta1: The exponential decay rate for the 1st moment in the optimizer
:param get_batches: Function to get batches
:param data_shape: Shape of the data
:param data_image_mode: The image mode to use for images ("RGB" or "L")
"""
print_every = 10
show_every = 100
out_channel_dim = 1 if data_image_mode == "L" else 3
input_real, input_z, is_training = model_inputs(data_shape[1], data_shape[2], out_channel_dim, z_dim)
d_loss, g_loss = model_loss(input_real, input_z, out_channel_dim, alpha=0.2)
d_opt, g_opt = model_opt(d_loss, g_loss, learning_rate, beta1)
steps = 0
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for e in range(epoch_count):
for batch_images in get_batches(batch_size):
steps += 1
# Images are range -0.5 to 0.5, but want -1 to 1
batch_images *= 2
# Sample random noise for G
batch_z = np.random.uniform(-1, 1, size=(batch_size, z_dim))
# Run optimizers
_ = sess.run(d_opt, feed_dict={input_real: batch_images, input_z: batch_z})
_ = sess.run(g_opt, feed_dict={input_z: batch_z, input_real: batch_images})
if steps % print_every == 0:
# At the end of each epoch, get the losses and print them out
train_loss_d = d_loss.eval({input_z: batch_z, input_real: batch_images})
train_loss_g = g_loss.eval({input_z: batch_z})
print("Epoch {}/{}...".format(e+1, epochs),
"Step: {}".format(steps),
"Discriminator Loss: {:.4f}...".format(train_loss_d),
"Generator Loss: {:.4f}\r".format(train_loss_g), end='')
if steps % show_every == 0:
show_generator_output(sess, 25, input_z, out_channel_dim, data_image_mode)
# At the end of each epoch, get the losses and print them out
train_loss_d = d_loss.eval({input_z: batch_z, input_real: batch_images})
train_loss_g = g_loss.eval({input_z: batch_z})
print("Epoch (end) {}/{}...".format(e+1, epochs),
"Step: {}".format(steps),
"Discriminator Loss: {:.4f}...".format(train_loss_d),
"Generator Loss: {:.4f}\r".format(train_loss_g), end='')
show_generator_output(sess, 25, input_z, out_channel_dim, data_image_mode)
Test your GANs architecture on MNIST. After 2 epochs, the GANs should be able to generate images that look like handwritten digits. Make sure the loss of the generator is lower than the loss of the discriminator or close to 0.
batch_size = 128
z_dim = 100
learning_rate = 0.0002
beta1 = 0.5
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
epochs = 2
mnist_dataset = helper.Dataset('mnist', glob(os.path.join(data_dir, 'mnist/*.jpg')))
with tf.Graph().as_default():
train(epochs, batch_size, z_dim, learning_rate, beta1, mnist_dataset.get_batches,
mnist_dataset.shape, mnist_dataset.image_mode)
Run your GANs on CelebA. It will take around 20 minutes on the average GPU to run one epoch. You can run the whole epoch or stop when it starts to generate realistic faces.
batch_size = 128
z_dim = 100
learning_rate = 0.0002
beta1 = 0.5
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
epochs = 1
celeba_dataset = helper.Dataset('celeba', glob(os.path.join(data_dir, 'img_align_celeba/*.jpg')))
with tf.Graph().as_default():
train(epochs, batch_size, z_dim, learning_rate, beta1, celeba_dataset.get_batches,
celeba_dataset.shape, celeba_dataset.image_mode)
When submitting this project, make sure to run all the cells before saving the notebook. Save the notebook file as "dlnd_face_generation.ipynb" and save it as a HTML file under "File" -> "Download as". Include the "helper.py" and "problem_unittests.py" files in your submission.


1.Is "孤独症" the same thing with "自闭症"?
Correct Answer: A “孤独症” and “自闭症” are both a translation of Autism，there's no difference. “孤独症” is always used in China mainland; while “自闭症” is used internationally.


I am pursuing my Second Bachelor’s Degree in Computer Science at FAU. Python is my strongest programming language and I enjoy solving coding problems. “A Leetcode a day keeps unemployment away.” My website
I am a computer science major at FAU and a musician of about 15 years. I was born and raised in Titusville, Florida, and I currently reside in Orlando. I'm fairly adept at C++, slightly less adept at writing bios. Install Gentoo!My website
I am a Senior at Florida Atlantic University and is working on a bachelor’s degree in Computer Engineering. Some of the classes that I have completed recently Include Embedded Systems (where I created an automated gardening system), Data Structures and Analysis and Electronics 1 with the lab. Before I began going to university, I was in the Coast Guard for four years. I started off as a Fireman’s Apprentice on a medium endurance cutter based out of Oregon, and before I left the service, I was an Electrician’s Mate Second Class working on a base in San Francisco. After the Coast Guard I became a Generator Technician and was going to Palm Beach State part time. I am currently living in Port Saint Lucie with my wife and two-year-old son. My goal after getting my degree is to get a job in embedded systems or software development.My website
My name is Luiz Zullino Junior. I was born and raised in Brazil and came to the US in 2015. Before I came here, I had been studying Electrical Engineering for 2 years. In 2018, I started my AA in Palm Beach State College, studying part-time because of my full-time job. In 2020, I finished the AA and transferred to FAU to pursue my major in Computer Engineering. I was always passionate about video games and that lead me to start learning programming. I have experience with C++, HTML, Javascript, CSS, PHP, Python. I also have a little experience with Java, C#, SQL. One of my goals is to develop meaningful games that can add something to people’s life when they play them. Another goal of mine is to develop mobile apps that can solve some problem in our society.My website
I am currently enrolled at Florida Atlantic University , my major is computer science, and I plan to graduate in 2021. I would like to use this project to gain experience in agile development. I am always continuing to learn, and am looking forward to working in a professional environment.


Video: John Terry makes baffling claim about why Liverpool & Man City stars didn’t make it at Chelsea
by Lucien SilverbergFormer Chelsea captain John Terry has made a slightly bizarre claim about why Liverpool and Manchester City stars Mohamed Salah and Kevin De Bruyne didn’t make it at Stamford Bridge.
Both were at Chelsea earlier in their careers but were sold before really being given much of an opportunity with the club, though they’ve since come back to haunt the Blues by becoming so successful for their rivals.
MORE: Chelsea dealt injury blow ahead of big game against Manchester City
Salah has been a lethal goal-scorer for Liverpool, helping them win the Champions League last season and playing a part in their strong charge for the Premier League title this term, while De Bruyne has been a creative force at this dominant City side for the last few years.
Terry, however, says in the video clip above that former Chelsea manager Jose Mourinho could not afford to risk playing them when he had quality goal-scoring wingers like Arjen Robben and Damien Duff in his squad.
Now, while those two were undoubtedly fine players for Chelsea once upon a time, they were both long gone by the time Salah and De Bruyne were at the west London club.
Terry seems to have got Mourinho’s two spells at CFC mixed up in rather embarrassing fashion!


Tidygeocoder 1.0.4
Filed under:
Tidygeocoder v1.0.4 is released! 🍾 This release adds support for the Geoapify geocoding service (thanks Daniel Possenriede!), a progress bar, more helpful console output, and new functions for combining the results of multiple geocoding queries. A more detailed overview of the changes in this release is available in the changelog.
Progress Bars and Console Output
Progress bars are now displayed for single input geocoding queries (ie. not batch queries). Additionally, console messages now by default show which geocoding service was used, how many addresses or coordinates were given to it, and how long the query took to execute.
The progress_bar
parameter can be used to toggle the use of the progress bar while the quiet
parameter can be used to silence console messages that are displayed by default. See the documentation for geo() or reverse_geo() for details.
Additionally, the quiet
, progress_bar
, and verbose
parameters can now be set permanently via options()
. For example, options(tidygeocoder.progress_bar = FALSE)
will disable progress bars for all queries.
Combining Multiple Queries
In past releases of the package, method = "cascade"
could be used in the geo()
and geocode()
functions to combine the results of geocoding queries from two different services. The “cascade” method is now deprecated in favor of two new and more flexible functions: geocode_combine()
and geo_combine()
. These functions allow for executing and combining the results of more than two queries and they allow the queries to be fully customized.
To demonstrate the utility of these new functions, below I’ve assembled a dataset of addresses to be geocoded. The first 5 are street level addresses in the United States that can be geocoded with the US Census geocoding service. However, three of these addresses will not return results with the US Census batch service (see issue #87 for more information) and must instead be geocoded with the US Census single address geocoder. Also, the last three addresses are cities outside the United States and require a different geocoding service entirely (the US Census service is limited to the United States).
library(tidyverse)
library(tidygeocoder)
mixed_addresses <- tribble(
~street_address, ~city, ~state_cd, ~zip_cd,
"624 W DAVIS ST #1D", "BURLINGTON", "NC", 27215,
"201 E CENTER ST #268", "MEBANE", "NC", 27302,
"7833 WOLFE LN", "SNOW CAMP", "NC", 27349,
"202 C St", "San Diego", "CA", 92101,
"121 N Rouse Ave", "Bozeman", "MT", 59715
) %>%
bind_rows(
tibble(city = c('Taipei', 'Moscow', 'Buenos Aires'))
)
If we wanted to geocode a large dataset with addresses such as these, we might first try to geocode as many as possible via the US Census batch service, then attempt the remaining addresses with the US Census single address geocoder, and then finally send any remaining unfound addresses to another service. We’ll accomplish this workflow in the code below.
The geocode_combine()
function accepts a dataframe input and a list of queries provided as lists (ie. a list of lists). Each list in the queries
argument contains parameters that are passed to the geocode()
function. Optionally, the query_names
argument can be used to specify a label to be used for each query’s results.
Below, the street
, city
, state
, and postalcode
arguments are specified for the first two queries while the address
argument (ie. single line address) is pointed at the city
column for the third query (the ArcGIS service only accepts a single line address argument and doesn’t use address component arguments like city
and state
).
results <- mixed_addresses %>%
geocode_combine(
queries = list(
list(method = 'census', mode = 'batch',
street = 'street_address', city = 'city', state = 'state_cd', postalcode = 'zip_cd'),
list(method = 'census', mode = 'single',
street = 'street_address', city = 'city', state = 'state_cd', postalcode = 'zip_cd'),
list(method = 'arcgis', address = 'city')
),
query_names = c('census - batch', 'census - single', 'arcgis')
)
##
## Passing 8 addresses to the US Census batch geocoder
## Query completed in: 1.9 seconds
## Passing 6 addresses to the US Census single address geocoder
## Query completed in: 3.6 seconds
## Passing 3 addresses to the ArcGIS single address geocoder
## Query completed in: 1.4 seconds
| street_address | city | state_cd | zip_cd | lat | long | query |
|---|---|---|---|---|---|---|
| 624 W DAVIS ST #1D | BURLINGTON | NC | 27215 | 36.09598 | -79.44453 | census - single |
| 201 E CENTER ST #268 | MEBANE | NC | 27302 | 36.09683 | -79.26977 | census - single |
| 7833 WOLFE LN | SNOW CAMP | NC | 27349 | 35.89866 | -79.43713 | census - single |
| 202 C St | San Diego | CA | 92101 | 32.71676 | -117.16283 | census - batch |
| 121 N Rouse Ave | Bozeman | MT | 59715 | 45.68066 | -111.03203 | census - batch |
| NA | Taipei | NA | NA | 25.03737 | 121.56355 | arcgis |
| NA | Moscow | NA | NA | 55.75696 | 37.61502 | arcgis |
| NA | Buenos Aires | NA | NA | -34.60849 | -58.37344 | arcgis |
By default the results of the queries are combined into a single dataframe as shown above and the query
column shows which query produced each result. Alternatively, the results of each query can be returned as separate dataframes in a list by using return_list = TRUE
.
By default, only addresses that are not found in a query are passed to the subsequent query. However, setting cascade = FALSE
will pass all addresses to all queries. See the documentation for the geocode_combine() function for more usage details.
Package Housekeeping
The return_type
, geocodio_v
, mapbox_permanent
, mapquest_open
, iq_region
, and here_request_id
parameters are now deprecated in favor of the new api_options
parameter. For instance, instead of using return_type = "geographies"
you should now instead use api_options = list(census_return_type = "geographies")
.
Also, the cascade_order
, param_error
, and batch_limit_error
parameters in geo()
are now deprecated as they were only required because of the deprecated “cascade” method. Refer to the documentation for geo() or reverse_geo() for details.


Represents an achievement
More...
#include <RuyiNetAchievementResponse.h>
Represents an achievement
◆ parseJson()
| void Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::parseJson |
( |
nlohmann::json & |
j | ) |
|
|
inline |
◆ achievementId
| std::string Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::achievementId |
The ID of the achievement.
◆ coinAwarded
| int Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::coinAwarded |
The amount of coin awarded when this achievement is gained.
◆ description
| std::string Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::description |
A description of the achievement.
◆ extraData
| std::string Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::extraData |
Any extra data attached by the developer.
◆ gameId
| std::string Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::gameId |
The ID of the game this achievement belongs to.
◆ imageUrl
| std::string Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::imageUrl |
The URL of the image related to this achievement.
◆ invisibleUntilEarned
| bool Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::invisibleUntilEarned |
Whether or not the achievement is invisible until it's earned.
◆ status
| std::string Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::status |
Whether or not the current player has earned this achievement.
◆ title
| std::string Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::title |
◆ xpAwarded
| int Ruyi::SDK::Online::RuyiNetAchievementResponse::Data::Achievement::xpAwarded |
The XP awarded when this achievement is gained.
The documentation for this struct was generated from the following file:


Function order
Boy, we covered a LOT in the last section! We saw how we could translate, rotate and scale an object to create the world matrix. We also saw how we can use lookAt to create a view matrix.
Now, i always say matrix multiplication is assisiative, but not cumulative. This means:
- A * B * C = A * (B * C)
- A * B != B * A
So, whats the right order to multiply matrices in? Well, with the modelView matrix you would expect to multiply the model by the view matrix, but that is NOT the case. That's right, we're about to make matrices a LOT more confusing. But first, let's take a look at the full multiplication that's happening.
Remember, OpenGL is column major, so vectors are column matrices (1 x 4). Because matrix multiplication inner products must match, this means the vector goes on the right side. The entire transform pipeline looks like this:
In theory
translated vertex = vertex * model * view * projection
How OpenGL really does it
renderVertex = vertex * modelView * projection
We want to first transform into model space, then view space, then projection space. Column major matrices have a slight gotcha to them, the matrices take effect from left to right, not right to left.
This means that the above code, would first move into projection space, then view space then model space. The exact Opposite of what we want!
This is confusing, but in order to do this:
translated vertex = vertex -> model -> view -> projection
You have to multiply in reverse order, like so:
translated vertex = projection * view * model * vertex
This is not the case for row major matrices! Only column major ones.
Scaling, Translating and Rotating
The other order we need to worry about is scale-translate-rotate order.
What order should you scale/translate/rotate in?
- Scale First
- Rotate second
- Translate last
So the transformation pipe looks like this:
transformed = vertex -> scale -> rotate -> translate
Remember, multiply right to leftThis means your multiplication order will look like this:
Result = Translate * Rotate * Scale * Vertex
Fun times.
OpenGL functions
Hopefully that all made sense, so how does that apply to OpenGL functions? Well if you recall, openGL functions just multiply matrices, so we have to call them in the right order, like so
void Render() {
// Pipeline: translated vertex = vertex -> model -> view -> projection
// Model matrix: transformed = vertex -> scale -> rotate -> translate
// Remember, read right to left when implementing multiplication!
// TODO: Set up projection here
// Multiply projection
// Set the modelView matrix to identity
GL.MatrixMode(MatrixMode.ModelView);
GL.LoadIdentity();
// Multiply view
LookAt(0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
// Draw an object
// Multiply model (scale, rotate, translate)
// Multiply translate
GL.Translate(-3.0f, 0.0f, 1.0f);
// Multiply rotate
GL.Rotate(90.0f, 1.0f, 0.0f, 0.0f);
// Multiply scale
GL.Scale(1.0f, 1.0f, 1.0f); // No scale
// The actual model has the input vertices
DrawCube();
}
If this doesn't make sense right now, go ahead and give me a call on skype. I know it's a bit of a confusing topic.
Box Demo
Let's make a demo that draws a cube in the scene. This cube will have some rotation, scale and translation for you to play around with.
First, make a new demo scene and follow along
using System;
using OpenTK.Graphics.OpenGL;
namespace GameApplication {
class BoxDemo : Game {
Grid grid = null;
// Add Look at function, it's in this gist
// https://gist.github.com/gszauer/91038dbb010755d719de
public override void Initialize() {
grid = new Grid();
}
public override void Update(float dTime) {
}
public override void Render() {
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity(); // Reset modelview matrix
LookAt(
0.5f, 0.5f, 0.5f, // Position
0.0f, 0.0f, 0.0f, // Target
0.0f, 1.0f, 0.0f // Up
);
// Render grid at the origin of the world
grid.Render();
}
public override void Shutdown() {
}
}
}
This puts us exactly where we left off in the last section. With the grid being visible at an angle. Remember, your machine will not look 100% like mine. We should have the same image, but yours might be culled out on the side.
Next, let's add a function that draws a cube. How do you draw a cube? A lot of triangles. I went ahead and drew one on paper, then counted all the verts out into CCW triangles. The result is this static function.
Go ahead and add the above function to your class. In render, after drawing the grid set the render color to red, and draw the cube. Like so:
public override void Render() {
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity(); // Reset modelview matrix
LookAt(
0.5f, 0.5f, 0.5f, // Position
0.0f, 0.0f, 0.0f, // Target
0.0f, 1.0f, 0.0f // Up
);
// Render grid at the origin of the world
grid.Render();
// Set render color
GL.Color3(1.0f, 0.0f, 0.0f);
// Draw cube
DrawCube();
}
When you run the game one of two things is going to happen. Either the entire screen is going to be red, or you will see the scene as before, with no changes. This is because the size of the cube is -1 to +1. The same size as NDC. The cube will either fill NDC and render the whole screen red, or get clipped and not render at all.Depends on your graphics card's default Z-Test setting.
On your own
We now have a rudimentary 3D scene! I want you to apply the following transformation to the 3D cube on your own:
- Scale to 0.05f on all axis
- Rotate 73 degrees on the Y axis
- Rotate 45 degrees on the X axis
- Translate to 0.25f on the X axis
- Translate to -0.25f on the Z axis
Keep in mind, if your pipeline is
scale -> rotate -> translate
Then the multiplication order is
translate * scale * rotate
I'll give you a bit of a hint as to where to do this. The full transform pipeline is this:
render vertex = projection -> model -> view -> scale -> rotate -> translate -> original vertex
We don't have projection yet. No action there
So you want to set the modelview matrix with the lookAt function (this was already done in the previous step, it does not change)
Next you want to render the grid at origin. We don't want to apply any transformations to the grid. You could say, the grid is only transformed by the view matrix, it has no model matrix.
Next you want to do your Scaling, Rotating and Translating. This is going to be the "model" part of the modelView matrix. It will position the square in the scene.
Last, you simply set the color to red (already there from previous section) and render by calling DrawCube (already there from previous section).
The resulting screen will look kind of like this:
If you get stuck, this page has a subsection with the solution. If i'm on skype, message me before you look at the solution, we can work trough the problem.


% layout('layout/default') -%> <% script('/assets/js/form.js') -%>
Simply enter your consumer key and consumer secret provided by Twitter via their app center.
We do not record any information. We simply pass your key and secret to twitter. If you prefer to do this offline, download the project and run it on your machine.


Before Change
if (action != "train") and (action != "tag") and (action != "train_eval"):
print("action not specifed, must be one of [train,train_eval,tag]")
embed_size, embedding_vector = make_embeddings_simple("/mnt/data/wikipedia/embeddings/crawl-300d-2M.vec", True)
if action == "train":
train(model, embedding_vector)
After Change
if (action != "train") and (action != "tag") and (action != "train_eval"):
print("action not specifed, must be one of [train,train_eval,tag]")
embedding_vector = Embeddings("fasttext-crawl").model
if action == "train":
train(model, embedding_vector)


In this section, we’ll go over the income you and the other members of your household who are not infants, children, or students receive.
We’ll ask a lot of questions—this is just to help you remember all of the different possible sources of income that might support your household.


Menu
Dashboard
START DRIVING
CUSTOM CONTROLS
EDIT MY CONTROLLER
HELP & MANUAL
SETTINGS
ROUTER SETUP
WRITE CODE
Log Out
BATTERY 100%
WIFI 100%
Ral-Rover
main Controls
Stopped
Distance
Clear
Too Close
Stop!
NO SIGNAL
Drive settings
Speed = 50 %
Heading = 0 degrees
Move duration = 10 seconds


Use the tree on the left to manage content. Your installation is made of the Document types and Properties listed below.
This document type has no properties.
Download Umbraco 7 editor guide


Dear Good day!!. Compliments of the day and my best wishes to you and family!!!. I know this letter will come to you surprisingly but let it not be a surprise to you, for nature has a way of arriving unannouced and an adage says 'originals are very hard to find but their echo sounds louder'. So, I decided to contact you myself for you to assure me of safety and honesty if I have to entrust any amount of money under your custody. I am Mr Micheal Bangura, the son of late Mr Thaimu Bangura who was the minister of finance in Sierra leone but was killed during the civil war. Knowing your country as being economical condusive for investment and your people as transperant and trustworthy to engage in business on which premise I write you. Before my father death, he had the sum of twenty-three million united states dollars(us$23,000,000.00) which he kept away from the rebel leaders during the course of the war and deposited it in a security company for saftey and safe-keeping. this fund was supposed to be used for rehabilitation of water reserves all over the country before the outbreak of war. when the war broke out, the rebel leader demanded that this fund be given to him, my father insisted that the money was not in his possesion but he was killed because of his refusal to release the fund. Meanwhile my mother and i is the only person who knows about this fund,because my father always confide in me since i am the only child in the family.When my father was killed,I quickly made an arrangemnt with a red cross rellief worker who used his official van to move me and my mother to lungi airport in freetownfor our safety because the rebels also wanted to kill us too. The fund was deposited by my late father as a family inheritance with a safe relaible security company in Dakar senegel where I was only given temporary asylum with my mother.I do not want to invest this money in senegel due to unfavourable economic climate and so close to my country. Also, I still kept this money also for security reasons as the present administration is investigating the existence of such fund of which I denied knowledge of it, claiming that my father did not tell me about such money. The only assistance I need from you which i believe you would do for me are the following: 1.Assist me invest this money in your country when it is release to you on our behalf by the security company. 2.Assure me that you will not sit on my share when this fund gets to your country. You will have 15% of the money for yourself as you guide me further to invest the remaining 80% in any valueble business venture while 5% is earmarked to cover expenses contingencies. Most importantly, i will like to buy a personal house where i and my mother will reside.Upon confirmation of your interest to help me as my foreign partner to invest this money, i will link you the details of this transaction to be scheduled in your favo ur by the security company. While thanking you for your anticipated understanding and cooperation, I look forward to your urgent response. please note that this transaction is strictly confidential and must be treated with utmost secrecy. Best regards, Mr. Micheal Bangura. Please you can contact me on this E-mail Address mbangura@worldemail.com