Best Practice¶
When writing your own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
For your own work this is of course fine, but if you want to collaborate with others or have your work included with blender there are practices we encourage.
Style Conventions¶
For Blender/Python development we have chosen to follow python suggested style guide to avoid mixing styles amongst our own scripts and make it easier to use python scripts from other projects.
Using our style guide for your own scripts makes it easier if you eventually want to contribute them to blender.
This style guide is known as pep8 and can be found here
A brief listing of pep8 criteria.
- camel caps for class names: MyClass
- all lower case underscore separated module names: my_module
- indentation of 4 spaces (no tabs)
- spaces around operators.
1 + 1
, not1+1
- only use explicit imports, (no importing
*
) - don’t use single line:
if val: body
, separate onto 2 lines instead.
As well as pep8 we have other conventions used for blender python scripts.
Use single quotes for enums, and double quotes for strings.
Both are of course strings, but in our internal API enums are unique items from a limited set. eg.
bpy.context.scene.render.image_settings.file_format = 'PNG' bpy.context.scene.render.filepath = "//render_out"
pep8 also defines that lines should not exceed 79 characters, we felt this is too restrictive so this is optional per script.
Periodically we run checks for pep8 compliance on blender scripts, for scripts to be included in this check add this line as a comment at the top of the script.
# <pep8 compliant>
To enable line length checks use this instead.
# <pep8-80 compliant>
User Interface Layout¶
Some notes to keep in mind when writing UI layouts:
UI code is quite simple. Layout declarations are there to easily create a decent layout.
General rule here: If you need more code for the layout declaration, then for the actual properties, you do it wrong.
Example layouts:
layout()
The basic layout is a simple Top -> Bottom layout.
layout.prop() layout.prop()
layout.row()
Use row(), when you want more than 1 property in one line.
row = layout.row() row.prop() row.prop()
layout.column()
Use column(), when you want your properties in a column.
col = layout.column() col.prop() col.prop()
layout.split()
This can be used to create more complex layouts. For example you can split the layout and create two column() layouts next to each other. Don’t use split, when you simply want two properties in a row. Use row() for that.
split = layout.split() col = split.column() col.prop() col.prop() col = split.column() col.prop() col.prop()
Declaration names:
Try to only use these variable names for layout declarations:
- row for a row() layout
- col for a column() layout
- split for a split() layout
- flow for a column_flow() layout
- sub for a sub layout (a column inside a column for example)
Script Efficiency¶
List Manipulation (General Python Tips)¶
Searching for list items¶
In Python there are some handy list functions that save you having to search through the list.
Even though you are not looping on the list data python is, so you need to be aware of functions that will slow down your script by searching the whole list.
my_list.count(list_item)
my_list.index(list_item)
my_list.remove(list_item)
if list_item in my_list: ...
Modifying Lists¶
In python we can add and remove from a list, this is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
The most simple way to add onto the end of the list is to use
my_list.append(list_item)
or my_list.extend(some_list)
and the fastest way to
remove an item is my_list.pop()
or del my_list[-1]
.
To use an index you can use my_list.insert(index, list_item)
or list.pop(index)
for list removal, but these are slower.
Sometimes its faster (but more memory hungry) to just rebuild the list.
Say you want to remove all triangular polygons in a list.
Rather than…
polygons = mesh.polygons[:] # make a list copy of the meshes polygons
p_idx = len(polygons) # Loop backwards
while p_idx: # while the value is not 0
p_idx -= 1
if len(polygons[p_idx].vertices) == 3:
polygons.pop(p_idx) # remove the triangle
It’s faster to build a new list with list comprehension.
polygons = [p for p in mesh.polygons if len(p.vertices) != 3]
Adding List Items¶
If you have a list that you want to add onto another list, rather than…
for l in some_list:
my_list.append(l)
Use…
my_list.extend([a, b, c...])
Note that insert can be used when needed, but it is slower than append especially when inserting at the start of a long list.
This example shows a very sub-optimal way of making a reversed list.
reverse_list = []
for list_item in some_list:
reverse_list.insert(0, list_item)
Python provides more convenient ways to reverse a list using the slice method, but you may want to time this before relying on it too much:
some_reversed_list = some_list[::-1]
Removing List Items¶
Use my_list.pop(index)
rather than my_list.remove(list_item)
This requires you to have the index of the list item but is faster since remove()
will search the list.
Here is an example of how to remove items in 1 loop, removing the last items first, which is faster (as explained above).
list_index = len(my_list)
while list_index:
list_index -= 1
if my_list[list_index].some_test_attribute == 1:
my_list.pop(list_index)
This example shows a fast way of removing items, for use in cases where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last.
pop_index = 5
# swap so the pop_index is last.
my_list[-1], my_list[pop_index] = my_list[pop_index], my_list[-1]
# remove last item (pop_index)
my_list.pop()
When removing many items in a large list this can provide a good speedup.
Avoid Copying Lists¶
When passing a list/dictionary to a function, it is faster to have the function modify the list rather than returning a new list so python doesn’t have to duplicate the list in memory.
Functions that modify a list in-place are more efficient than functions that create new lists.
This is generally slower so only use for functions when it makes sense not to modify the list in place.
>>> my_list = some_list_func(my_list)
This is generally faster since there is no re-assignment and no list duplication.
>>> some_list_func(vec)
Also note that passing a sliced list makes a copy of the list in python memory.
>>> foobar(my_list[:])
If my_list was a large array containing 10000’s of items, a copy could use a lot of extra memory.
Writing Strings to a File (Python General)¶
Here are 3 ways of joining multiple strings into one string for writing. This also applies to any area of your code that involves a lot of string joining.
String addition
-
this is the slowest option, don’t use if you can help it, especially when writing data in a loop.
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
String formatting
-
use this when you are writing string data from floats and ints.
>>> file.write("%s %s %s\n" % (str1, str2, str3))
String join() function
use to join a list of strings (the list may be temporary). In the following example, the strings are joined with a space ” ” in between, other examples are “” or “, “.
>>> file.write(" ".join([str1, str2, str3, "\n"]))
Join is fastest on many strings, string formatting is quite fast too (better for converting data types). String arithmetic is slowest.
Parsing Strings (Import/Exporting)¶
Since many file formats are ASCII, the way you parse/export strings can make a large difference in how fast your script runs.
There are a few ways to parse strings when importing them into Blender.
Parsing Numbers¶
Use float(string)
rather than eval(string)
, if you know the value will be an int then int(string)
,
float() will work for an int too but it is faster to read ints with int().
Checking String Start/End¶
If you are checking the start of a string for a keyword, rather than…
>>> if line[0:5] == "vert ": ...
use…
>>> if line.startswith("vert "):
Using startswith()
is slightly faster (approx 5%) and also avoids a possible
error with the slice length not matching the string length.
my_string.endswith(“foo_bar”) can be used for line endings too.
If you are unsure whether the text is upper or lower case, use the lower()
or upper()
string function.
>>> if line.lower().startswith("vert ")
Use try/except Sparingly¶
The try statement is useful to save time writing error checking code.
However try is significantly slower than an if since an exception has to be set each time, so avoid using try in areas of your code that execute in a loop and runs many times.
There are cases where using try is faster than checking whether the condition will raise an error, so it is worth experimenting.
Value Comparison¶
Python has two ways to compare values a == b
and a is b
,
the difference is that ==
may run the objects comparison function __cmp__()
whereas is
compares identity,
this is, that both variables reference the same item in memory.
In cases where you know you are checking for the same value which is referenced from multiple places, is
is faster.
Time Your Code¶
While developing a script it is good to time it to be aware of any changes in performance, this can be done simply.
import time
time_start = time.time()
# do something...
print("My Script Finished: %.4f sec" % (time.time() - time_start))


This quiz board project simulates a real paper work exam done in classes by students. The student/user is able to see multi-choice questions when the website loads. Each question has a number of points awarded when scored right. The
user is able to tick the correct answer through a radio button and submit answers when done taking the quiz. Once the answers are submitted, the student/user gets the results of what they scored and they are able to know their overall
performance using a predefined criteria.
For each question select the answer by clicking the radio button. After answering the first three questions, click next to go to the next set. Once Done, click SUBMIT and view results
4. The population of a country increased by an average of 2% per year from 2000 to 2003. If the population of this country was 2 000 000 on December 31, 2003, then the population of this country on January 1, 2000, to the nearest
thousand would have been
5. f is a quadratic function whose graph is a parabola opening upward and has a vertex on the x-axis. The graph of the new function g defined by g(x) = 2 - f(x - 5) has a range defined by the interval
6. f is a function such that f(x) < 0. The graph of the new function g defined by g(x)=| f(x) | is a reflection of the graph of f 2(x / 4) is equal to


Psalm 90:12-17
- So teach us to number our days, that we may apply our hearts unto wisdom.
- Return, O Lord, how long? and let it repent thee concerning thy servants.
- O satisfy us early with thy mercy; that we may rejoice and be glad all our days.
- Make us glad according to the days wherein thou hast afflicted us, and the years wherein we have seen evil.
- Let thy work appear unto thy servants, and thy glory unto their children.
- And let the beauty of the Lord our God be upon us: and establish thou the work of our hands upon us; yea, the work of our hands establish thou it.


Exploring Optimization Convergence
27 Dec 2017Exploring Optimization Convergence
In the previous chapter we created a simple single variable linear regression model to fit a data set. While the Python code was actually fairly short and simple, I did gloss over some details related to the optimization, and I hope to use this short chapter to answer some dangling questions about it. Since this chapter doesn't introduce new models or concepts you can skip it (or come back later) if you prefer. However, getting a feel for optimization is useful for training just about any model, not just the single variable linear regression model, and this chapter should give you insight that is useful for the rest of this guide and just about any machine learning you do.
To explore optimization we are going to exactly copy the code from the previous chapter, and experiment with it. To review, let's look at the part of the code from before that performed the optimization (just look at the previous chapter if you need to review the entire thing):
# Setup the optimizer object, so it optimizes a and b.
optimizer = optim.Adam([a, b], lr=0.2)
# Main optimization loop
for t in range(10000):
# Set the gradients to 0.
optimizer.zero_grad()
# Compute the current predicted y's from x_dataset
y_predicted = model(x_dataset)
# See how far off the prediction is
current_loss = loss(y_predicted, y_dataset)
# Compute the gradient of the loss with respect to a and b.
current_loss.backward()
# Update a and b accordingly.
optimizer.step()
print(f"t = {t}, loss = {current_loss}, a = {a.item()}, b = {b.item()}")
The main unanswered questions to address are:
- I said that the learning rate affects how large of steps the optimization algorithm takes in one unit of time. But how do we choose an appropriate value for the learning rate, such as
0.2
? - What is this
AdamOptimizer
exactly, are there other choices for optimizers, and how do they differ? - Currently this code runs for
10000
iterations, and that seems good enough to fully optimizeL
. But how do we choose this appropriate amount of time for training?
There aren't exact or easy answers to the above questions, but answering these questions is made even harder by the fact that we can not effectively visualize the training progress with the code we have. Currently we have some print(...)
statements, which is good enough to see that the training error is decreasing, but not much more than that. Let's start with learning how to visualize training, since this will help us address the other questions and give us a deeper intuition about optimization.
How to visualize training progress
Extracting hyperparameters
One of the simplest ways to visualize training progress is to plot the value of the loss function over time. We could certainly plot the value of the loss function using matplotlib, like we plotted the data set. But PyTorch actually lets us plot training progress conveniently in real time by communicating with a tool called TensorBoard. It's pretty handy, but first we need to do some work to refactor our current code.
The first thing I'd like to do is move hyperparameters to the top of the script. What exactly are hyperparameters? They are parameters that affect how the training of the model proceeds, but are not part of the model itself. For example, \(a\) and \(b\) are parameters, while the learning rate \(\alpha\) is a hyperparameter. The hyperparameters we have are:
- The learning rate, currently
0.2
. - The number of training iterations, currently
10000
. - The choice of optimization routine, currently
tf.train.AdamOptimizer
(This isn't often thought of as a hyperparameter, but here we'll think of it as one).
So, we can just put these into constants at the top of the code. Also, we are going to change these values to give us a simpler starting point:
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.optim as optim
### Hyperparameters ###
LEARNING_RATE = 0.000001 # Much smaller training rate, to make sure the optimization is at least reliable.
NUM_ITERS = 20000 # Twice as many training iterations, just gives us more room to experiment later.
OPTIMIZER_CONSTRUCTOR = optim.SGD # This is the simplest optimization algorithm.
# .. all the rest of the code, hyperparameter constants properly substituted
Installing TensorBoard
Next we need to actually install TensorBoard on our system. The following command should do it:
pip3 install tb-nightly future
Setting up TensorBoard
Now, we need to add some code to configure TensorBoard for our model. We will need to add a new import:
from torch.utils.tensorboard import SummaryWriter
We want to tell PyTorch where to save a log of all the parameter and loss values. We setup the log location based on the values of the hyperparameters:
# ... above this is where loss is defined
### TensorBoard Writer Setup ###
log_name = f"{LEARNING_RATE}, {OPTIMIZER_CONSTRUCTOR.__name__}"
writer = SummaryWriter(log_dir=f"runs/{log_name}")
print("To see tensorboard, run: tensorboard --logdir=runs/")
# ... below this is where we create the optimizer and session
The point of basing the log location names on the hyperparameter values is so that we can later compare logs that used different hyperparameters.
The last thing we need to do is make PyTorch actually write the values of a
, b
and the loss to the log as training progresses. In our training code before we had a print
statement that showed how training was going, but now we can replace it (or keep it, you choose):
# Main optimization loop
for t in range(NUM_ITERS):
# Set the gradients to 0.
optimizer.zero_grad()
# Compute the current predicted y's from x_dataset
y_predicted = model(x_dataset)
# See how far off the prediction is
current_loss = loss(y_predicted, y_dataset)
# Compute the gradient of the loss with respect to a and b.
current_loss.backward()
# Update a and b accordingly.
optimizer.step()
# This is where we write the current values of a, b, and loss to the log.
# global_step=t tells tensorboard at what step of the training this is.
writer.add_scalar('a', a, global_step=t)
writer.add_scalar('b', b, global_step=t)
writer.add_scalar('L', current_loss, global_step=t)
# After we are done with the writer, we should close the log file.
writer.close()
And as a final touch, we can also delete or comment out the code that plots the data set, since it reduces the amount of clicking we have to do when trying different hyperparameters. The complete modified code should look something like this:
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.optim as optim
from torch.utils.tensorboard import SummaryWriter
### Hyperparameters ###
LEARNING_RATE = 0.000001 # Much smaller training rate, to make sure the optimization is at least reliable.
NUM_ITERS = 20000 # Twice as many training iterations, just gives us more room to experiment later.
OPTIMIZER_CONSTRUCTOR = optim.SGD # This is the simplest optimization algorithm.
# Load the data
D = pd.read_csv("homicide.csv")
x_dataset = torch.tensor(D.age.values, dtype=torch.float)
y_dataset = torch.tensor(D.num_homicide_deaths.values, dtype=torch.float)
### Model definition ###
# First we define the trainable parameters a and b
a = torch.randn(1, requires_grad=True) # requires_grad means it is trainable
b = torch.randn(1, requires_grad=True)
# Then we define the prediction model
def model(x_input):
return a * x_input + b
### Loss function definition ###
def loss(y_predicted, y_target):
return ((y_predicted - y_target)**2).sum()
### TensorBoard Writer Setup ###
log_name = f"{LEARNING_RATE}, {OPTIMIZER_CONSTRUCTOR.__name__}"
writer = SummaryWriter(log_dir=f"runs/{log_name}")
print("To see tensorboard, run: tensorboard --logdir=runs/")
### Training the model ###
# Setup the optimizer object, so it optimizes a and b.
optimizer = OPTIMIZER_CONSTRUCTOR([a, b], lr=LEARNING_RATE)
# Main optimization loop
for t in range(NUM_ITERS):
# Set the gradients to 0.
optimizer.zero_grad()
# Compute the current predicted y's from x_dataset
y_predicted = model(x_dataset)
# See how far off the prediction is
current_loss = loss(y_predicted, y_dataset)
# Compute the gradient of the loss with respect to a and b.
current_loss.backward()
# Update a and b accordingly.
optimizer.step()
writer.add_scalar('a', a, global_step=t)
writer.add_scalar('b', b, global_step=t)
writer.add_scalar('L', current_loss, global_step=t)
writer.close()
Using TensorBoard
With the Python code prepared, we can now run it and use TensorBoard to visualize the training. First, run the Python code as usual, using Terminal, or your IDE. This will write logs to runs/{log_name}
(relative to the directory from where you run the code). Now, we can open this up with TensorBoard, by running this command in Terminal in the same directory as you run your Python code from:
# Make sure you cd first to the directory that contains runs/ (probably where you .py file is)
tensorboard --logdir=runs/
Once you run that command, go to http://localhost:6006 in your web browser, and you should see plots of L
, a
, and b
as the training progressed. With the hyperparameter choices from above, the plots should look like:
Interpreting the TensorBoard plots
Ok, so now we have some plots showing the progression of L
, a
, and b
. What can these plots tell us? Well, with the current choice of LEARNING_RATE = 0.000001
, the plot for L
clearly continues to decrease continually during training. This is good, since this means that the optim.SGD
is doing it's job of decreasing the value of the loss function. However, the loss function continues to decrease quickly even towards the end of training: it is reasonable to expect that the loss function would continue to decrease substantially if we continued to train for more iterations. Therefore, we have not found the minimum of the loss function.
To remedy this, we could do one of 3 things: run the training for more iterations, increase the learning rate, or experiment with another optimization algorithm. We don't want to train for more iterations unless we have to, since that just takes more time, so we will start with increasing the learning rate.
Increasing the learning rate
Currently the learning rate is 0.000001
, and is too small. A pretty easy way to try new learning rates is to go roughly by powers of 10. For now, we can try 0.000001
, 0.000005
, 0.00001
. For each of these, you can just tweak the LEARNING_RATE
constant, and re-run the code. You don't need to re-run the TensorBoard command (but you can), but make sure to reload the http://localhost:6006 page once you do all the runs. You should get plots that look like:
We can clearly see the improvement by increasing the learning rate. The final loss obtained with a learning rate of 0.00001
is much smaller than our original loss obtained with a learning rate of 0.000001
. In addition, we can see that the loss is decreasing more slowly at the end of training. However, the loss function still hasn't converged, as it is still decreasing significantly. Again, to fix this we could train for longer, but as before we can try increasing the learning rate even more. We can try a learning rate of 0.00005
, and we get this:
Huh? No plot!?!?? If you mouse over the L
plot, TensorBoard will say that the value of L
is NaN (not a number). What gives? Well, if the learning rate is too big then optim.SGD
can explode: a
and b
(and consequently L
) increase to infinity and become NaN. What "too big" is depends on the specific problem.
At this point there isn't a lot more that we can do by just tweaking the learning rate: it's either too big and causes the optimization to explode, or is too small to achieve convergence in 20000
iterations. We can certainly try more learning rates between 0.00001
and 0.00005
, but it won't be a ton better than what we already have.
Using different optimization algorithms
So far we have been using optim.SGD
. It is the simplest, classic way to iteratively train machine learning models. As discussed in the previous chapter, it is like moving a ball downhill, according to the current slope (aka the derivative). Generally, gradient descent is part of a class of optimization algorithms called first-order methods, since it uses only information from the first derivative of the loss function, and not higher-order derivatives. First-order methods are currently the dominant way to train most machine learning models.
In fact, there are many first order methods, other than simple gradient descent. Most of them are designed to offer an advantage over other first-order methods via speed to find convergence, reliability, ease of use, etc. For a fairly in-depth exploration, see this blog post. To see the different optimization algorithms that are built-in to PyTorch, see the documentation here. In this list, you can see the optim.Adam
that we used before, and the classic optim.SGD
that we just tried.
We can experiment with any number of these. Here, I'll demonstrate experimenting with optim.Adagrad
, but feel free to play around with any of them. To use optim.Adagrad
we just need to change OPTIMIZER_CONSTRUCTOR
, and set LEARNING_RATE
back to 0.000001
for good measure:
LEARNING_RATE = 0.000001
OPTIMIZER_CONSTRUCTOR = optim.Adagrad
Running this we see:
Well, this is disappointing: L
did not seem to decrease at all during training. The problem is that the learning rate used by gradient descent is really an entirely different learning rate from the Adagrad one: conceptually they are similar, but are on entirely different scales numerically. So, we just need to try different learning rates for Adagrad now. Since the value of L
stayed constant with this very small learning rate, we expect that we need to try much larger learning rates for Adagrad. In fact, by trying learning rates of 0.5, 1, and 5, we get these plots:
Now this is looking like progress! For the first time we start to get a sense of the loss rapidly decreasing, and then slowing down substantially. In addition, the final value of a
is now negative (which we know is correct) compared to previous runs which ended either positive or close to zero. However, by looking at the plots for a
and b
(and to a lesser degree L
) we can see that we still haven't achieved convergence: a
and b
haven't stopped changing substantially at the end of training. So, time to increase the learning rate even more! Before doing so, I am going to delete the logs of previous runs, except for the Adagrad run with a learning rate of 5, so that we can read the plots more clearly:
# This will delete logs of all the runs
rm -rf runs/
# Or, you can delete a specific run, for example:
rm -rf runs/10,\ Adagrad/
By trying learning rates of 10 and 50, we finally achieve convergence:
Qualitatively, this looks like convergence (with a learning rate of 10, and certainly with a learning rate of 50) since the progress that Adagrad is making on decreasing L
(and adjusting a
and b
) has hit a brick wall: no matter how long we run Adagrad, we can't seem to get a loss function value lower than about \(3.9296 \cdot 10^4 \), and similarly for the values of a
and b
. We've finally trained our model completely.
Unfortunately, I don't know of an easy way to intuitively understand the differences between Adagrad, Adam, and other first-order methods. This blog post does give some mathematical analysis that explains what each algorithm tries to improve upon, and some reasoning for choosing an algorithm, but it can be tricky to apply to real problems. In general, you can always start with the simplest algorithm (gradient descent), and if it isn't converging quickly enough for you, then you can switch to a more sophisticated algorithm, such as Adagrad, Adam, or others.
Concluding Remarks
The experimental nature of this chapter should illustrate the practicalities of machine learning: a lot of cutting-edge machine learning currently involves running multiple experiments to try to find the best combination of hyperparameters. There isn't a golden rule for choosing the optimization algorithm and hyperparameters, but hopefully this chapter demonstrates how to alter the algorithm and hyperparameters in PyTorch and monitor convergence using TensorBoard. The most important takeaways are:
- Learning how to use TensorBoard
- Recognizing convergence
- Recognizing the symptoms of too small of a learning rate
- Recognizing the symptoms of too large of a learning rate
In future chapters I won't include the code specifically for TensorBoard (unless it is important to that chapter) since I don't want it to get in the way of actual models, but I would highly encourage you to insert your own TensorBoard summary code, and monitor plots of convergence in TensorBoard, since it is useful both educationally and practically.
Challenge Problems
- Experiment on your own with a few other built-in PyTorch optimization algorithms, and try different learning rates. If you prefer a more focused goal, try to beat my configuration of an Adagrad optimizer with a learning rate of 50, and converge faster. Also note that some optimization algorithms have additional hyperparameters other than the learning rate. See the PyTorch documentation for information about these.
- One other cause of slow convergence for the homicide rate linear regression is the somewhat extreme scaling of the problem. The \(y\) variable is a whole order of magnitude greater than the \(x\) variable, and this affects optimization. We will actually look at this problem specifically in chapter 2.4, but for now you can experiment on your own with one solution: instead of using the \(x\) and \(y\) data directly from the data set, modify them first to rescale them. A quick, hacky way is to modify the code that loads the data, so that \(x\) and \(y\) vary between 0 and 1:
# Load the data, and convert to 1x30 vectors
D = pd.read_csv("homicide.csv")
# 21 and 50 are the min and max of x_data
x_data = (torch.tensor(D.age.values, dtype=torch.float) - 21.0) / (50.0 - 21.0)
# 196 and 653 are the min and max of y_data
y_data = (torch.tensor(D.num_homicide_deaths.values, dtype=torch.float) - 196.0) / (653.0 - 196.0)
On your own, add this code and see if you can achieve convergence using only gradient descent. You can also see how quickly you can achieve convergence using a more advanced algorithm such as Adam.
Complete Code
The complete code including TensorBoard summaries, and using Adagrad is available on GitHub and directly below. Note that this code lacks the plotting of the data and the linear regression line:
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.optim as optim
from torch.utils.tensorboard import SummaryWriter
### Hyperparameters ###
LEARNING_RATE = 50 # Much smaller training rate, to make sure the optimization is at least reliable.
NUM_ITERS = 20000 # Twice as many training iterations, just gives us more room to experiment later.
OPTIMIZER_CONSTRUCTOR = optim.Adagrad # This is the simplest optimization algorithm.
# Load the data
D = pd.read_csv("homicide.csv")
x_dataset = torch.tensor(D.age.values, dtype=torch.float)
y_dataset = torch.tensor(D.num_homicide_deaths.values, dtype=torch.float)
### Model definition ###
# First we define the trainable parameters a and b
a = torch.randn(1, requires_grad=True) # requires_grad means it is trainable
b = torch.randn(1, requires_grad=True)
# Then we define the prediction model
def model(x_input):
return a * x_input + b
### Loss function definition ###
def loss(y_predicted, y_target):
return ((y_predicted - y_target)**2).sum()
### TensorBoard Writer Setup ###
log_name = f"{LEARNING_RATE}, {OPTIMIZER_CONSTRUCTOR.__name__}"
writer = SummaryWriter(log_dir=f"runs/{log_name}")
print("To see tensorboard, run: tensorboard --logdir=runs/")
### Training the model ###
# Setup the optimizer object, so it optimizes a and b.
optimizer = OPTIMIZER_CONSTRUCTOR([a, b], lr=LEARNING_RATE)
# Main optimization loop
for t in range(NUM_ITERS):
# Set the gradients to 0.
optimizer.zero_grad()
# Compute the current predicted y's from x_dataset
y_predicted = model(x_dataset)
# See how far off the prediction is
current_loss = loss(y_predicted, y_dataset)
# Compute the gradient of the loss with respect to a and b.
current_loss.backward()
# Update a and b accordingly.
optimizer.step()
writer.add_scalar('a', a, global_step=t)
writer.add_scalar('b', b, global_step=t)
writer.add_scalar('L', current_loss, global_step=t)
writer.close()


Measure introduced in Ohio would ban abortion outright
by JULIE CARR SMYTHCOLUMBUS, Ohio (AP) - A group of conservative lawmakers in Ohio has introduced a bill to outlaw abortion outright.
State Rep. Candice Keller is a Republican from Middletown and says backers are tired of taking an incremental approach to ending abortion.
The legislation was introduced Thursday. It declares a fetus a person and would subject doctors who terminate pregnancies to potential murder charges.
TOP STORIES
Adam Schiff cracking under 'point of order' pressure
Focus groups show undecided voters think impeachment is going to 'backfire' on Dems
Franklin Graham calls on nation to pray for Trump as impeachment effort gains speed
The bill appears to make an exception for the life of the mother.
Ohio is among states that have passed restrictive abortion laws in recent years in hopes of sparking a legal challenge that would overturn Roe v. Wade.
The conservative majority on the U.S. Supreme Court has emboldened abortion opponents.
The Ohio bill is opposed by abortion rights groups. The state’s largest anti-abortion group is remaining neutral.
Sign up for Daily Newsletters
Copyright © 2019 The Washington Times, LLC.
Please read our comment policy before commenting.


The following content is loaded by using load() methid
Vibrating bicycle senses traffic
Weird and wonderful world of tech
Samsung Galaxy S6 leak hints at a slim, glass-backed body
Google Officially Unveils Travel Sites-Killer
Load


ruitzy
Vruitzy
Home
Products
Profile
Cart
Logout
My Cart
CUSTOMER PAYMENT
SELECT PAYMENT METHOD
PAYMENT ID
TOTAL PAYMENT
PHONE NUMBER
Vruitzypay
Gopay
OVO


Insert a Name
Enter a valid email address
Enter a message subject
Enter a message
Thank you. I'll get back to you as soon as possible.
Sorry, an error has occured. Please try again later.


About
Data Science/AI specialist with excellent presentation and critical thinking skills, passionate about studying how to improve performance. Seeking to leverage data analytical/management skills to improve corporate performance as a Data Professional. I am highly skilled in data cleaning using microsoft Excel and google Spreadsheet, data visualization and story telling for effective communication of insights using Microsoft PowerBI and Tableau
- Birthday: 1 July
- Email<EMAIL_ADDRESS>- Phone: +2348136189418
Amarachukwu is also a Microsoft Administrator, well versed in cloud computing. Highly trained and skilled in Windows, Microsoft Office 365, Microsoft Teams, Microsoft Exchange, SQL, Unix PowerShell, collaboration software such as SharePoint and OneDrive Online
Skills
Resume
Summary
Amarachukwu Eze
Innovative and deadline-driven Data Professional with Experience in cleaning, analyzing and visualizing data using various analytical tools like Tableau, Power BI, Excel, and ML Techniques.
- Lekki, Nigeria
- +23436189418
-<EMAIL_ADDRESS>Education
Master in Artificial Intelligence
2020 - 2022
IUBH International Univerisity of Applied Sciences, Germany
Bachelor of Engineering
2011 - 2016
University of Nigeria, Nsukka
Awards
- 1st Runner-up, Microsoft Leap Hackathon
- 2016 Best Project. Faculty of Engineering, UNN
- Best Graduating Female Exco, NFCS, UNN
Trainings & Certifications
- Microsoft Certified Professional Azure AI fundamentals
- Microsoft Certified Professional Axure Data fundamentals
- Intermediate Machine Learning Course on Kaggle
- Udacity Introduction to Machine Learning on Azure
- YAAW Women in Machine Learning Conference, Participant
- Microsoft Leap Apprenticeship
Extracurricular Activities
Data Analysis Virtual Learning Program (July 2021)
Participated in an automated virtual program where I learned and implemented the following with several mentors in the Data Analytics field
- Learned how to determine a business problem
- Learned a number of data cleaning methods using Excel/Google Sheets.
- Created Pivot Tables to show key insights within dataset
- Learned basic functionality of Tableau and created data visualizations.
- Earned a Team Leader Badge by assisting my peers throughout the program
Professional Experience
PwC PowerBI Virtual Experience (2021)
PwC
- Transformed data into usable information, which was then formed as part of a business plan to drive growth.
- Defined relevant KPIs in hiring, promotion, performance and turnover
- Created a dashboard that reveals the KPIs of a call center agents as well as their customers
- Explained the findings of why customers have terminated their contract but they might consider returning to the company
- Worked on a HR project for top management by creating an additional dashboard in diversity and inclusion
Data Science & AI Fellow
2021
Women Techsters/Tech4Dev
- Cleaned and prepared data for analyzing the effect of covid-19 on education in Africa using Microsoft Excel.
- Documented Numpy and Pandas basic/commonly used functions and methods in Data Science and Data Analysis.
- Utilized Tableau and Microsoft PowerBI to build dashboards and create reports on the number of Subscribers for an online education platform
- Built a tandem app that would provide a platform for students and teachers to interact using python.
- Carried out a data science & analytics research on effect of covid-19 on education in Africa.
- Predicted Titanic accident survival with 77% accuracy: aiming for 95 - 97% accuracy for other models for better decision and problem solving
Microsoft Support Engineer (CONCIERGE)
2019 - 2020
Tek-Experts
- Provided a 1st class customer support satisfaction on M365 administrative services including SharePoint, Teams, Licensing, EXO, OneDrive, and Identity management to International Microsoft clients.
- Acted as the primary technical contact, delivered advanced technical troubleshooting on M365 products, and problem-solving solutions for corporate customers that include issues escalated to the highest level of management.
- Managed clients through a series of actions, either via phone or email until they have solved a technical issue
- Received numerous 100% satisfied customer surveys and feedback. Maintained anywhere from about 5 to 8 service requests simultaneously.
- Collaborated with subject matter experts and escalation managers when additional support was needed to resolve customer issues.


MdSlideToggleModule
Official Documentation
<md-slide-toggle>
is an on/off control that can be toggled via clicking or dragging.
The slide-toggle behaves similarly to a checkbox, though it does not support
an indeterminate state like <md-checkbox>
.
Note: the sliding behavior for this component requires that HammerJS is loaded on the page.
The slide-toggle label is provided as the content to the <md-slide-toggle>
element.
If you don't want the label to appear next to the slide-toggle,
you can use aria-label
or aria-labelledby
to specify an appropriate label.
<md-slide-toggle>
is compatible with @angular/forms and supports both FormsModule
and ReactiveFormsModule.
The color of a <md-slide-toggle>
can be changed by using the color property.
By default, slide-toggles use the theme's accent color. This can be changed to 'primary' or 'warn'.
<md-slider>
allows for the selection of a value from a range via mouse, touch,
or keyboard, similar to <input type="range">
.
Note: the sliding behavior for this component requires that HammerJS is loaded on the page.
By default the minimum value of the slider is 0, the maximum value is 100, and the thumb moves in increments of 1. These values can be changed by setting the min, max, and step attributes respectively. The initial value is set to the minimum value unless otherwise specified.
<md-slider min="1" max="5" step="0.5" value="1.5">
</md-slider>
By default sliders are horizontal with the minimum value on the left and the maximum value on the right. The vertical attribute can be added to a slider to make it vertical with the minimum value on bottom and the maximum value on top.
<md-slider vertical>
</md-slider>
An invert attribute is also available which can be specified to flip the axis that the thumb moves along. An inverted horizontal slider will have the minimum value on the right and the maximum value on the left, while an inverted vertical slider will have the minimum value on top and the maximum value on bottom.
<md-slider invert>
</md-slider>
By default, the exact selected value of a slider is not visible to the user. However, this value can be added to the thumb by adding the thumbLabel attribute.
The Material Design spec recommends using the thumbLabel attribute (along with tickInterval="1") only for sliders that are used to display a discrete value (such as a 1-5 rating).
<md-slider thumbLabel tickInterval="1">
</md-slider>
By default, sliders do not show tick marks along the thumb track. This can be enabled using the tickInterval attribute. The value of tickInterval should be a number representing the number of steps between between ticks. For example a tickInterval of 3 with a step of 4 will draw tick marks at every 3 steps, which is the same as every 12 values.
<md-slider step="4" tickInterval="3">
</md-slider>
The tickInterval can also be set to auto which will automatically choose the number of steps such that there is at least 30px of space between ticks.
<md-slider tickInterval="auto">
</md-slider>
The slider will always show a tick at the beginning and end of the track. If the remaining space doesn't add up perfectly the last interval will be shortened or lengthened so that the tick can be shown at the end of the track.
The Material Design spec recommends using the tickInterval attribute (set to 1 along with the thumbLabel attribute) only for sliders that are used to display a discrete value (such as a 1-5 rating).
The slider has the following keyboard bindings:
| Key | Action |
|---|---|
| Right arrow | Increment the slider value by one step (decrements in RTL). |
| Up arrow | Increment the slider value by one step. |
| Left arrow | Decrement the slider value by one step (increments in RTL). |
| Down arrow | Decrement the slider value by one step. |
| Page up | Increment the slider value by 10 steps. |
| Page down | Decrement the slider value by 10 steps. |
| End | Set the value to the maximum possible. |
| Home | Set the value to the minimum possible. |
MdSlideToggleModule
Two-state control, which can be also called `switch`.
| Name | Description |
|---|---|
|
@Input()
name |
Name value will be applied to the input element if present |
|
@Input()
id |
A unique id for the slide-toggle input. If none is supplied, it will be auto-generated. |
|
@Input()
ariaLabel |
Used to set the aria-label attribute on the underlying input element. |
|
@Input()
ariaLabelledby |
Used to set the aria-labelledby attribute on the underlying input element. |
|
@Input()
disabled |
Whether the slide-toggle is disabled. |
|
@Input()
required |
Whether the slide-toggle is required. |
|
@Output()
change |
An event will be dispatched each time the slide-toggle changes its value. |
inputId |
Returns the unique id for the visual hidden input. |
|
@Input()
checked |
Whether the slide-toggle is checked. |
|
@Input()
color |
The color of the slide-toggle. Can be primary, accent, or warn. |
| focus | |
|---|---|
| Focuses the slide-toggle. |
| toggle | |
|---|---|
| Toggles the checked state of the slide-toggle. |
| Name | Description |
|---|---|
source |
|
checked |


Happy Teacher's Day Dharmendra sir!
You have been a wonderful teacher and a very dear friend. I will miss your classes but I have all that you taught me stored safely in my mind and my heart. Thank you for the inspiration and always believing in me, even when sometimes I didn't believe in myself.
You showed me the path to success: believe in yourself, be confident in your abilities and always strive to achieve your own personal best. Thank you Dharmendra sir for being such an inspiration!
Made With


Eight minutes added to Subuh prayer times in Federal Territories
KUALA LUMPUR, Nov 29 — There will be an addition of eight minutes to Subuh (dawn) prayer times for the Federal Territories of Kuala Lumpur, Putrajaya and Labuan beginning tomorrow.
Federal Territories Mufti Datuk Seri Zulkifli Mohamad Al-Bakri said the matter was approved at the 116th National Council of Islamic Religious Affairs Committee meeting on November 20 and 21.
The matter also had the consent of The Yang di-Pertuan Agong Al-Sultan Abdullah Ri’ayatuddin Al-Mustafa Billah Shah, he said via his official Twitter page today.
“We took note of the eight minutes added to Subuh prayer times throughout Selangor,” he said.
Yesterday, the Selangor Islamic Religious Department (Jais) announced that there would be an eight minutes addition to Subuh prayer times throughout the state, starting from today. — Bernama


A Look at How the American Ratings Board Rates Video Games
by Luke PlunkettDanny O’Dwyer’s Noclip documentary series recently got the chance to visit the ESRB – the US Entertainment Software Rating Board – and see just how the organisation works. It's basically the American equivalent of PEGI, and while their rating system is slightly different, this video still provides an interesting look into the world of video game ratings.
The 44-minute video touches on a number of topics. First, it’s a pretty good history of the ESRB, detailing their origins in the wake of social and political hysteria surrounding video game violence in the 1990s.
Next, it goes behind the scenes, meets several key employees and shows not just how the ESRB works in the US, but how they cooperate with other international ratings boards as well.
Finally, and perhaps least satisfactorily, it raises the question of what the ESRB is going to do in the future, and how they’re reacting to more contemporary controversies like lootboxes. Here, the ESRB’s answers aren’t going to impress anyone hoping the organisation is as opposed to publisher’s predatory pricing strategies as consumers are.


wiki / init / changing-init Edit this page
Edited (4dad319) at 2020-08-16 by Alejandro Sior
Changing Init Systems
________________________________________________________________________________
KISS' default init system and service manager are provided by busybox. The
service manager being an independent implementation of runit's utilities. This
default should work with all system configurations though one may still wish to
swap to the init system and service manager of their choosing.
This is very easily done via the package manager's alternatives system as
nothing is tightly coupled or dependent on a specific init or service manager.
[0.0] Index
________________________________________________________________________________
- Rebooting after switching init systems [1.0]
- runit [2.0]
- Hummingbird [3.0]
- Setting up runsvdir [3.1]
[1.0] Rebooting after switching init systems
________________________________________________________________________________
After switching init systems, your running init system may not accept the
new poweroff commands. You will need to reboot/poweroff using the running init's
utilities for the new utilities to work.  Some people find it useful to have one, such as runsvdir.
+--------------------------------------------------------------------------+
| |
| $ mkdir /etc/rc.d |
| $ echo 'runsvdir -P /var/service &' > /etc/rc.d/runsvdir.boot |
| |
+--------------------------------------------------------------------------+
________________________________________________________________________________
Dylan Araps (C) 2019-2020
kiss-community (C) 2020-2021
Dilyn Corner (C) 2021
Linux(R) is the registered trademark of Linus Torvalds in the U.S. and
other countries.


19.09.2013 - version 3.6.1
* fixed some stats in vehicle and weapons tab
* fixed bblog assignments not loading
* fixed board favorites
* fixed xss problem (thx Edvin_1337)
* easteregg
* some minor improvements and preparations for bf4
Alright, another awesome update
But wait, what is that?
Easter egg?
BrainFooLong
Administrator
Hm... Easteregg... Easter... Egg...
Don't know what you mean.
BrainFooLong
Administrator
Mabye something for cooking...

Doesn't say anything
Don't expect me to find it, I suck at these
I_like_Chocolate
haha.PNG
is that the easteregg? }:-D
Topicstarter
Eliittihemuli
Just a new, better title I'd reckon.
ORFK
Global Moderator
maybe you should wait till eastern and than you should try to eat it ;-)
I_like_Chocolate
What da hell? xD
Irody
next easter is on 20.April 2014 :P can't wait till then - so hungry :D
no srsly i can't find this damn easter egg... searching for about 2 hours straight now ;)
BrainFooLong
Administrator
Only real "bblog" fanboys/girls will find it, literally.
 :-( I even looked it up in the .js but I can't read JavaScript . Lol
Georgeto
The easteregg is hard to find, if you dont read the sourcecode.
I_like_Chocolate
When YOU can read it, then say where it is xD
Post edited 2 x times, last by
Georgeto
Georgeto
Hint 1: It doesnt matter where on battlelog you are.
Hint 2: You need more than your mouse and eyes to find it.
Post edited 3 x times, last by
I_like_Chocolate
I_like_Chocolate
Georgeto wrote:
Hint 1: It doesnt matter where on battlelog you are.
Hint 2: You need more than your mouse and eyes to find it.
You don't make that dat easy maan xD
EDIT: does it matter which theme/background I use?
iraqiboy90
I found the script and the text (which is funny), but I can't activate it to see it in action ;)
Topicstarter
Eliittihemuli
I'm going crazy, I don't know what I'm looking for but I know from where
Post edited 1 x times, last by
iraqiboy90
iraqiboy90
Hint 3: it's a word "egg" inside a JS
I found the text but I want to activate it as normal, but I can't.
I_like_Chocolate
I have no clue anymore....
DONT DISTURBE MY MIND!! ;D
iraqiboy90
Give us another hint or I will post the text already ;D
I_like_Chocolate
Whuuut? xD
pacheddu
found it :D
Cool but i preferred the original easter egg
tips: keyboard is the way(or maybe no?)
Post edited 1 x times, last by
kurtextrem
kurtextrem
Ahh, it's a code...
Did I mention I like ..no not konami games.. I like bblog?
Tauthe
FIND IT!! ITS SO EASY!!
I_like_Chocolate
This is awesome!! xDDD
can you add the nuclear one from the past again? xD
Post edited 1 x times, last by
iraqiboy90
iraqiboy90
this? (part of it ;) )
We now shutdown Battlelog for you..................
I_like_Chocolate
jap
Post edited 1 x times, last by
Lumy79
Lumy79
found it!
very nice easter egg! ;)
Post edited 1 x times, last by
CartmaniLP
CartmaniLP
where is it (easter egg) :(
Georgeto
Everywhere on battlelog.com
CartmaniLP
Im blind ._.
Georgeto
You can not see it.
CartmaniLP
And how can i see it :D
I_like_Chocolate
Hints:
-Don't care on which blog site you are
-You need your keyboard
-You have to find a code
Do
you
like BBlog.... eh.. *cough*.. i mean Eastereggs? :D


Border Guard Harlow:
Stop! Stop!  Slow!
I am Harlow, a member of the border patrol. You cannot go any further north from here. Go back!
Quest


You can use this form which will e-mail your Pick Up request for a pending shipment. Of course you can always call us at<PHONE_NUMBER>. Also, you can find a list of available loads here.
Our customers include retailers, general merchandise stores, manufactures, distributors, and wholesalers, among others. Headquartered in Bolwing Green, KY, Piccolo Inc. is a registered S-Corporation.


This is the webbased tool to label images with boxes and landmarks. You can also use Face++ API to prepopulate the points and then adjust them to improve the position by dragging them.
Point Detail
x:
y:
Box Detail
t:
l:
w:
h:
Time Saver
Plot points using following methods and adjust them to improve the accuracy.
Select a file to read landmarks and face box position. (xml, json)


--- layout: paper title: Publications --- Unsupervised Relation Discovery with Sense Disambiguation, , Proceedings of the 50th Annual Meeting of the Association for Computational Linguistics (ACL) 2012 [pdf]
@inproceedings{yao12unsupervised, month={July}, year={2012}, author={Limin Yao and Sebastian Riedel and Andrew McCallum}, bdsk-url-1={http://ciir-publications.cs.umass.edu/pub/web/getpdf.php?id=1032}, booktitle={Proceedings of the 50th Annual Meeting of the Association for Computational Linguistics (ACL)}, title={Unsupervised Relation Discovery with Sense Disambiguation}, }


{% extends "base.html" %} {% block content %}
It looks like you're trying to submit a duplicate answer, or answering a question you haven't been asked. Anyway, we are unable to check the validity of this answer.


Data Arguments Required:
None.
Description:
This restart is established by warn so that handlers of warning conditions have a way to tell warn that a warning has already been dealt with and that no further action is warranted.
Examples:
(defvar *all-quiet* nil) => *ALL-QUIET* (defvar *saved-warnings* '()) => *SAVED-WARNINGS* (defun quiet-warning-handler (c) (when *all-quiet* (let ((r (find-restart 'muffle-warning c))) (when r (push c *saved-warnings*) (invoke-restart r))))) => CUSTOM-WARNING-HANDLER (defmacro with-quiet-warnings (&body forms) `(let ((*all-quiet* t) (*saved-warnings* '())) (handler-bind ((warning #'quiet-warning-handler)) ,@forms *saved-warnings*))) => WITH-QUIET-WARNINGS (setq saved (with-quiet-warnings (warn "Situation #1.") (let ((*all-quiet* nil)) (warn "Situation #2.")) (warn "Situation #3."))) >> Warning: Situation #2. => (#<SIMPLE-WARNING 42744421> #<SIMPLE-WARNING 42744365>) (dolist (s saved) (format t "~&~A~%" s)) >> Situation #3. >> Situation #1. => NIL
See Also:
Section <IP_ADDRESS> (Restarts), Section <IP_ADDRESS>.2 (Interfaces to Restarts), invoke-restart, muffle-warning (function), warn


A team of students from Olin College that builds and races offroad vehicles for SAE Mini Baja competitions
Phoenix Racing is a student team from Olin College of Engineering. We compete in the intercollegiate Baja SAE design series, which involves designing, building, testing, and racing an off-road vehicle. Our team has 35 undergraduate stdents from all classes. We are an education-oriented team which provides members with long-term experience in an extensive, hands-on engineering project. Additionally, students get to work on design, manufacturing, testing, fixing, and even racing our vehicle!


{% extends 'seanWebapp/base.html' %} {% load static %} {% block stylesheets %} {% endblock %} {% block title %} SEAN Help {% endblock %} {% block textblock %}
{% endblock %} {% block main_panel %}
Work in progress...
We are sorry, this is still a work in progress. Hopefully it will be done soon.


Hello, I'm Chirag, a prospective developer. I try to create exciting Webapps. All of my projects are Open-Source, So Enjoy!


TypeScript
the path to better JavaScript
Introduction
/usr/bin/whoami
Steve Byerly
- Work: Senior Software Engineer @ Intellitect
- Github: github.com/SteveByerly
- Twitter: @SteveByerly
- Python Spokane: github.com/python-spokane • @PythonSpokane
Table of Contents
-
Intro to TypeScript
- Background & Purpose
- Features
- TypeScript: the bad parts
-
Using TypeScript
- Installation & Basic Usage
- Extended Tooling
- Typing Existing JavaScript
- Configuration & Compiling to JavaScript
-
Basic TypeScript
- Types & Interfaces
- Destructuring & Spread
- Classes
-
Advanced TypeScript
- Set Theory and Enums
- Generics and Partials
- Type Narrowing & Type Guards
- Questions
Housekeeping
-
Questions?
Please Ask!. Might take long questions offline. -
Miss Something?
Please let me know. Slides and examples will be available.
https://github.com/SteveByerly/typescript-demo -
do/don't, should/shouldn't, can/can't
My opinions. Do what works best for you.
1 - Intro to TypeScript
1 - Intro to TypeScript
Background & Purpose
1 - Intro to TypeScript
What is TypeScript?
More than just JavaScript with types
"JavaScript that scales"
"TypeScript is a typed superset of JavaScript that compiles to plain JavaScript"
1 - Intro to TypeScript
"JavaScript that scales."
JavaScript is hard
There are many idiosyncrasies to JavaScript. Keeping track of everything when working on your own project is hard enough - exponentially harder with a team.
var username, totalFunds = 100, clickHandler; var handleUser = function handler(name, debitFunds) { var username = name; function setupUser(name) { clickHandler = userHandler; totalFunds = totalFunds - debitFunds; username = name; } setupUser(name); } handleUser('steve', 50); handleUser(50, 'mark'); userHandler();
Demo: ./intro/js-is-hard.js
1 - Intro to TypeScript
"TypeScript is a typed superset of JavaScript that compiles to plain JavaScript."
All JavaScript is TypeScript.
TypeScript, the language, is quite similar to plain JavaScript. It changes the more you opt-in to additional features - some of which are not unique to TypeScript.
In the end, your TypeScript is compiled back to JavaScript
Usually better JavaScript than you or I would write
// app.js var username = 'steve'; function sayHi() { return 'Hi, ' + username; }
// app.ts var username = 'steve'; function sayHi() { return 'Hi, ' + username; }
1 - Intro to TypeScript
Features
1 - Intro to TypeScript
Features at a glance
-
Types
-
Base
boolean, number, string
Object, null, undefined -
Collections
array, enum, "tuple"
-
Special
any, void, never
-
-
Components
- Types
- Interfaces
- Enums
-
Classes
- Inheritance
- Mixins
- Modules
- Namespaces
-
ES-next Features
- Spread / Destructuring
- Iterators / Generators
- Async / Await
- Async / Dynamic Imports
- Decorators
1 - Intro to TypeScript
TypeScipt In-Use
JavaScript
var User = (function () { function User(username) { this.isLoggedIn = true; this.username = username; } User.prototype.logout = function () { this.isLoggedIn = false; return "Goodbye, " + this.username; }; return User; }()); var user = new User("steve");
TypeScript
class User { private username: string; private isLoggedIn = true; constructor(username: string) { this.username = username; } private logout() { this.isLoggedIn = false; return `Goodbye, ${this.username}`; } } const user = new User("steve");
1 - Intro to TypeScript
The Bad Parts
1 - Intro to TypeScript
Haters gonna hate
Typescript is to .NET as Coffeescript was to Ruby.
A bunch of developers who didn't know JavaScript and wanted to find the closest thing they could to what they already knew.
I'll keep writing in the language it compiles down to.
Which would be JavaScript, of course.
If you like typescript so much you might as well stop pretending you write JavaScript and just write in C# like you really want to.
1 - Intro to TypeScript
JS Fatigue ++
-
New/Additional Tooling
- Compilers
- Linters
- Build Pipelines
- IDE configuration
- More dependencies to produce the same output
- Extra effort to keep your project and dependencies updated
- Interoperability with other systems and frameworks
1 - Intro to TypeScript
3rd-Party Type Definitions
https://github.com/DefinitelyTyped/DefinitelyTyped
-
Repo size makes it hard to:
- Find relative issues/bugs
- Search through commit history
- Contribute
- Often difficult to match versions against library versions
- No cler timeline for updates / releases
- Documentation lacking (usually non-existent)
This is seriously awful
1 - Intro to TypeScript
Unit Testing
-
How to test?
- Are tests written in TypeScript?
- Does compilation use the same config as source?
-
What to test?
- Reference your TypeScript files directly?
- Import your compiled library / app?
-
Setup build pipelines for both code and tests
- Loaders for src and test files
- Ensure proper sourcemap configuration
1 - Intro to TypeScript
Developers
When you tell the compiler "trust me, everything's cool"
...but not your team
...and you don't add test cases
const percentUsed = amtRemaining / (<any>initialAmt); const userName = user.profile!.username.strip();
TypeScript provides us a way to avoid many of the pitfalls and unforseen errors in our normal JavaScript.
However...
You still need to be disciplined and maintain good practices, avoiding 'easy' routes as they come up.
Using TypeScript
2 - Using TypeScript
Installation & Basic Usage
2 - Using TypeScript
Installation
Most examples and tutorials have you install TypeScript globally:
$ npm install -g typescript
Make TypeScript a dev dependency of your project instead:
$ npm install --save-dev --save-exact typescript
- Version is now specific to your app
- All contributors will use the same version
- Saving exact version helps avoid unexpected changes
2 - Using TypeScript
Basic Usage
CLI - passing arguments directly
$ # global install $ tsc srcFile.ts --outDir ./dist $ # local installs $ npx tsc srcFile.ts --outDir ./dist $ ./node_modules/.bin/tsc srcFile.ts --outDir ./dist
CLI - using a 'project'
$ npx tsc -p ../tsconfig.json
2 - Using TypeScript
Extended Tooling
Extended Tooling
-
IDEs and Plugins
-
VS Code
- First-Class Support!
- Sublime Text
- Atom
-
VS Code
-
Formatters / Linters
-
Bundlers / Loaders
2 - Using TypeScript
Typing Existing JavaScript
2 - Using TypeScript
Type Checking JS
TypeScript 2.3 added support for type-checking and reporting errors in
.js
files with the --checkJs
compiler option.
Types can often be inferred by their assignment. When this fails, types can be specified using JSDoc annotations similar to TS annotations.
The TS compiler is surprisingly good at checking JS, but this process is tedious and still prone to error.
Demo:
./intro/js-type-checked.js
2 - Using TypeScript
Configuration &
Compiling to JavaScript
2 - Using TypeScript
Configuration
TypeScript projects use a configuration file (tsconfig.json
) to determine
how the source will be compiled.
Several of these settings will vary based on the type of application.
Recommended Universal Settings:
- strict - strict(null/func/prop) & noImplicit(this/any)
- noUnusedLocals
- noUnusedParameters
- forceConsistentCasingInFileNames
1 - Intro to TypeScript
Compiled JavaScript
ES5
npx tsc --target es5 --removeComments *.ts
var User = (function () { function User(username) { this.isLoggedIn = true; this.username = username; } User.prototype.logout = function () { this.isLoggedIn = false; return "Goodbye, " + this.username; }; return User; }()); var user = new User("steve");
ES6
npx tsc --target es6 *.ts
class User { constructor(username) { this.isLoggedIn = true; this.username = username; } // This Is Private!!! logout() { this.isLoggedIn = false; return `Goodbye, ${this.username}`; } } const user = new User("steve");
Basic TypeScript
3 - Basic TypeScript
Types & Interfaces
3 - Basic TypeScript
Types
Types are the most fundamental and integral parts of TypeScript.
They allow us to define our variables, method parameters, object properties, etc so that we can build code with confidence.
The compiler is smart enough to generate implicit types for those values you do not explicitly type.
Lastly, we can generate our own types whenever & wherever they're needed.
Demo:
./basics/types.ts
3 - Basic TypeScript
Interfaces
Interfaces are one of the most powerful features of TypeScript.
They provide two key benefits:
- Define the shape of our data without an implementation
- Provide a contract for our code and consumers of our code
One very important difference from other interface implementations (e.g. c#) is that you do not need to explicitly implement the interface to adhere to it.
Demo:
./basics/interfaces.ts
3 - Basic TypeScript
Destructuring & Spread
3 - Basic TypeScript
Destructuring
- Taking elements from an array by position and re-assigning them to new variables.
- Taking properties from an object by name and re-assigning them to new variables.
3 - Basic TypeScript
3 - Basic TypeScript
Spread Operator
The (...
) spread operator allows you to 'spread' an array into another array,
or an object into another object.
While the spread operator makes it easier to create new variables from
existing variables, it has a very important benefit:
Demo:
./basics/spread.ts
3 - Basic TypeScript
Classes
3 - Basic TypeScript
Classes
Classes were a pseudo-construct in JavaScript, but have finally made their way as first-class JavaScript citizens (for better or worse).
Classes:
- Encapsulate logic and 'instance' values
- Can be used as both a value and type
- Can be inherited, mixed-in, abstract
Advanced TypeScript
4 - Advanced TypeScript
Set Theory and Enums
4 - Advanced TypeScript
Intersection Types
An intersection type combines multiple types into one.
This allows you to add together existing types to represent a single type that has all the features you need.
Uses:
Most commonly used for composition.
e.g. Generic functions that take multiple arguments and combine them into one entity.
Demo:
./advanced/intersection.ts
4 - Advanced TypeScript
Union Types
Allow you to specify that a value will be one of several types and contain those properties that are common to both.
You can both decrease the specificity of your function arguments and narrow their scope to use only those features necessary.
Uses:- Handle similar, but un-related implementations
-
Operate on variables that can take multiple value types
e.g. numberic input changeHandler
Demo:
./sets/union.ts
4 - Advanced TypeScript
Generics and Partials
4 - Advanced TypeScript
Generics
Generics allow you to create dynamic components that can work over a variety of types.
This allows you, and potential external parties, to use these components in a way that is simpler and more expressive.
They also provide a way to create type-factories to generate reusable pieces of data structure, or rules for how you can interact with your objects.
Demo:
./advanced/generics.ts
4 - Advanced TypeScript
Partials
Partials are a form of generics that alter an existing type.
They provide a mechanism for quickly altering existing structures with well-defined, new behaviors and can also supplement existing structures with new properties.
Demo:
./advanced/partials.ts
4 - Advanced TypeScript
Type Narrowing & Type Guards
4 - Advanced TypeScript
Type Narrowing
A type guard is some expression that performs a runtime check that guarantees the type in some scope.
To define a type guard, you define a function whose return type is a type predicate.
Demo:
./advanced/type-narrowing.ts


Necklace
问题描述 :
Henryy gave the princess of the kingdom of Henryy a necklace, which is made by a series of diamonds which are the most valuable among the world.
The necklace can be regarded as a string of diamonds. (Notice that it’s not a loop of them!) In the kingdom, another kind of necklace is very popular, but it is much less precious. If this kind of necklace is a sub-string (not sub-sequence) of the princess’, maybe somebody will use the fake one to replace a part of it, and this is quite dangerous. Thus, Henryy want to remove some of the diamonds off from the necklace to make it safer. This number, of course, should be as small as possible.
The necklace can be regarded as a string of diamonds. (Notice that it’s not a loop of them!) In the kingdom, another kind of necklace is very popular, but it is much less precious. If this kind of necklace is a sub-string (not sub-sequence) of the princess’, maybe somebody will use the fake one to replace a part of it, and this is quite dangerous. Thus, Henryy want to remove some of the diamonds off from the necklace to make it safer. This number, of course, should be as small as possible.
输入:
The first line contains an integer T (1 ≤ T ≤ 10) which means T test cases follow:
In each test case:
The first line is a string indicating the princess’ necklace with its length no more than 10000 and made up by characters from ‘a’ to ‘z’.
The second line is the common necklace, with its length no more than 1000 and also made up by characters from ‘a’ to ‘z’.
The two necklaces cannot be reversed. (For example, a necklace “abc” cannot be regarded as “cba”.)
A blank line is followed after each test case.
In each test case:
The first line is a string indicating the princess’ necklace with its length no more than 10000 and made up by characters from ‘a’ to ‘z’.
The second line is the common necklace, with its length no more than 1000 and also made up by characters from ‘a’ to ‘z’.
The two necklaces cannot be reversed. (For example, a necklace “abc” cannot be regarded as “cba”.)
A blank line is followed after each test case.
输出:
The first line contains an integer T (1 ≤ T ≤ 10) which means T test cases follow:
In each test case:
The first line is a string indicating the princess’ necklace with its length no more than 10000 and made up by characters from ‘a’ to ‘z’.
The second line is the common necklace, with its length no more than 1000 and also made up by characters from ‘a’ to ‘z’.
The two necklaces cannot be reversed. (For example, a necklace “abc” cannot be regarded as “cba”.)
A blank line is followed after each test case.
In each test case:
The first line is a string indicating the princess’ necklace with its length no more than 10000 and made up by characters from ‘a’ to ‘z’.
The second line is the common necklace, with its length no more than 1000 and also made up by characters from ‘a’ to ‘z’.
The two necklaces cannot be reversed. (For example, a necklace “abc” cannot be regarded as “cba”.)
A blank line is followed after each test case.
样例输入:
1 ababaa aba
样例输出:
1
# include <iostream> # include <cstdio> # include <cstring> using namespace std; int p[1002][26],pre[1002],n,m; char a[10002],b[1002]; int f[10002][1002]; void relax(int &i,const int&j){if(i>j) i=j;} int main() { int Case; scanf("%d",&Case); while(Case--){ scanf("%s",a+1); scanf("%s",b+1); n = strlen(a+1); m = strlen(b+1); for(int i=1; i<=n; i++)a[i]-='a',b[i]-='a'; int k = 0; pre[1] = 0; for(int i=2; i<=m; i++) { while(k && b[k+1]!=b[i]) k = pre[k]; if(b[k+1] == b[i]) k++; pre[i]=k; } memset(p,0,sizeof(p)); for(int i=1; i<=m; i++) p[i-1][b[i]]=i; for(int i=1; i<=m; i++) for(int j=0; j<26; j++) if(!p[i][j]) p[i][j] = p[pre[i]][j]; for(int j=0; j<26; j++) p[m][j] = m; memset(f,0x7f,sizeof(f)); f[0][0]=0; for(int i=0; i<n; i++) for(int j=0; j<m; j++) if( f[i][j]<0x7f7f7f7f ) relax(f[i+1][j], f[i][j]+1), relax(f[i+1][p[j][a[i+1]]], f[i][j]); int ans = n+1; for(int i=0; i<m; i++) relax(ans, f[n][i]); printf("%d\n",ans); } return 0; }
(adsbygoogle = window.adsbygoogle || []).push({});
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
你这是“不道德”的，大冷的天居然扒皮陈教授，一条内裤也不留，好歹也发条纸尿裤吧，不然陈教授吓尿了咋办，
网站不错
程序员会算法，等于一个古惑仔带了zhi抢啊
这个方法是错的，不信你试试：
20 5
1 A:9
1 A:9
1 A:9
1 A:6
1 A:4
正确答案应该是19，这个答案是18
参考 http://www.acmerblog.com/leetcode-solutions-6422.html
真考人啊
学算法中的数据结构学到一定程度会乐此不疲的，比如其中的2－3树，类似的红黑树，我甚至可以自己写个逻辑文件系统结构来。
必须试过啊
这个分析相当全面，经典！
很好。代码比书上的简练！
分析的很专业！
我没看懂题目
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
我觉得第一个应该是5 6 -1 5 4 输出是19 5 4
第二个是7 0 6 -1 1 -6 7输出是14 7 7
不知道题目例子是怎么得出来的
站长好。我是一个准备创业的互联网小白,我们打算做一个有关国*际*游*学的平台。手上也有了一些境外资源。现阶段的团队现在没有cto.原意出让一些管理股寻找一个靠谱的技术专家做合伙人, 不知道是不是能得到您的帮助。发个帖子或者其他方式。期待您的回应。可以加我微信tianxielemon聊聊。
多谢提醒，是漏掉了
大哥，你复制也看看是不是这题的答案才复制吧。


Notice that due to internal implementation differences, frameworks that uses async rendering (e.g. m-react, Vue, Om, Mercury, mithril) gains the advantage by skipping part of the calculations that happened in the same event loop.
However, the comparison result doesn't reflect the real use scenarios. Use with discretion.
Here is the code used for these tests.


WITNESS LIST Economic Development Committee (Subcommittee on Private Sector Business Financing) January 19, 2000-9:00A Business Financing & Capital On: Adamek, Thomas J. (Certified Capital Corporations (CAPCO)), Baton Rouge, LA Donohoe, Dan (Bank One, Texas N.A.), Dallas Pinkley, Craig (Texas Dept. of Economic Development), Austin Pinkus, David (Small Business United of Texas), Austin


Node-Wiimote docs
Basic easy to use Wiimote library for node.js.
Contents:
1. Quick Start
1.1 Installation
npm install node-wiimote --save
1.2 Initialise
var Wiimote = require("node-wiimote");
var wii = new Wiimote();
Then check against wii.exists
if (wii.exists) {
}
1.3 Add Listeners
wii.on(type, action, callback);
Sample uses:
var pressBToken = wii.on("button_b", "pressed", handlePressedB);
var relesBToken = wii.on("button_b", "released", handleReleasedB);
var relesHomeToken = wii.on("button_home", "released", exitApplication);
More on events: Section 2
1.4 Remove Listeners
wii.off(token);
wii.off(type, action)
Sample uses:
wii.off(pressBToken);
wii.off(relesBToken);
wii.off("button_home", "released");
2. Events
2.1 Behaviour
Each event has a "type" and an "action"
The event type is used to target the button, sensor, or other devices the user can interface with.
The event action is used to specify what the user does (press button, movement etc)
Also available are the all and * keywords
These may be used in place of types and/or actions as wildcards. ie:
An event listener with type: "button_a", action: "all" will trigger for every action on the a button.
An event listener with type: "all", action: "pressed" will trigger for a pressed event on any device.
An event listener with type: "all", action: "all" will trigger for every device.
The wii.on() function returns a WiiListenerToken that can be used to remove that event listener.
That can be done by simply passing it into wii.off(token)
You can also remove all events with specific types and actions by using wii.off(type, action)
Note that unlike specifying all or * with events, using all or * to remove events only removes events with the types/actions all or *, ie:
Remove with type: "all", action: "pressed" will only remove events that match type: "all", action: "pressed", and not other events with action: "pressed"
2.2 Buttons
2.2.1 Types
button_a
button_b
button_1
button_2
button_plus
button_minus
button_left
button_right
button_up
button_down
button_home
2.2.2 Actions
pressed
Triggered when a button is pressed down.
released
Triggered when a button is released.
3. Feedback
3.1 Haptics/Rumble/Vibration
wii.vibrate(<(true/false)|duration>);
Expects and does as the following:
true/false (boolean): Enables/Disables vibration or rumble feature
duration (number, milliseconds): Enables vibration for a set length of time
3.2 Lights
wii.setLights(1, 2, 3, 4);
Takes 4 boolean values and turns on the LEDs on the bottom of the Wiimote (left to right)
3.2 List Events
wii.listEvents(toConsole*);
Returns an object with all events in eventType: prettyName format.
If toConsole is true, prints the list to the console instead.
If toConsole is not present, it is assumed to be false.


My values
My values
limitations
my only limitation is not having the finances to set myself up to find a job in auckland or wellington straight away. An experience of working productively with others and there was tension was when me and my flatmates were trying to find people to replace us for our rooms so we can break the lease and move away. I used the strategy of doing whatever i could to help and start early, and hope the others will see my determination and start doing the same. my strategy was not effective at all. Rather then trying to help everyone get people for their rooms at the same time and get overwhelmed, i should have methodically went through. made sure mine was done, then helped the next person, then the next. Its much less stressful doing it this way and its always easier to do things one step at a time.
Culture
my culture is very family and love oriented. praise is given for showing respect for elders and tradition. everyone is proud to be Maori and to be in our family. These cultural values have heavily influenced mine whether i like it or not. Ive had alot of trouble being able to stand up for myself in the workplace as ive had respect and go out of your way for your superiors drilled into me. Fortunately ive acknowledged and processed this, discovering how low i put myself in my priority list.
Strengths
im experienced in building a web-application from scratch. My strengths are that once im hooked, ive got lazer focus and can get lost in my work for days. Ive failed so much at committing to projects, reaching my goals. That i know how to utilize my potential. Having a flexible daily routine that encourages discipline and does not discourage rest/ fun time. Using chunking methodology to tackle projects and goals. And above everything, enjoy the moment. This will definitely help me in my learning journey. when im stuck into something, its really easy to get lost in enjoying the process. This will keep my fire lit so i can power through the work!!


TemplateEngine
public protocol TemplateEngine
Template Engine protocol for Kitura. Implemented by Templating Engines in order to integrate with Kitura’s content generation APIs.
Note
Influenced by http://expressjs.com/en/guide/using-template-engines.html-
The file extension of files in the views directory that will be rendered by a particular templating engine.
Declaration
Swift
var fileExtension: String
-
Take a template file and a set of
variables
in the form of a context and generate content to be sent back to the client.Parameter
Parameter filePath: The path of the template file to use when generating the content.Parameter
Parameter context: A set of variables in the form of a Dictionary of Key/Value pairs, that can be used when generating the content.Declaration
Swift
func render(filePath: String, context: [String: Any]) throws -> String
Parameters
filePath
The path of the template file to use when generating the content.
context
A set of variables in the form of a Dictionary of Key/Value pairs, that can be used when generating the content.


Dmitry Nikulin , Sebastian Kosch , Fabian Steuer , Hoagy Cunningham
This project was completed during AI Safety Camp 3 in Ávila, Spain, in May 2019.
Advances in deep learning are enabling reinforcement learning (RL) agents to accomplish increasingly difficult tasks. For instance, relatively simple machine learning agents can learn how to beat humans in video games, without ever having been programmed how to do so. However, agents sometimes learn to make correct decisions for the wrong reasons, which can lead to surprising and perplexing failures later. In order to diagnose such problems effectively, the developer needs to understand how information flows through the artificial neural network that powers the agent's decision-making process.
One approach to visualizing how complex models operate on image inputs is through saliency maps. A saliency map is a heatmap highlighting those pixels of the input image that are most responsible for the model output. An example could be a neural network performing an image classification task: given a photograph of a dog in a meadow that was correctly classfied as "dog", a saliency map highlights the pixels the network considers most dog-like. This lets us check whether the network has truly learned the concept of dogs, or whether it merely made a lucky guess based on the presence of the meadow.
To some extent, the methods for generating saliency maps can be repurposed for the analysis of RL agents playing video games, since the agent infers actions (labels) from render frames (images). However, the resulting heatmaps are often blurry or noisy. Furthermore, image classifiers simply detect individual objects, while RL agents must choose actions based on complex relationships between entities detected in the input. A simple heatmap visualization cannot convey whether and where such relationships were detected.
In this work, we present a potential improvement to existing visualization approaches in RL, and report on our experimental findings regarding their performance on six Atari games.
In 2018, Yang et al.[1] explored the effects of adding two attention layers to the decision-making network of an agent learning to play Breakout and other games. The attention layers, applied after some convolutional layers which detect basic game entities, restrict the input to the agent's action selection mechanism to a subset of the input pixels (the attention mask). In effect, this bottleneck forces the agent's model to focus spatially. This can improve sample efficiency, but more importantly, the attention layer activations provide a direct clue about what the model is focusing on. This directness is attractive when compared to post-hoc methods, which require additional computation to reason about the relevance of network activations after inference.
Note that there is no direct correspondence between activated attention layer neurons and relevant input pixels. This is due to the convolutional downsampling layers that separate the input image from the attention layers. However, we can generate a heatmap by backpropagating the attention tensor through the network. Several different approaches exist to accomplish this, from the gradient method introduced by Simonyan et al.[2] to the more recent SmoothGrad[5] and VarGrad[6] sampling methods.
After some experimentation, Yang et al. chose a simpler approach, where they simply visualized the receptive field of the neuron which corresponded to the single strongest activation in their agent's attention layer. Their findings confirm that in trained agents, the attention tends to be strong near crucial entities in the game, i.e. the Pacman sprite or the moving ball in Breakout. However, their attention mask heatmaps are fairly crude.
The effectiveness of attention layers depends crucially on how the attention is constrained. This is especially true in architectures with repeated downsampling, such as Yang et al.'s, where a small but diffuse attention mask will effectively correspond to all input pixels, defeating the purpose of the attention layer.
To incentivize more informative heatmaps than those obtained by Yang et al., we therefore added an extra loss term to represent the diffuseness of the attention tensor. Several options for such loss terms exist; we settled on using the entropy of the final attention layer.
The entropy of the attention mask is a single number that captures whether the attention is spread diffusely across the layer (high entropy) or concentrated in a few locations (low entropy). For our purposes, a high entropy is undesirable, as we wish to constrain attention to only a few locations. In other words, the extra loss term rewards our agent for focusing on only a few locations of the input image, which we can later visualize.
For a discrete probability distribution \(p_i, i=1..n\), entropy is defined as:
\[ \operatorname{entropy}(p) = -\sum_{i = 1}^n p_i \cdot \log(p_i). \]
This quantity is greatest when \(p_i \equiv \frac 1 n\) for all \(i\), i.e., when the probability distribution is perfectly uniform. By contrast, it is equal to zero when \(p_i = 1\) for some \(i\), while the other outcomes have zero probability.
In our case, we regard the output of the attention layer as a probability distribution, and we modify the loss in such way as to minimize the entropy of this distribution. Specifically, we add \(\lambda \cdot \operatorname{entropy}(attn)\) to the loss, where \(\lambda\) is a non-negative coefficient and \(attn\) is the output of the attention layer.
Although attention mechanisms have been shown to improve training times, excessively strong regularization will naturally prevent the agent from taking into account complex relationships between spatially distant entities, and thus degrade performance. We ran a suite of experiments to quantify the impact of entropy regularization on the agent's performance at playing Atari games.
We recreated the agent by Yang et al. in TensorFlow using the
stable-baselines
[3] package, a fork of OpenAI's
baselines
package with a stable programming interface and
improved documentation. Since stable-baselines
does not
include a full implementation of the Rainbow algorithm, we used PPO[4]
as another state-of-the-art algorithm available in the library.
Our experiments show that entropy regularization can be added in such way that its effects on attention maps become pronounced, but performance does not suffer noticeably. The following figure shows average reward agents obtain during training with varying \(\lambda\). The value \(\lambda = 0.0\) means that entropy loss did not affect training. This setup should be regarded as baseline.
These results are reassuring: in the environments tested, constraining attention with \(\lambda = 0.0005\) does not slow down training, suggesting that we can use entropy regularization to improve our salience visualizations without degrading agent performance. The following figure shows how \(\lambda\) affects the average performance of trained agents:
With the exception for BeamRider, it is clear that for the particular case of these Atari games, it is possible to choose a value of \(\lambda\) such that the extra term in the loss will have a noticeable effect on entropy value, without degrading performance.
In BeamRider, none of the agents achieved good performance. This is expected; the authors of PPO report that learning in BeamRider only starts after roughly 10M frames, and we terminated training after exactly 10M frames.
The following videos show what learned attention maps look like for different \(\lambda\).
Entropy regularization ensures that attention masks have a few prominent peaks. Each peak corresponds directly to a particular configuration of features in the underlying convolutional layers. In the entropy-regularized networks, the representation of such feature correlations is often pleasantly sparse, lending itself well to a new variant of visualization via layer-relevance propagation.
Instead of creating a two-dimensional heatmap based on the activation of the entire attention layer, as is commonly done, we chose to focus on only one or a few of the newly-obtained attention peaks. We then recurse through the layers below, picking the strongest associated activations each time, creating a tree structure that represents, at each convolutional layer, the features that contributed most to the attention peaks—and, thus, to the agent's chosen action.
This tree of features can help us understand not only where the most relevant pixels are, but also how these pixels combine to form the features that contributed to the action. The following interactive display shows a selection of four deep branches of the tree structure, and the location of the corresponding features, for a single frame of the Breakout environment.
We select the peaks of the attention layer using a simple peak detection algorithm (more sophisticated approaches, such as k-means clustering with a gap-statistic, proved too slow for interactive visualizations).
Although such visualizations are quite time-consuming to implement in an interactive manner, that effort may be justified. After all, understanding an RL agent's behaviour can be more difficult than confirming that a simple image classifier correctly detected the relevant features.
In comparison, two-dimensional, heatmap-based salience visualizations cannot adequately capture the spatial relationships between entities in the input that are so essential to selecting the correct action. To illustrate this point, we show here the Simonyan gradient, SmoothGrad and VarGrad of the input with respect to the (unregularized) attention layer:
Although SmoothGrad and VarGrad provide a sharper salience map, this advantage quickly diminishes when more samples are used, suggesting that much of the apparent structure is due to the noise in the sampling.
Applying entropy loss to an attention layer in RL agents can help make their policy networks more interpretable by creating better opportunities for deep, layer-based visualizations with sparse, meaningful peaks, rather than the diffuse, population-encoded activity often seen in unregularized attention layers.
We have shown that such entropy-based regularization rarely has a negative effect on agent performance, and can sometimes even improve it, in a variety of Atari environments.
Yang et al. Learn to Interpret Atari Agents↩
Simonyan et al. Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps↩
Hill et al. Stable Baselines↩
Schulman et al. Proximal Policy Optimization Algorithms↩
Smilkov et al. SmoothGrad: removing noise by adding noise↩
Adebayo et al. Local Explanation Methods for Deep Neural Networks Lack Sensitivity to Parameter Values↩


We particularly love making and breaking ciphers.
Most of our work is tied to government organizations all over the world, but some of our public work will probably be coming up below as posts.
If you want us to have a look at your case, send in your request to<EMAIL_ADDRESS>Don't frown, that was for the bots.
Recently bots have become smart and can figure out email addresses in images as well as js-obfuscated web pages.
You can decipher our email address using this text: C2wacZMmg3S1AAGHbIBtt2FbGW5afy==.
Decode with Vigenére cipher using electroencephalograph as the key (with the plain alphabet) and then base64 -d the output.
 What counts as spam?


Hello, I am an electronic engineer graduated from the University of Antioquia in Medellin, Colombia. I am currently working as a junior Java developer, and freelance web developer. |
| Java | GitHub | CodePen | Sublime |
| Junior Java developer, with experience in Eclipse and InttelliJ. | Version control tool that I use to host my projects, I have also used GitLab. | I usually use it to do front-end developments. | My favorite text editor, although sometimes I also use Atom. |
| Trello | IntelliJ | ||
| Task management tool that I use for my projects. | The IDE that I am currently using to make my Java developments. |
I'm not an expert, but I've done projects in: |
||
|---|---|---|
| Unity | Android Studio | Python |
| I made a Jumping Guy style game for Android, Windows and WEB. | I did a free online course and some practical exercises. | Make scripts to communicate by SSH and Telnet with Cisco switches and Motorola access points and configure them from a Linux server with Axiros. |


--- layout: post title: "Code coverage is a useless target measure" description: "Aiming for a particular percentage of code coverage is counter-productive." date: 2015-11-16 8:38 UTC tags: [Productivity, Unit Testing] --- {% include JB/setup %}
{{ page.description }}
It's the end of 2015, and here I thought that it was common knowledge that using code coverage as a metric for code quality is useless at best. After all, Martin Fowler wrote a good article on the subject in 2012, but the fundamental realisation is much older than that. Apparently, it's one of those insights that one assumes that everyone else already knows, but in reality, that's not the case.
Let's make it clear, then: don't set goals for code coverage.
You may think that it could make your code base better, but asking developers to reach a certain code coverage goal will only make your code worse.
I'll show you some examples, but on a general level, the reason is that as with all other measurements, you get what you measure. Unfortunately, we can't measure productivity, so measuring code coverage will produce results that are entirely unrelated to software quality.
"People respond to incentives, although not necessarily in ways that are predictable or manifest. Therefore, one of the most powerful laws in the universe is the law of unintended consequences." - Super FreakonomicsIncentives with negative consequences are called perverse incentives; asking developers to reach a particular code coverage goal is clearly a perverse incentive.
It doesn't matter whether you set the target at 100% code coverage, 90%, 80%, or some other number.
Here's a simple code example:
public class GoldCustomerSpecification : ICustomerSpecification { public bool IsSatisfiedBy(Customer candidate) { return candidate.TotalPurchases >= 10000; } }
Imagine that you have been asked to reach a high level of code coverage, and that this class is still not covered by tests. Not only that, but you have bugs to fix, meetings to go to, new features to implement, documentation to write, time sheets to fill out, and the project is already behind schedule, over budget, and your family is complaining that you're never home.
Fortunately, it's easy to achieve 100% code coverage of the GoldCustomerSpecification class:
[Fact] public void MeaninglessTestThatStillGivesFullCoverage() { try { var sut = new GoldCustomerSpecification(); sut.IsSatisfiedBy(new Customer()); } catch { } }
This test achieves 100% code coverage of the GoldCustomerSpecification class, but is completely useless. Because of the try/catch block and the lack of assertions, this test will never fail. This is what Martin Fowler calls Assertion-Free Testing.
If you can declare a rule that your code base must have so-and-so test coverage, however, you can also declare that all unit tests must have assertions, and must not have try/catch blocks.
Despite of this new policy, you still have lots of other things you need to attend to, so instead, you write this test:
[Fact] public void SlightlyMoreInnocuousLookingTestThatGivesFullCoverage() { var sut = new GoldCustomerSpecification(); var actual = sut.IsSatisfiedBy(new Customer()); Assert.False(actual); }
This test also reaches 100% coverage of the GoldCustomerSpecification class.
What's wrong with this test? Nothing, as such. It looks like a fine test, but in itself, it doesn't prevent regressions, or proves that the System Under Test works as intended. In fact, this alternative implementation also passes the test:
public class GoldCustomerSpecification : ICustomerSpecification { public bool IsSatisfiedBy(Customer candidate) { return false; } }
If you want your tests to demonstrate that the software works as intended, particularly at boundary values, you'll need to add more tests:
[Theory] [InlineData(100, false)] [InlineData(9999, false)] [InlineData(10000, true)] [InlineData(20000, true)] public void IsSatisfiedReturnsCorrectResult( int totalPurchases, bool expected) { var sut = new GoldCustomerSpecification(); var candidate = new Customer { TotalPurchases = totalPurchases }; var actual = sut.IsSatisfiedBy(candidate); Assert.Equal(expected, actual); }
This is a much better test, but it doesn't increase code coverage! Code coverage was already 100% with the SlightlyMoreInnocuousLookingTestThatGivesFullCoverage test, and it's still 100% with this test. There's no correlation between code coverage and the quality of the test(s).
Not only is test coverage percentage a meaningless number in itself, but setting a goal that must be reached actually hinders improvement of quality. Take another look at the GoldCustomerSpecification class:
public class GoldCustomerSpecification : ICustomerSpecification { public bool IsSatisfiedBy(Customer candidate) { return candidate.TotalPurchases >= 10000; } }
Is the implementation good? Can you think of any improvements to this code?
What happens if candidate
is null? In that case, a NullReferenceException will be thrown. In other words, the IsSatisfiedBy method doesn't properly check that its preconditions are satisfied (which means that encapsulation is broken).
A better implementation would be to explicitly check for null:
public class GoldCustomerSpecification : ICustomerSpecification { public bool IsSatisfiedBy(Customer candidate) { if (candidate == null) throw new ArgumentNullException(nameof(candidate)); return candidate.TotalPurchases >= 10000; } }
The problem, though, is that if you do this, coverage drops! That is, unless you write another test case...
Developers in a hurry often refrain from making the code better, because it would hurt their coverage target - and they don't feel they have time to also write the tests that go with the improvement in question.
Instituting a code coverage target - any percentage - will have that effect. Not only does the coverage number (e.g. 87%) tell you nothing, but setting it as a target will make the code base worse.
You may argue that I'm taking too dim a view on developers, but I've seen examples of the behaviour I describe. People mostly have good intentions, but if you put enough pressure on them, they'll act according to that pressure. This is the reason we need to be aware of perverse incentives.
You may also argue that if a team is already doing Test Driven Development, and in general prioritise code quality, then coverage will already be high. In that case, will it hurt setting a target? Perhaps not, but it's not going to help either. At best, the target will be irrelevant.
This article, however, doesn't discuss teams that already do everything right; it describes the negative consequences that code coverage targets will have on teams where managers or lead developers mistakenly believe that setting such goals is a good idea.
While it's dangerous to use code coverage for target setting, collecting coverage metrics can still be useful.
Some people use it to find areas where coverage is weak. There may be good reasons that some parts of a code base are sparsely covered by tests, but doing a manual inspection once in a while is a good idea. Perhaps you find that all is good, but you may also discover that a quality effort is overdue.
In some projects, I've had some success watching the code coverage trend. When I review pull requests, I first review the changes by looking at them. If the pull request needs improvement, I work with the contributor to get the pull request to an acceptable quality. Once that is done, I've already made my decision on merging the code, and then I measure code coverage. It doesn't influence my decision to merge, but it tells me about the trend. On some projects, I've reported that trend back to the contributor while closing the pull request. I wouldn't report the exact number, but I'd remark that coverage went up, or down, or remained the same, by 'a little', 'much', etc. The point of that is to make team members aware that testing is important.
Sometimes, coverage goes down. There are many good reasons that could happen. Watching how coverage evolves over time doesn't mean that you have to pounce on developers every time it goes down, but it means that if something looks odd, it may be worth investigating.
Don't use code coverage as an objective. Code coverage has no correlation with code quality, and setting a target can easily make the quality worse.
On the other hand, it can be useful to measure code coverage once in a while, but it shouldn't be your main source of information about the status of your source code.


Erikson Aguiar is a Master’s candidate at the Intermidia Lab of the University of São Paulo. His Interests include distributed systems, blockchain, data mining, IoT, and security. He leads a research related to blockchain in healthcare environments to improve privacy using differential privacy, supervised by Prof. Jó Ueyama.
MSc in Computer Science, In progress
University of São Paulo
BSc in Computer Science, 2017
Northern Paraná State University
Master degree project - FAPESP Scholarship
Responsibilities include:
Undergraduate CNPQ Scholarship
Responsibilities include: