Welcome to the third project of the Machine Learning Engineer Nanodegree! In this notebook, some template code has already been provided for you, and it will be your job to implement the additional functionality necessary to successfully complete this project. Sections that begin with 'Implementation' in the header indicate that the following block of code will require additional functionality which you must provide. Instructions will be provided for each section and the specifics of the implementation are marked in the code block with a 'TODO'
statement. Please be sure to read the instructions carefully!
In addition to implementing code, there will be questions that you must answer which relate to the project and your implementation. Each section where you will answer a question is preceded by a 'Question X' header. Carefully read each question and provide thorough answers in the following text boxes that begin with 'Answer:'. Your project submission will be evaluated based on your answers to each of the questions and the implementation you provide.
Note: Code and Markdown cells can be executed using the Shift + Enter keyboard shortcut. In addition, Markdown cells can be edited by typically double-clicking the cell to enter edit mode.
In this project, you will analyze a dataset containing data on various customers' annual spending amounts (reported in monetary units) of diverse product categories for internal structure. One goal of this project is to best describe the variation in the different types of customers that a wholesale distributor interacts with. Doing so would equip the distributor with insight into how to best structure their delivery service to meet the needs of each customer.
The dataset for this project can be found on the UCI Machine Learning Repository. For the purposes of this project, the features 'Channel'
and 'Region'
will be excluded in the analysis — with focus instead on the six product categories recorded for customers.
Run the code block below to load the wholesale customers dataset, along with a few of the necessary Python libraries required for this project. You will know the dataset loaded successfully if the size of the dataset is reported.
# Import libraries necessary for this project
import numpy as np
import pandas as pd
import itertools
# To make output stable across runs
np.random.seed(42)
# To plot pretty figures
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
from IPython.display import display # Allows the use of display() for DataFrames
# Import supplementary visualizations code visuals.py
import visuals as vs
# Pretty display for notebooks
%matplotlib inline
# Load the wholesale customers dataset
try:
data = pd.read_csv("customers.csv")
data.drop(['Region', 'Channel'], axis = 1, inplace = True)
print("Wholesale customers dataset has {} samples with {} features each.".format(*data.shape))
except:
print("Dataset could not be loaded. Is the dataset missing?")
data.head()
In this section, you will begin exploring the data through visualizations and code to understand how each feature is related to the others. You will observe a statistical description of the dataset, consider the relevance of each feature, and select a few sample data points from the dataset which you will track through the course of this project.
Run the code block below to observe a statistical description of the dataset. Note that the dataset is composed of six important product categories: 'Fresh', 'Milk', 'Grocery', 'Frozen', 'Detergents_Paper', and 'Delicatessen'. Consider what each category represents in terms of products you could purchase.
# Display a description of the dataset
display(data.describe())
To get a better understanding of the customers and how their data will transform through the analysis, it would be best to select a few sample data points and explore them in more detail. In the code block below, add three indices of your choice to the indices
list which will represent the customers to track. It is suggested to try different sets of samples until you obtain customers that vary significantly from one another.
# Let's create five categories in our data for each feature, i.e quintiles
purchase_categories = ["Very Low", "Low", "Median", "High", "Very High"]
# Let's check for big purchases of Fresh Products
quint_fresh = pd.qcut(data['Fresh'],
5, purchase_categories)
# Let's check for big purchases of Deli Products
quint_frozen = pd.qcut(data['Frozen'],
5, purchase_categories)
# Let's check big purchases of cleaning products
quint_cleaning = pd.qcut(data['Detergents_Paper'],
5, purchase_categories)
data[quint_fresh == "Very High"].loc[quint_cleaning == "Low"].sort_values(by='Fresh', ascending=False).head()
data[quint_cleaning == "Very High"].sort_values(by="Detergents_Paper", ascending=False).head()
data[quint_frozen == "Very High"].sort_values(by="Frozen", ascending=False).head()
# Select three indices of your choice you wish to sample from the dataset
indices = [33, 333, 93]
# Create a DataFrame of the chosen samples
samples = pd.DataFrame(data.loc[indices], columns = data.keys()).reset_index(drop = True)
print("Chosen samples of wholesale customers dataset:")
display(samples)
# Visualize the samples along with the means
samples_mean = data.describe().loc['mean']
index = [1,2,3] + ['mean']
samples_with_mean = samples.copy()
samples_with_mean = samples_with_mean.append(samples_mean)
samples_with_mean.index = index
samples_with_mean.head()
_ = samples_with_mean.plot(kind='bar', figsize=(14,8))
_ = plt.ylabel('Total Anual Purchase')
_ = plt.xlabel('Samples and Mean')
_ = plt.show()
Consider the total purchase cost of each product category and the statistical description of the dataset above for your sample customers.
Hint: Examples of establishments include places like markets, cafes, delis, wholesale retailers, among many others. Avoid using names for establishments, such as saying "McDonalds" when describing a sample customer as a restaurant. You can use the mean values for reference to compare your samples with. The mean values are as follows:
Knowing this, how do your samples compare? Does that help in driving your insight into what kind of establishments they might be?
Answer:
One interesting thought to consider is if one (or more) of the six product categories is actually relevant for understanding customer purchasing. That is to say, is it possible to determine whether customers purchasing some amount of one category of products will necessarily purchase some proportional amount of another category of products? We can make this determination quite easily by training a supervised regression learner on a subset of the data with one feature removed, and then score how well that model can predict the removed feature.
In the code block below, you will need to implement the following:
new_data
a copy of the data by removing a feature of your choice using the DataFrame.drop
function.sklearn.cross_validation.train_test_split
to split the dataset into training and testing sets.test_size
of 0.25
and set a random_state
.random_state
, and fit the learner to the training data.score
function.# Added version check for recent scikit-learn 0.18 checks
from distutils.version import LooseVersion as Version
from sklearn import __version__ as sklearn_version
if Version(sklearn_version) < '0.18':
from sklearn.cross_validation import train_test_split
else:
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
for column in data.columns:
# Make a copy of the DataFrame, using the 'drop' function to drop the given feature
new_data = data.drop([column], axis=1)
# Split the data into training and testing sets(0.25) using the given feature as the target
# Set a random state.
X_train, X_test, y_train, y_test = \
train_test_split(new_data, data[column], test_size=0.25, random_state=42)
# Create a decision tree regressor and fit it to the training set
regressor = DecisionTreeRegressor(random_state=42)
regressor = regressor.fit(X_train, y_train)
# Report the score of the prediction using the testing set
score = regressor.score(X_test, y_test)
print("If we remove {} products, the R2 score is {:.3f}".format(column, score))
Hint: The coefficient of determination, R^2
, is scored between 0 and 1, with 1 being a perfect fit. A negative R^2
implies the model fails to fit the data. If you get a low score for a particular feature, that lends us to beleive that that feature point is hard to predict using the other features, thereby making it an important feature to consider when considering relevance.
Answer:
| Predicted Product | Score |
|---|---|
| Fresh | -0.386 |
| Milk | 0.156 |
| Grocery | 0.682 |
| Frozen | -0.210 |
| Detergents | 0.272 |
| Delicatessen | -2.255 |
To get a better understanding of the dataset, we can construct a scatter matrix of each of the six product features present in the data. If you found that the feature you attempted to predict above is relevant for identifying a specific customer, then the scatter matrix below may not show any correlation between that feature and the others. Conversely, if you believe that feature is not relevant for identifying a specific customer, the scatter matrix might show a correlation between that feature and another feature in the data. Run the code block below to produce a scatter matrix.
# Produce a scatter matrix for each pair of features in the data
pd.plotting.scatter_matrix(data, alpha = 0.3, figsize = (16,8), diagonal = 'kde');
data.hist(bins=100, figsize=(16, 8), facecolor='green', alpha=0.5);
plt.figure(figsize=(12,6))
_ = sns.heatmap(data.corr(), annot=True)
Hint: Is the data normally distributed? Where do most of the data points lie? You can use corr() to get the feature correlations and then visualize them using a heatmap(the data that would be fed into the heatmap would be the correlation values, for eg: data.corr()
) to gain further insight.
Answer:
By looking at the scatter matrix and the histogram, none of the features seems to be normally distributed, they are highly left-skewed. The most left-skewed of them is the Delicatessen, with a lot of samples near 0.
The heatmap clearly shows high positive correlation between the pairs:
Mild Positive Correlation
The Mild Positive correlation between the Delicatessen, Frozen and Milk products make perfect sense, since a lot of deli products uses milk and frozen ingredients. Other than that there not much information about the spending habits in deli products from the other features.
In this section, you will preprocess the data to create a better representation of customers by performing a scaling on the data and detecting (and optionally removing) outliers. Preprocessing data is often times a critical step in assuring that results you obtain from your analysis are significant and meaningful.
If data is not normally distributed, especially if the mean and median vary significantly (indicating a large skew), it is most often appropriate to apply a non-linear scaling — particularly for financial data. One way to achieve this scaling is by using a Box-Cox test, which calculates the best power transformation of the data that reduces skewness. A simpler approach which can work in most cases would be applying the natural logarithm.
In the code block below, you will need to implement the following:
log_data
after applying logarithmic scaling. Use the np.log
function for this.log_samples
after applying logarithmic scaling. Again, use np.log
.# Scale the data using the natural logarithm
log_data = np.log(data)
# TODO: Scale the sample data using the natural logarithm
log_samples = np.log(samples)
# Produce a scatter matrix for each pair of newly-transformed features
pd.plotting.scatter_matrix(log_data, alpha = 0.3, figsize = (16,10), diagonal = 'kde');
After applying a natural logarithm scaling to the data, the distribution of each feature should appear much more normal. For any pairs of features you may have identified earlier as being correlated, observe here whether that correlation is still present (and whether it is now stronger or weaker than before).
Run the code below to see how the sample data has changed after having the natural logarithm applied to it.
# Display the log-transformed sample data
display(log_samples)
Detecting outliers in the data is extremely important in the data preprocessing step of any analysis. The presence of outliers can often skew results which take into consideration these data points. There are many "rules of thumb" for what constitutes an outlier in a dataset. Here, we will use Tukey's Method for identfying outliers: An outlier step is calculated as 1.5 times the interquartile range (IQR). A data point with a feature that is beyond an outlier step outside of the IQR for that feature is considered abnormal.
In the code block below, you will need to implement the following:
Q1
. Use np.percentile
for this.Q3
. Again, use np.percentile
.step
.outliers
list.NOTE: If you choose to remove any outliers, ensure that the sample data does not contain any of these points!
Once you have performed this implementation, the dataset will be stored in the variable good_data
.
# This dictionary will keep count of the index outliers
count_outliers = {}
# For each feature find the data points with extreme high or low values
for feature in log_data.keys():
# Calculate Q1 (25th percentile of the data) for the given feature
Q1 = np.percentile(log_data[feature], 25)
# Calculate Q3 (75th percentile of the data) for the given feature
Q3 = np.percentile(log_data[feature], 75)
# TODO: Use the interquartile range to calculate an outlier step (1.5 times the interquartile range)
step = 1.5 * (Q3 - Q1)
# Display the outliers
print("Data points considered outliers for the feature '{}':".format(feature))
subset_outliers = log_data[~((log_data[feature] >= Q1 - step) & (log_data[feature] <= Q3 + step))]
display(subset_outliers)
for i in subset_outliers.index:
count_outliers[i] = count_outliers.get(i, 0) + 1
# Another way to do the same
# count_outliers[i]+=1 if i in count_outliers else count_outliers[i] = 1
# Uncomment this line and comment the following line to remove all outliers
# outliers = np.array(count_outliers.keys())
# Let's remove just the outliers which appear in more than one feature
outliers = [k for k,v in count_outliers.items() if v > 1]
print("Data points considered outliers in more than one feature")
log_data.iloc[outliers]
# Remove the outliers, if any were specified
good_data = log_data.drop(log_data.index[outliers]).reset_index(drop = True)
good_data.shape
outliers
list to be removed, explain why.Hint: If you have datapoints that are outliers in multiple categories think about why that may be and if they warrant removal. Also note how k-means is affected by outliers and whether or not this plays a factor in your analysis of whether or not to remove them.
Answer:
65,66,75,128,154
are outlies in more than one feature. None of those multiple outliers belong to the samples chosen.In this section you will use principal component analysis (PCA) to draw conclusions about the underlying structure of the wholesale customer data. Since using PCA on a dataset calculates the dimensions which best maximize variance, we will find which compound combinations of features best describe customers.
Now that the data has been scaled to a more normal distribution and has had any necessary outliers removed, we can now apply PCA to the good_data
to discover which dimensions about the data best maximize the variance of features involved. In addition to finding these dimensions, PCA will also report the explained variance ratio of each dimension — how much variance within the data is explained by that dimension alone. Note that a component (dimension) from PCA can be considered a new "feature" of the space, however it is a composition of the original features present in the data.
In the code block below, you will need to implement the following:
sklearn.decomposition.PCA
and assign the results of fitting PCA in six dimensions with good_data
to pca
.log_samples
using pca.transform
, and assign the results to pca_samples
.from sklearn.decomposition import PCA
# Apply PCA by fitting the good data with the same number of dimensions as features
pca = PCA(n_components=len(good_data.columns), random_state=42)
pca.fit(good_data)
# Transform log_samples using the PCA fit above
pca_samples = pca.transform(log_samples)
# Generate PCA results plot
pca_results = vs.pca_results(good_data, pca)
The sign in the second dimension seems to be reversed, since there is no positive correlation in the second one, I think it would make more sense if the dimension were rotated and the sign changed. This also seems to be the case in the first component where the majority of the correlation occurs negatively.
plt.figure(figsize=(12, 6))
_ = sns.heatmap(pca_results.transpose(), annot=True)
print("Cumulative Sum of Explained Variances:")
print(np.cumsum(pca.explained_variance_ratio_))
var_exp = pca.explained_variance_ratio_
cum_var_exp = np.cumsum(pca.explained_variance_ratio_)
# Plot Code extracted from: http://sebastianraschka.com/Articles/2015_pca_in_3_steps.html
with plt.style.context('seaborn-whitegrid'):
plt.figure(figsize=(8, 6))
plt.bar(range(1,7), var_exp, alpha=0.5, align='center',
label='individual explained variance')
plt.step(range(1,7), cum_var_exp, where='mid',
label='cumulative explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal components')
plt.legend(loc='best')
plt.tight_layout()
Hint: A positive increase in a specific dimension corresponds with an increase of the positive-weighted features and a decrease of the negative-weighted features. The rate of increase or decrease is based on the individual feature weights.
Answer:
70.68%
of the total variance in the data is explained by the first and second components93.10%
of the total variance in the data is explained by the first four principal components1st component:
Positively correlated:
Negatively correlated:
The First Component increases weakly with purchases in Fresh and Frozen products and decreases strongly with purchases in cleaning producs, mildly with groceries and Milk, and weakly with deli products. This could be a greengrocery since the strong absence of cleaning products, groceries and milk - this products we buy at a supermarket, grocery store or even a small retail. The Fresh products could be fruits, greens and vegetables. The frozen products could be the fishes or seafood, because of the weak correlation, since this is not the bulk or focus of greengroceries or open markets.
The Dimension rotated ( with the sign reversed ) would mean:
Consumers who purchase Cleaning products, Groceries (such as cookies, bread and a whole bunch of dry or industrialized eating products ) and also Milk don't tend to buy Fresh and Frozen Products. This rotated component could represent a Grocery Store, Convenience Store or medium/small supermarket not focused on fresh products. This could also represent hotels since the high cost of cleaning products and the absence of Fresh or Frozen products.
2nd component:
3rd component:
4th component:
Run the code below to see how the log-transformed sample data has changed after having a PCA transformation applied to it in six dimensions. Observe the numerical value for the first four dimensions of the sample points. Consider if this is consistent with your initial interpretation of the sample points.
# Display sample log-data after having a PCA transformation applied
display(pd.DataFrame(np.round(pca_samples, 4), columns = pca_results.index.values))
When using principal component analysis, one of the main goals is to reduce the dimensionality of the data — in effect, reducing the complexity of the problem. Dimensionality reduction comes at a cost: Fewer dimensions used implies less of the total variance in the data is being explained. Because of this, the cumulative explained variance ratio is extremely important for knowing how many dimensions are necessary for the problem. Additionally, if a signifiant amount of variance is explained by only two or three dimensions, the reduced data can be visualized afterwards.
In the code block below, you will need to implement the following:
good_data
to pca
.good_data
using pca.transform
, and assign the results to reduced_data
.log_samples
using pca.transform
, and assign the results to pca_samples
.# TODO: Apply PCA by fitting the good data with only two dimensions
pca = PCA(n_components=2, random_state=42).fit(good_data)
# Transform the good data using the PCA fit above
reduced_data = pca.transform(good_data)
# TODO: Transform log_samples using the PCA fit above
pca_samples = pca.transform(log_samples)
# Create a DataFrame for the reduced data
reduced_data = pd.DataFrame(reduced_data, columns = ['Dimension 1', 'Dimension 2'])
reduced_data.head()
Run the code below to see how the log-transformed sample data has changed after having a PCA transformation applied to it using only two dimensions. Observe how the values for the first two dimensions remains unchanged when compared to a PCA transformation in six dimensions.
# Display sample log-data after applying PCA transformation in two dimensions
display(pd.DataFrame(np.round(pca_samples, 4), columns = ['Dimension 1', 'Dimension 2']))
A biplot is a scatterplot where each data point is represented by its scores along the principal components. The axes are the principal components (in this case Dimension 1
and Dimension 2
). In addition, the biplot shows the projection of the original features along the components. A biplot can help us interpret the reduced dimensions of the data, and discover relationships between the principal components and original features.
Run the code cell below to produce a biplot of the reduced-dimension data.
# Create a biplot
_ = vs.biplot(good_data, reduced_data, pca)
Once we have the original feature projections (in red), it is easier to interpret the relative position of each data point in the scatterplot. For instance, a point the lower right corner ( lower left, since the first two dimensions seems to be rotated ) of the figure will likely correspond to a customer that spends a lot on 'Milk'
, 'Grocery'
and 'Detergents_Paper'
, but not so much on the other product categories.
From the biplot, which of the original features are most strongly correlated with the first component? What about those that are associated with the second component? Do these observations agree with the pca_results plot you obtained earlier?
In this section, you will choose to use either a K-Means clustering algorithm or a Gaussian Mixture Model clustering algorithm to identify the various customer segments hidden in the data. You will then recover specific data points from the clusters to understand their significance by transforming them back into their original dimension and scale.
Hint: Think about the differences between hard clustering and soft clustering and which would be appropriate for our dataset.
Answer:
Depending on the problem, the number of clusters that you expect to be in the data may already be known. When the number of clusters is not known a priori, there is no guarantee that a given number of clusters best segments the data, since it is unclear what structure exists in the data — if any. However, we can quantify the "goodness" of a clustering by calculating each data point's silhouette coefficient. The silhouette coefficient for a data point measures how similar it is to its assigned cluster from -1 (dissimilar) to 1 (similar). Calculating the mean silhouette coefficient provides for a simple scoring method of a given clustering.
In the code block below, you will need to implement the following:
reduced_data
and assign it to clusterer
.reduced_data
using clusterer.predict
and assign them to preds
.centers
.pca_samples
and assign them sample_preds
.sklearn.metrics.silhouette_score
and calculate the silhouette score of reduced_data
against preds
.score
and print the result.from sklearn.mixture import GaussianMixture
from sklearn.metrics import silhouette_score
highest_score = -1
scores = []
n_components_range = range(2, 7) # Since we have 6 features in the data this seemed reasonable
cv_types = ['spherical', 'tied', 'diag', 'full']
for cv_type in cv_types:
for n_components in n_components_range:
# Fit the model with the parameters above
gmm = GaussianMixture(n_components=n_components,
covariance_type=cv_type,
random_state=42)
# Apply your clustering algorithm of choice to the reduced data
clusterer = gmm.fit(reduced_data)
# Predict the cluster for each data point
preds = clusterer.predict(reduced_data)
# Find the cluster centers
centers = clusterer.means_
# Predict the cluster for each transformed sample data point
sample_preds = clusterer.predict(pca_samples)
try:
# Calculate the mean silhouette coefficient for the number of clusters chosen
score = silhouette_score(reduced_data, preds)
except ValueError:
print("For the pair Covariance: {}\n"
"# of Components {}\n"
"the # clusters predicted is only 1,"
"so it's not possible to apply the"
"Silhouette Score\n".format(cv_type, n_components))
next
#score = clusterer.bic(reduced_data)
scores.append(score)
if scores[-1] > highest_score:
highest_score = scores[-1]
best_gmm = clusterer
print("Score for covariance type {} and {} # of components: {:.4f}".format(cv_type, n_components, score))
print(65 * "=")
print('\n')
print("\nBest Model: \n\n"
"Covariance type: {} \n"
"# of Components: {} \n"
"Hihest Score: {:.4f}".format(best_gmm.covariance_type,
best_gmm.n_components,
highest_score))
# Save the Best Model based on Silhouette Score
preds = best_gmm.predict(reduced_data)
centers = best_gmm.means_
sample_preds = best_gmm.predict(pca_samples)
from scipy import linalg
scores = np.array(scores)
color_iter = itertools.cycle(['navy', 'turquoise', 'cornflowerblue',
'darkorange'])
clf = best_gmm
bars = []
# Plot the Silhouette scores
#spl = plt.subplot(2, 1, 1)
plt.figure(figsize=(14,8))
for i, (cv_type, color) in enumerate(zip(cv_types, color_iter)):
xpos = np.array(n_components_range) + .2 * (i - 2)
bars.append(plt.bar(xpos, scores[i * len(n_components_range):
(i + 1) * len(n_components_range)],
width=.2, color=color))
plt.xticks(n_components_range)
plt.ylim([scores.min() * 1.01 - .01 * scores.max(), scores.max()*1.1 ])
plt.title('Silhouette score per model')
xpos = np.mod(scores.argmin(), len(n_components_range)) + .65 +\
.2 * np.floor(scores.argmin() / len(n_components_range))
plt.text(xpos - 2.3, scores.max(), '*', fontsize=36)
plt.xlabel('Number of components')
_ = plt.legend([b[0] for b in bars], cv_types)
_ = plt.tight_layout()
Answer:
Once you've chosen the optimal number of clusters for your clustering algorithm using the scoring metric above, you can now visualize the results by executing the code block below. Note that, for experimentation purposes, you are welcome to adjust the number of clusters for your clustering algorithm to see various visualizations. The final visualization provided should, however, correspond with the optimal number of clusters.
# Display the results of the clustering from implementation
vs.cluster_results(reduced_data, preds, centers, pca_samples)
Each cluster present in the visualization above has a central point. These centers (or means) are not specifically data points from the data, but rather the averages of all the data points predicted in the respective clusters. For the problem of creating customer segments, a cluster's center point corresponds to the average customer of that segment. Since the data is currently reduced in dimension and scaled by a logarithm, we can recover the representative customer spending from these data points by applying the inverse transformations.
In the code block below, you will need to implement the following:
centers
using pca.inverse_transform
and assign the new centers to log_centers
.np.log
to log_centers
using np.exp
and assign the true centers to true_centers
.# TODO: Inverse transform the centers
log_centers = pca.inverse_transform(centers)
# TODO: Exponentiate the centers
true_centers = np.exp(log_centers)
# Display the true centers
segments = ['Segment {}'.format(i) for i in range(0,len(centers))]
true_centers = pd.DataFrame(np.round(true_centers), columns = data.keys())
true_centers.index = segments
display(true_centers)
true_centers_with_mean = true_centers.copy()
true_centers_with_mean = true_centers_with_mean.append(samples_mean)
true_centers_with_mean.transpose()
_ = true_centers_with_mean.plot(kind='bar', figsize=(14,8))
Hint: A customer who is assigned to 'Cluster X'
should best identify with the establishments represented by the feature set of 'Segment X'
. Think about what each segment represents in terms their values for the feature points chosen. Reference these values with the mean values to get some perspective into what kind of establishment they represent.
Answer:
Run the code block below to find which cluster each sample point is predicted to be.
# Display the predictions
for i, pred in enumerate(sample_preds):
print("Sample point", i, "predicted to be in Cluster", pred)
Answer:
The predictions for sample 1 and 3 were some sort of Meal Service and a retail for Sample 2
The Clusters are consistent with predictions made before, Sample points 1 and 3 are in the same segment, Segment 0, while Sample 2 is Segment 1.
In this final section, you will investigate ways that you can make use of the clustered data. First, you will consider how the different groups of customers, the customer segments, may be affected differently by a specific delivery scheme. Next, you will consider how giving a label to each customer (which segment that customer belongs to) can provide for additional features about the customer data. Finally, you will compare the customer segments to a hidden variable present in the data, to see whether the clustering identified certain relationships.
Companies will often run A/B tests when making small changes to their products or services to determine whether making that change will affect its customers positively or negatively. The wholesale distributor is considering changing its delivery service from currently 5 days a week to 3 days a week. However, the distributor will only make this change in delivery service for customers that react positively.
Hint: Can we assume the change affects all customers equally? How can we determine which group of customers it affects the most?
Answer:
Additional structure is derived from originally unlabeled data when using clustering techniques. Since each customer has a customer segment it best identifies with (depending on the clustering algorithm applied), we can consider 'customer segment' as an engineered feature for the data. Assume the wholesale distributor recently acquired ten new customers and each provided estimates for anticipated annual spending of each product category. Knowing these estimates, the wholesale distributor wants to classify each new customer to a customer segment to determine the most appropriate delivery service.
Hint: A supervised learner could be used to train on the original customers. What would be the target variable?
Answer:
At the beginning of this project, it was discussed that the 'Channel'
and 'Region'
features would be excluded from the dataset so that the customer product categories were emphasized in the analysis. By reintroducing the 'Channel'
feature to the dataset, an interesting structure emerges when considering the same PCA dimensionality reduction applied earlier to the original dataset.
Run the code block below to see how each data point is labeled either 'HoReCa'
(Hotel/Restaurant/Cafe) or 'Retail'
the reduced space. In addition, you will find the sample points are circled in the plot, which will identify their labeling.
# Display the clustering results based on 'Channel' data
vs.channel_results(reduced_data, outliers, pca_samples)
Answer:
Note: Once you have completed all of the code implementations and successfully answered each question above, you may finalize your work by exporting the iPython Notebook as an HTML document. You can do this by using the menu above and navigating to
File -> Download as -> HTML (.html). Include the finished document along with this notebook as your submission.


--- layout: post title: The core features of the scientific writing style date: 2011-03-15 01:52:49.000000000 +01:00 type: post published: true status: publish categories: - Scientific writing tags: - advice on scientific writing - tips meta: _edit_last: '29' author: login: Petra Kralj email<EMAIL_ADDRESS>display_name: Petra Kralj first_name: Petra last_name: Kralj ---
As stressed throughout The JEPS Bulletin, an important part of research is writing the report to acquaint the public with your findings. Such publications serve as a platform for academic communication and exchange of opinions. It is very important to follow certain standards and writing style if you intend to cultivate further research based on your results. Here’s what you should keep in mind when forming your message to the scientific community.
Writing a scientific paper assumes knowledge of the purposes of your work as well its intended audience, expertise and knowledge of methodology, and last but not least, a good scientific style (Milas, 2005). What is style in general? It’s "an author’s way of writing" (Klaić, 1983, p. 1267). A text can follow a number of ways of writing – poetical, romantic, informative. The characteristics of a scientific writing style derive from the intention of communicating scientific information (Silobrčić, 1998). Simply put, a good scientific style is one that fulfils the purpose of providing its reader unambiguous comprehensibility of its content. The aim of any publication is to cover the background, the procedure and results and meaning of the research.
To prevent misinterpretations, scientific writing requires clarity and precision, together with logical sequence of presentation of ideas and viewpoints (Milas, 2005; Silobrčić, 1998). Avoiding excessive stylistic flourish and unnecessary details, which extend the text or reduce its clarity, is a prerequisite. The use of abstract and vague expressions blurs legibility and penetrability of the text, as does wrong selection of words. Also, personal attitudes, mitigation or exaggeration of your claims easily lead to misunderstandings and confusion. In any case, the complexity of the subject in no case justifies ambiguity and incomprehensibility of the text (Barzun & Graff, 1957; Silobrčić, 1998).
Weigh the meaning of the words you use. Careless expression of your thoughts may lead to nonsense.
Take an example: 'Although this book differs from Harisse's on Columbus, it is also important'. At least three words here are improper and darken understanding: 'although', 'differs', and 'also'. Taken together, 'although' and 'also' imply that the book which 'differs' from a certain other book is unimportant. And 'differs' by itself is an absurdity, since every work differs from every other. (Barzun &Graff, 1957, p. 250).
Finally, integrity is an essential characteristic of every work. Each thought should follow a logical path and be supported by evidence or be pointed out as a hypothesis. Such presentation of ideas allows the reader to follow and grasp the text with ease.
Of course, the abovementioned features are not the only ones important for a nice flowing scientific text. In addition, proper implementation of the general linguistic principles contributes considerably to the quality of the text. May this be the topic of our future post.
Summary: tips to follow
References:
Barzun, J., and Graff, H., F. (1957). The Modern Researcher. New York: A Harbinger Book.
Klaić, B. (1983). Rječnik stranih riječi. Zagreb: Nakladni zavod Matice hrvatske.
Milas, G. (2005). Istraživačke metode u psihologiji i drugim društvenim znanostima. Jastrebarsko: Naklada Slap.
Silobrčić, V. (1998). Kako sastaviti, objaviti i ocijeniti znanstveno djelo. Zagreb: Medicinska Naklada.
Edited by: Maris Vainre


To get started, climb a route or create a route!
If you wish to know more about this project, visit the about page.


Provides a visual example of a lookup and grid on same page. Initially this was a problem. If the lookup and grid both render this example works.


Automate your safety inspection workflow, including request, completion, and Certificate of Supervision generation.
Auto drop down lists and completion guides with field-specific instructions ensure data is captured accurately and completely.
Cloud document management with E-Spector is the simple and secure way to transform how you work.
Regardless of the devices you're using, E-Spector is fully responsive to offer you the best user experience.
Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod.
Including Building and Construction Authority (BCA), Ministry of Manpower (MOM), PUB, Singapore Civil Defence Force (SCDF).
Including gondola, formwork, scaffold, mast climbing work platforms, rope access, ST, ERSS, and others.
Request for Certificate of Supervision, Request for Inspection, ERSS Annex C, ERSS Annex D, ERSS Annex E, Daily Diary, and others.
Certificate of Supervision (COS), Request for Inspection (RFI), Inspection Checklist, Daily Diary, ERSS.
Automated. Connected. Proactive.
We aim to create the next generation smart worksite through technology and rich data. E-Spector empowers construction firms’ management with the right tools to monitor, analyze, and improve safety inspection workflow.
Sign UpWe're here to help!
Consectetur adipisicing elit. Aut eaque, totam corporis laboriosam veritatis quis ad perspiciatis, totam corporis laboriosam veritatis, consectetur adipisicing elit quos non quis ad perspiciatis, totam corporis ea,
© 2017 G TOP INTERNATIONAL PTE LTD
What our partners say
Donec sed odio dui. Etiam porta sem malesuada.


Routines for the analysis of indirectly measured haplotypes. The statistical methods assume that all subjects are unrelated and that haplotypes are ambiguous (due to unknown linkage phase of the genetic markers). The main functions are: haplo.em(), haplo.glm(), haplo.score(), and haplo.power(); all of which have detailed examples in the vignette.
| Version: | 1.7.9 |
| Depends: | R (≥ 3.0.0), methods, stats, graphics |
| Imports: | rms |
| Suggests: | R.rsp |
| Published: | 2018-04-11 |
| Author: | Sinnwell JP, Schaid DJ |
| Maintainer: | Jason P. Sinnwell <sinnwell.jason at mayo.edu> |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| URL: | http://www.mayo.edu/research/labs/statistical-genetics-genetic-epidemiology/software |
| NeedsCompilation: | yes |
| Materials: | NEWS |
| In views: | Genetics |
| CRAN checks: | haplo.stats results |
| Reference manual: | haplo.stats.pdf |
| Vignettes: |
manualHaploStats |
| Package source: | haplo.stats_1.7.9.tar.gz |
| Windows binaries: | r-devel: haplo.stats_1.7.9.zip, r-release: haplo.stats_1.7.9.zip, r-oldrel: haplo.stats_1.7.9.zip |
| OS X binaries: | r-release: haplo.stats_1.7.9.tgz, r-oldrel: haplo.stats_1.7.9.tgz |
| Old sources: | haplo.stats archive |
| Reverse depends: | BVS, SNPassoc |
| Reverse imports: | BIGDAWG, CollapsABEL, IFP, Rsampletrees |
| Reverse suggests: | asymLD, gap |
Please use the canonical form https://CRAN.R-project.org/package=haplo.stats to link to this page.


initialized sodium instance
Asymmetrically decrypts all shares using an OC's keys
public key of an options counselor
secret key of an options counselor
an array of encrypted data of matched users
object containg decrypted records and errors
Asymmetric decryption
secret key of an options counselor
a decrypted coordinate
Asymmetric encryption
a plaintext string
the public key of an options counselor
encrypted string in base 64 encoding
Converts bytes to their string representation of a number
Checks that all entries have matching index
Encrypting under a single randId and then updating the encrypted data object
encrypted data object
result of OPRF
dictionary of all OC public keys
user passphrase
Decrypts an array of encrypted data
an array of encrypted data of matched users
public key of an options counselor
secret key of an options counselor
object containing decrypted records and errors
Decrypts a single record
additional data associated with ciphertext
decrypted record
Decrypts a single share using the derived key, k
key used to decrypt the record key
current share
encrypted data object corresponding to current share
object containing decrypted records and errors
Decrypts a user's record for editing purposes
original passphrase used to encrypt the record key
a user's record encrypted under each OC public key
object containing decrypted records and errors
Key derivation
result of OPRF
object containing key, matching index, and slope
Encryption workflow
array of all randIds corresponding to each perpId submitted
record information
dictionary of all OC public keys
user's passphrase for use in encrypting for editing
object containing encrypted data and errors
Calculates the y-intercept using a coordinate and slope
a coordinate
y-intercept
Mathematically correct mod over a prime
input value
Converts a string representation of a number to a Uint8Array of bytes
string representation
Symmetric decryption
in base 64 encoding with a nonce split on ("$")
additional data associated with ciphertext
decrypted data
Symmetric encryption
plaintext string
additional data associated with ciphertext
encrypted string in base 64 encoding
original passphrase used to encrypt the record key
a user's record encrypted under each OC public key
a user's updated record
an array of encrypted data containing the cipher text of the updated record
Generated using TypeDoc
Initializes sodium


Squid uses these hostnames to test the DNS before starting. If
Squid can't resolve any of these names, it prints an
error and refuses to run. If the default list
doesn't seem to work on your network, try listing
some local hostnames instead. |
Syntax
|
dns_testnames hostname ...
| |
Default
|
dns_testnames netscape.com internic.net nlanr.net microsoft.com
| |
Example
|
dns_testnames yahoo.com example.com squid-cache.org
|
|


DRUNKS [Spoilers] A film review by Mike Ryan Copyright 1995 Mike Ryan
Director: Peter Cohn (debut) A cast of dozens including Richard Lewis, Faye Dunaway, Dianne Wiest, Spalding Gray, Howard Robbins, Christopher Lawford, and George Martin.
This film debuted tonight at the Boston Film Festival, on the heels of a glowing review by the Boston Globe's Jay Carr. I can't concur--I found it a self-conscious actor's movie--pretty much like watching an audition tape.
If you're not afraid of spoilers, here's what happens: There's an AA meeting, at which each member tells their story. Richard Lewis' character goes first, then takes off and goes on a binge. That's it--that is literally the entire movie. There's nothing here but the barest of frameworks for a bunch of (admittedly talented) actors to give their individual interpretations of alcoholism. Each story is told as a monologue, with no connection to the rest of the film, and no relationships developed between characters (wait, that's an exaggeration - two of them did talk for a minute in the women's room). Each actor works in isolation, which makes it impossible to forget for a moment that you're watching actors performing rather than flesh-and-blood characters. You could extract each monologue from the film into a distinct short, and watching neither the short or the film would you ever guess there was anything missing (other than interest).
Plot - non-existent Cinematography - yawn Acting - generally forced and self-conscious, a waste of some talented people (only Spalding Gray seems to know how to make an isolated monologue ring true)
Recommended only for students of acting. -- Mike Ryan Virtuoso Software http://world.std.com/~deeryan/virtuoso.html
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


4 writes to _current
System.Management.Automation (4)
engine\MshMemberInfo.cs (4)
5046
_current
= null;
5087
_current
= member;
5091
_current
= null;
5117
_current
= null;
1 reference to _current
System.Management.Automation (1)
engine\MshMemberInfo.cs (1)
5108
return
_current
;


This sample shows, how to use dynatree as a navigation menu.
The tree initialisation uses title
tags.
The onActivate
handler then uses node.data.href
to open the the pages in the embedded iframe.
Note that the navigation will fallback to standard HTML links,
when JavaScript is disabled.
The [Toggle tree] button in the embedded welcome page also gives an example on
how to access a tree that exists outside the own frame.
|
|
jquery.dynatree.js project home Link to this page Example Browser View source code


--- layout: post title: Presentation at IT University of Copenhagen date: 2011-03-11 10:05:29.000000000 +01:00 categories: - talks tags: [] status: publish type: post published: true meta: _edit_last: '1' author: login: cybear email<EMAIL_ADDRESS>display_name: cybear first_name: '' last_name: '' ---
Yesterday, I made a presentation on HTML5, CSS3 and Phonegap at IT University of Copenhagen. The audience is attending the course "Dynamic Web Design" has a mixed experience with regards to web development - all know a bit of HTML, CSS and PHP, some also have experience from Java development or similar. During the presentation there were many questions, which I always appreciate. One question was in regards to the new Local Storage in HTML5: We are now enforced by law to inform the user about cookies, do the same rules apply about HTML5 databases?
On this topic I wanted to share this pun: EU “Cookies” Directive. Interactive guide to 25th May and what it means for you
Other useful links:
My slides on Phonegap and mobile strategy


| Status Of Complaints | Nos Of Complaints |
|---|---|
OOpen |
{{helpdeskOpen.countOfOpenComplains}} |
IIn-progress |
{{helpDeskInProgress.countOfInProgressComplains}} |
RResolved |
{{helpDeskResolved.countOfResolvedComplains}} |
CCancelled |
{{heldeskCancelled.countOfInCancelledComplains}} |
HOn-Hold |
{{heldeskHold.countOfHoldComplains}} |
Cash
Bank
Axis Bank
Duties & Taxes
Provisions
Sundry Creditors
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.
Active
Comment
Live
Message
new tweet
Follower
Luciano Durk
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.


{% extends "layouts/base.html" %} {% import "macros/images.html" as image_macros %} {% block content %}
{{ page.summary | striptags | truncate(length=350) | safe}}


Application Containers
Lab 8: Application Patches
Overview
In Lab8 we define an application patch. Patches are comparable to the application upgrades that we've seen in previous labs, but there are three important differences.
- The types of operation that are allowed in a
patch are more limited. Essentially operations which are destructive are not
allowed, including:
- Drop a table, column, index, trigger...
- Create *or replace* view, package, procedure...
- Patches do not involve creation of Application Root Clones.
- Patches are not version-specific. This means that a single patch may be applied to multiple application versions.
Execution
- Open a terminal window
- Change directory to /u01/HOL/app_containers/
- source the environment. At command prompt execute source cdb1.env
- sqlplus /nolog
- At the SQL prompt execute<EMAIL_ADDRESS>Review of Application Container Lab8:
1. Define patch 301 for application wmStore.
a. Add column for financial quarter to wm_Orders.
b. Create a new index on wm_Orders.
c. Add more seed data to wm_List_of_Values.
d. Update data in wm_Orders to set the appropriate value for the newly added denormalized column.
2. Propagate the Upgrade to three franchises (but not to all).
Detailed Steps
Phase 1: Declare beginning of application patch.
Connected to Master Application Root Notice that patches are positive integers. (Compare this with upgrades, which are character strings.)
Phase 2. Upgrade the application schema.
Phase 3. Add more seed data to wm_List_of_Values.
Phase 4. Update orders to specify the appropriate financial quarter.
Remember the sequence of these operations. We shall refer to these in a future lab.
1. Add column wm_Orders.Financial_Quarter_Code.
2. Create index wm_Orders_M1 on wm_Orders.
3. Add rows to wm_List_of_Values
4. Update orders to specify the appropriate financial quarter.
The previous section included some standard DML (updates in this case) to change existing data in the normal course of an upgrade. One curiosity in this case is that the actual data to be updated is in the Application PDBs, not in Application Root. (Notice that no rows were updated by any of these update statements in Application Root.) These statements are captured in Application Root, and will be replayed in the Application PDBs for each tenant / franchise when they synchronize.
Phase 5. Declare the end of the patch definition.
We have now completed the definition of the application patch. As with upgrades, patches are defined in a "begin / end" block. Between the begin and end statements, the patch contains a typical set of SQL statements (both DDL and DML). We have also seen how the steps in the upgrade script are captured in Application Root, to be replayed subsequently in the Application PDBs as they are sync'ed. The patch is applied to the Application PDBs by synchronizing them. In this lab, we'll patch three franchises – Tulsa, California and Tahoe.
Phase 6. Sync Application PDBs for three franchises.
Do not patch NYC yet.
Click Here to Go to Lab 9


--- layout: post title: TivoToGo Web Interface categories: [] tags: [] status: publish type: post published: true meta: _original_post_id: '' _original_import_author: John Duprey author: ---
jduprey
contemplative


?Ludwigia
sect.
Oligospermum
Determined
by
T.P.
Ramamoorthy
Missouri
Botanical
Garden
Ludwigia
peploides
(HBK.)
Raven
subsp.
peploides
PLANTS
OF
JAMAICA
collected
for
the
herbarium
of
DUKE
UNIVERSITY
Determined
by
Elsa
Zardini
1986
Missouri
Botanical
Garden
C.D.
Adams
1963
Mary
Parish:
Area
around
Green
altitude
c.
10-100
feet.
Common
on
fresh
water
pond
margin,
and
wet
depression.
Calyx
and
exposed
ovary
green,
calyx
lobes
with
red
margins,
ovary
with
white
hairs;
petals
yellow;
readily
dropping;
style,
stigma,
filaments
and
m.
r.
crosbyanthers
yellow;
floats
pinkish.
H.
A.
HESPENHEIDE
W.
R.
ANDERSON
No.
4-'9
5
July
,
frEW
Yoy>S
botanical
NEWYORKBOTANiCAL
GARDEN
01447617
01447617
Legend -
Level of confidence that token is an accurately-transcribed word
extremely low
very low
low
undetermined
medium
high
very high


A14 fully reopened after lorry crash
by Holly HumeThe A14 has reopened after a serious collision which left both carriageways closed for several hours.
The dual carriageway was closed from around 3.37am onwards between junction 42 and 43 when a lorry smashed through the central reservation in the early hours of the morning.
Suffolk Constabulary confirmed that the driver had to be taken to hospital for treatment following the incident but that his injuries were not believed to be life-threatening.
Highways England were also assisting on the scene and a recovery truck was called at 5am but did not manage to clear the site for a long time due to the debris.
A spokesman from the police warned that the recovery would take hours and said this morning: "There is a lot of damage that's been caused and it's going to take quite some time to clear."
Highways England were aiming to have one lane in each direction moving by 9am if the recovery had gone smoothly but an hour later than that it was still closed.
Drivers were advised to exit on the roundabout before they reached the closure and instead use the A134, A1302 and A1101.
Traffic flow is now back to normal following hours of standstill.


BULLY A film review by David N. Butterworth Copyright 2001 David N. Butterworth
*1/2 (out of ****)
Kids today, eh?
If you're into watching near on two hours of bored, foul-mouthed Florida teens having sex, doing drugs, having sex, listening to Eminem, having sex, playing video games, having sex, and killing one of their peers, then "Bully"'s for you.
Based on Jim Schutze's novelization of a true-life event, "Bully" charts the story of a handful of disenchanted teenagers who, in 1993, murdered their high school bully in cold, calculated blood. The film could have provided fascinating insights into what turned these aimless kids into premeditated killers. In the hands of controversial director Larry Clark ("Kids"), however, it has less to say about its subject matter and more to say about the filmmaker's pornographic proclivities.
In terms of the incident and what provoked it, "Bully" stirs up nothing new. The high schoolers are presented as a uniformly screwed up lot--bored with life, not much ambition, promiscuous, profane.
The bully in question, Bobby Kent (Nick Stahl), is certainly an unpleasant piece of work but he doesn't exactly tower over his colleagues in the pathological department. He hounds and harries and humiliates his "best friend" Marty (played by Brad Renfro) and Marty's girlfriend Lisa (Rachel Miner) doesn't care for it at all and comes up with the idea of killing Bobby. Simply remove him from the equation.
There's no remorse--the next day they're talking about it as openly as a homework assignment. They did it because they wanted to, and because they could.
What's most troubling about the film, however, isn't the unsettling subject matter and the matter-of-fact way these young people go about eliminating one of their own but the way in which Clark is constantly distracted by his own material. Not only is the nudity plentiful and graphic in "Bully" but there's also an uneasy, exploitative feel to it. Gratuitous crotch shots abound (one of which makes the zipper cut-away in "There's Something About Mary" look like the height of subtlety!). Clark is so pre-occupied with his female (predominantly) leads that you forget, at times, what this movie is supposed to be about. The stripping bare, literally and figuratively, of these actors (who are, after all, playing underage teenagers) becomes harder to watch over time, as you begin to feel for them and question the motives of the man behind the camera.
The conclusion of "Bully" offers up literal snapshots of information about the sentences imposed on each of the protagonists for their involvement in the crime. It's a short sequence of stills--Heather: 7 years; Ali: 40 years; Lisa: life imprisonment, for example--but it's infinitely more telling than the 110 minutes of rampant unpleasantness that precedes it.
"Bully" aims for truth, exploits it shamelessly, then bludgeons it to death.
-- David N. Butterworth<EMAIL_ADDRESS>Got beef? Visit "La Movie Boeuf" online at http://members.dca.net/dnb
========== X-RAMR-ID: 29446 X-Language: en X-RT-ReviewID: 249814 X-RT-TitleID: 1108900 X-RT-SourceID: 878 X-RT-AuthorID: 1393 X-RT-RatingText: 1.5/4
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


| 1 | /* | |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
| 3 | * contributor license agreements. See the NOTICE file distributed with | |
| 4 | * this work for additional information regarding copyright ownership. | |
| 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
| 6 | * (the "License"); you may not use this file except in compliance with | |
| 7 | * the License. You may obtain a copy of the License at | |
| 8 | * | |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 | * | |
| 11 | * Unless required by applicable law or agreed to in writing, software | |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 | * See the License for the specific language governing permissions and | |
| 15 | * limitations under the License. | |
| 16 | */ | |
| 17 | ||
| 18 | package org.apache.commons.imaging.formats.pnm; | |
| 19 | ||
| 20 | import java.awt.image.BufferedImage; | |
| 21 | import java.io.IOException; | |
| 22 | import java.io.OutputStream; | |
| 23 | import java.util.Map; | |
| 24 | ||
| 25 | import org.apache.commons.imaging.ImageWriteException; | |
| 26 | ||
| 27 | public class PamWriter extends PnmWriter { | |
| 28 | public PamWriter() { | |
| 29 | super(true); | |
| 30 | } | |
| 31 | | |
| 32 | @Override | |
| 33 | public void writeImage(final BufferedImage src, final OutputStream os, | |
| 34 | final Map<String, Object> params) throws ImageWriteException, IOException { | |
| 35 | ||
| 36 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PNM_PREFIX_BYTE); |
| 37 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PAM_RAW_CODE); |
| 38 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PNM_NEWLINE); |
| 39 | | |
| 40 | final int width = src.getWidth(); | |
| 41 | final int height = src.getHeight(); | |
| 42 | ||
| 43 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(("WIDTH " + width).getBytes("US-ASCII")); |
| 44 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PNM_NEWLINE); |
| 45 | ||
| 46 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(("HEIGHT " + height).getBytes("US-ASCII")); |
| 47 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PNM_NEWLINE); |
| 48 | | |
| 49 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(("DEPTH 4").getBytes("US-ASCII")); |
| 50 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PNM_NEWLINE); |
| 51 | | |
| 52 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(("MAXVAL 255").getBytes("US-ASCII")); |
| 53 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PNM_NEWLINE); |
| 54 | ||
| 55 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(("TUPLTYPE RGB_ALPHA").getBytes("US-ASCII")); |
| 56 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PNM_NEWLINE); |
| 57 | | |
| 58 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(("ENDHDR").getBytes("US-ASCII")); |
| 59 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(PnmConstants.PNM_NEWLINE); |
| 60 | | |
| 61 |
3
1. writeImage : changed conditional boundary → NO_COVERAGE 2. writeImage : Changed increment from 1 to -1 → NO_COVERAGE 3. writeImage : negated conditional → NO_COVERAGE |
for (int y = 0; y < height; y++) { |
| 62 |
3
1. writeImage : changed conditional boundary → NO_COVERAGE 2. writeImage : Changed increment from 1 to -1 → NO_COVERAGE 3. writeImage : negated conditional → NO_COVERAGE |
for (int x = 0; x < width; x++) { |
| 63 | final int argb = src.getRGB(x, y); | |
| 64 |
2
1. writeImage : Replaced Shift Right with Shift Left → NO_COVERAGE 2. writeImage : Replaced bitwise AND with OR → NO_COVERAGE |
final int alpha = 0xff & (argb >> 24); |
| 65 |
2
1. writeImage : Replaced Shift Right with Shift Left → NO_COVERAGE 2. writeImage : Replaced bitwise AND with OR → NO_COVERAGE |
final int red = 0xff & (argb >> 16); |
| 66 |
2
1. writeImage : Replaced Shift Right with Shift Left → NO_COVERAGE 2. writeImage : Replaced bitwise AND with OR → NO_COVERAGE |
final int green = 0xff & (argb >> 8); |
| 67 |
2
1. writeImage : Replaced Shift Right with Shift Left → NO_COVERAGE 2. writeImage : Replaced bitwise AND with OR → NO_COVERAGE |
final int blue = 0xff & (argb >> 0); |
| 68 | ||
| 69 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write((byte) red); |
| 70 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write((byte) green); |
| 71 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write((byte) blue); |
| 72 |
1
1. writeImage : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write((byte) alpha); |
| 73 | } | |
| 74 | } | |
| 75 | } | |
| 76 | } | |
Mutations | ||
| 36 |
1.1 |
|
| 37 |
1.1 |
|
| 38 |
1.1 |
|
| 43 |
1.1 |
|
| 44 |
1.1 |
|
| 46 |
1.1 |
|
| 47 |
1.1 |
|
| 49 |
1.1 |
|
| 50 |
1.1 |
|
| 52 |
1.1 |
|
| 53 |
1.1 |
|
| 55 |
1.1 |
|
| 56 |
1.1 |
|
| 58 |
1.1 |
|
| 59 |
1.1 |
|
| 61 |
1.1 2.2 3.3 |
|
| 62 |
1.1 2.2 3.3 |
|
| 64 |
1.1 2.2 |
|
| 65 |
1.1 2.2 |
|
| 66 |
1.1 2.2 |
|
| 67 |
1.1 2.2 |
|
| 69 |
1.1 |
|
| 70 |
1.1 |
|
| 71 |
1.1 |
|
| 72 |
1.1 |


--- layout: post title: Common Threads date: 2014-09-15 01:31:45.000000000 -05:00 type: post parent_id: '0' published: true password: '' status: publish categories: - Coworking tags: - Coworking meta: _edit_last: '1' _thumbnail_id: '923' slide_template: default _at_widget: '1' fw:opt:ext:pb:page-builder:json: "[]" fw_options: a:9:{s:12:"page-builder";a:2:{s:4:"json";s:2:"[]";s:14:"builder_active";b:0;}s:9:"title_bar";s:7:"default";s:15:"footer_settings";s:7:"default";s:12:"header_style";a:2:{s:6:"option";s:0:"";s:11:"transparent";a:2:{s:16:"background_color";s:21:"rgba(255,255,255,0.3)";s:12:"border_color";s:0:"";}}s:12:"social_icons";s:0:"";s:12:"contact_info";s:0:"";s:12:"slider_above";a:2:{s:6:"option";s:2:"no";s:3:"yes";a:2:{s:5:"slide";s:1:"c";s:13:"scroll_effect";a:1:{s:6:"option";s:0:"";}}}s:22:"seo-titles-metas-title";s:0:"";s:28:"seo-titles-metas-description";s:0:"";} _wp_old_slug: 2014-06-common-threads author: login: superuser email<EMAIL_ADDRESS>display_name: Administrator first_name: '' last_name: '' ---
I’m awestruck by the growth, collaboration, and comradery shown by the Denton and wider DFW startup community lately.
Last week, we publicly launched TechMill, an Indiegogo campaign for Cowork Denton, and announced our first startup conference for Denton: BootConf. In the first week since our campaign launched, we’ve already reached 13% of our total funding goal — a huge milestone. That’s phenomenal!
To cap this off, the day after our campaign launched, The Grove also launched their Indiegogo campaign to expand their space in Dallas, due to unprecedented growth!
Late last week, I had the pleasure of talking with Justin Nygren, co-owner of The Grove, about the spirit of collaboration and resource sharing in the DFW startup community. Justin proposed that we show solidarity by donating to each other’s campaigns today. In support of Justin’s proposal, TechMill will be contributing directly to the Grove’s expansion campaign.
On top of this, Justin and I are asking all members of both the Grove, and future members of Cowork Denton, to donate directly to each other's campaigns. As Justin likes to say, “This is the new economy.”
The common threads we share with the Dallas startup community are too numerous to list here, but this is our region’s attempt to lead by example. Let’s show the rest of the state how our metroplex values collaboration over competition, and community over selfishness.


Build applications on top of Bitcoin, Dash or Bitcoin Cash blockchains. This library does the hard work under the hood and enables developers to create trully decentralized apps on top of Bitcoin or some of its supported forks.
Build any purpose applications on top of Ethereum blockchain that work in a trully decentralized manner.
This library is still in active development phase ...


Building C++ Applications
Thu 19 October 2017 by Little Captain编译、链接、打包 可执行程序、静态库、动态库 构建、工具集
编译、链接、打包、可执行程序、静态库、动态库
- The three basic tools used to build C++ applications are the
compiler
, thelinker
, and thearchiver
(or librarian). A collection of these programs and possibly other tools is called a toolset.- The
compiler
takes C++ source files as input and producesobject files
, whichcontain
a mixture ofmachine-executable code
andsymbolic references to functions and data
. - The
archiver
takes a collection ofobject files
asinput
andproduces a static library
, or archive,which is simply a collection of object files grouped for convenient use
. - The
linker
takes a collection ofobject files
andlibraries
andresolves
theirsymbolic references
toproduce
either anexecutable
ordynamic library
. Roughly speaking, thelinker
operates bymatching each use of a symbol to its definition
. When an executable or dynamic library is created, it is said to be linked; the libraries used to build the executable or dynamic library are said to be linked against.
- The
- An
executable
, or application, is simply any program that can be executed by the operating system. - A
dynamic library
, also called ashared library
, is like an executable except thatit can’t be run on its own
;it consists of a body of machine-executable code that is loaded into memory after an application is started and can be shared by one or more applications.
On Windows, dynamic libraries are also called dynamic link libraries (DLLs). - The
object files
andstatic libraries
on which an executable depends are needed only when the executable is built. - The
dynamic libraries
on which an executable depends, however, must be present on a user’s system when the executable is run.
File extensions on Windows and Unix
| File type | Windows | Mac OS X | Other Unix |
|---|---|---|---|
| Object files | .obj | .o | .o |
| Static libraries | .lib | .a | .a |
| Dynamic libraries | .dll | .dylib | .so |
| Executables | .exe | No extension | No extension |
构建、工具集
构建
- A
build system
provides a text file format for describing a collection of source files and the binary files that should be generated from them, together with a build tool that reads these text files and generates the binary files by invoking the appropriate command-line tools. Typically, these text files are created and edited using a text editor, and the build tool is invoked from the command line. Some build systems, however, provide a graphical interface for editing the text files and invoking the build tool. - The most common build tool is the
make
utility; the text files it relies on are calledmakefiles
. While there are many versions of make, such as GNU make, the most powerful and portable make incarnation.GNU make
is an extremely flexible tool that can be more than building C++ applications. It also has the advantage of being widely used and well-understood by developers. Unfortunately, getting GNU make to do exactly what you want it to do can be achallenge
, especially with complex projects involving multiple toolsets. For that reason, I will also discuss Boost.Build, a powerful and extensible build system designed from the ground up for building C++ applications. Boost.Build
was developed by members of the Boost C++ Libraries project. It has been used by a large community of developers for several years, and is currently under active development. Boost.Build uses a build tool calledbjam
and text files calledJamfiles
. Its greatest strength is the ease with which it allows you to manage complex projects involving multiple platforms and build configurations. Although Boost.Build started out as an extension of Perforce’s Jam build system, it has since undergone extensive redesign.
工具集
Names of command-line tools for various toolsets
| Toolset | Compiler | Linker | Archiver |
|---|---|---|---|
| GCC | g++[.exe] | g++ | ar[.exe] |
| Visual C++ | cl.exe | link.exe | lib.exe |
| Intel (Windows) | icl.exe | xilink.exe | xilib.exe |
| Intel (Linux) | icpc | icpc | ar ranlib |
| Metrowerks | mwcc[.exe] | mwld[.exe] | mwld[.exe] |
| Comeau | como[.exe] | como[.exe] | Toolset-dependent |
| Borland | bcc32.exe | bcc32.exe ilink32.exe |
tlib.exe |
| Digital Mars | dmc.exe | link.exe | lib.exe |
Location of your command-line tools
| Toolset | Location |
|---|---|
| GCC (Unix) | Typically /usr/bin or /usr/local/bin |
| GCC (Cygwin) | The bin subdirectory of your Cygwin installation |
| GCC (MinGW) | The bin subdirectory of your MinGW installation |
| Visual C++ | The VC/bin subdirectory of your Visual Studio installation |
| Intel (Windows) | The Bin subdirectory of your Intel compiler installation |
| Intel (Linux) | The bin subdirectory of your Intel compiler installation |
| Metrowerks | The Other Metrowerks Tools/Command Line Tools subdirectory of your CodeWarrior installation |
| Comeau | The bin subdirectory of your Comeau installation |
| Borland | The Bin subdirectory of your C++Builder, C++BuilderX or Borland command-line tools installation |
The GNU Compiler Collection (GCC)
- GCC is a collection of compilers for a wide assortment of languages, including C and C++. It’s remarkable for being open source, available on almost every imaginable platform, and highly conformant to the C++ language standard. It’s the dominant compiler on many Unix platforms, and is also widely used on Microsoft Windows. You can learn a lot by compiling your code with GCC. If you think you know a way to improve the C++ language, you can test your idea with the GCC code base.
- GCC comes with libstdc++, a good open source implementation of the C++ standard library. It can also be used with the open source STLPort C++ standard library and with Dinkumware’s standard library.
Visual C++
- Microsoft’s toolset is the dominant toolset on the Windows platform. While several old versions are still in wide use, the most recent version is highly standards conforming. It is also capable of producing highly optimized code. Microsoft’s tools are distributed with the Visual C++ and Visual Studio development environments. Visual C++ comes with a customized version of the Dinkumware C++ standard library implementation. Dinkumware’s C++ standard library is among the most efficient and standards-conforming commercial implementation.
The Usage of GCC
Building a Simple “Hello, World” Application from the Command Line
# Commands for compiling and linking hello.cpp in a single step
g++ -o hello hello.cpp
# Commands for compiling hello.cpp without linking
g++ -c -o hello.o hello.cpp
# Commands for linking hello
g++ -o hello hello.o
Building a Static Library from the Command Line
# Commands for creating the archive libjohnpaul.lib or libjohnpaul.a
ar ru libjohnpaul.a john.o paul.o johnpaul.o
g++ -c -o john.o john.cpp
g++ -c -o paul.o paul.cpp
g++ -c -o johnpaul.o johnpaul.cpp
# The `ru` option tells `ar` to add the given object files to the specified archive if there are no existing archive members with the same names, but to update an existing archive member only if the given object file is newer than the existing member.
ar ru libjohnpaul.a john.o paul.o johnpaul.o
# Traditionally, after an archive was created or updated, the tool `ranlib` was used to create or update the archive’s symbol table, i.e., the index of the symbols that appear in the various object files it contains.
ranlib libjohnpaul.a
Building a Dynamic Library from the Command Line
# GCC
g++ -shared -fPIC -o libgeorgeringo.so george.o ringo.o georgeringo.o
# GCC (Mac OS X)
g++ -dynamiclib -fPIC -o libgeorgeringo.dylib george.o ringo.o georgeringo.o
# GCC (Cygwin)
g++ -shared -o libgeorgeringo.dll -Wl,--out-implib,libgeorgeringo.dll.a -W1,--export-all-symbols -Wl,--enable-auto-image-base george.o ringo.o georgeringo.o
# GCC (MinGW)
g++ -shared -o libgeorgeringo.dll -Wl,--out-implib,libgeorgeringo.a -W1,--export-all-symbols -Wl,--enable-auto-image-base george.o ringo.o georgeringo.o
- Each command line specifies:
- The name of the input files: george.obj, ringo.obj, and georgeringo.obj
- The name of the dynamic library to be created
- On Windows, the name of the import library
Some Unix linkers
should be told to generate position-independent code using the option-fPIC
(GCC and Intel for Linux). This option makes it more likely that multiple processes will be able to share a single copy of the dynamic library’s code; on some systems, failing to specify this option can cause a linker error. Similarly, on Windows the GCC linker the option --enable-auto-image-base makes it less likely that the operating system will attempt to load two dynamic libraries at the same location; using this option helps to speed DLL loading.
Symbol visibility
Dynamic libraries
can contain the definitions of classes, functions, and data.On some platforms
, all such symbols are automatically accessible to code which uses a dynamic library;other systems
offer programmers fine-grained control over which symbols are accessible. Being able to determine which symbols should be visible on a case-by-case basis is generally advantageous; it gives a programmer more explicit control of his library’s public interface, and it often provides superior performance. It also makes building and using dynamic libraries more complex, however.With most Windows toolsets
, in order for a symbol defined in a dynamic library to be available to code which uses the dynamically library,it must be explicitly exported when the dynamic library is built and imported when an executable or dynamic library that uses the dynamic library is built
. Some Unix toolsets also offer this flexibility; this is true for recent versions of GCC on several platforms, for Metrowerks on Mac OS X, and for Intel on Linux. In some cases, however, there is no alternative but to make all symbols visible.
Passing libraries to the linker
On Unix
, a dynamic library can be specified as input to the linker when code using the dynamic library is linked.On Windows
, except when using GCC, dynamic libraries are not specified directly as input to the linker; instead, an import library or module definition file is used.
Import libraries and module definition files
- Import libraries, roughly speaking, are static libraries containing the information needed to invoke functions in a DLL at runtime. It’s not necessary to know how they work, only how to create and use them. Most linkers create import libraries automatically when you build a DLL, but in some cases it may be necessary to use a separate tool called an import librarian.
- A module definition file, or
.def
file, is a text file that describes the functions and data exported by a DLL. A.def
file can be written by hand or automatically generated by a tool.
A module definition file for libgeorgeringo.dll
LIBRARY LIBGEORGERINGO.DLL
EXPORTS
Georgeringo @1
Exporting symbols from a DLL
- There are two standard methods for exporting symbols from a Windows DLL:
- Use the
__declspec(dllexport)
attribute in the DLL’s headers, and build an import library for use when linking code that uses your DLL.
The__declspec(dllexport)
attribute should be inserted at the beginning of the declarations of exported functions and data, following any linkage specifiers, and immediately following the class or struct keyword for exported classes. Note that__declspec(dllexport)
is not part of the C++ language;it is a language extension implemented by most Windows compilers
. - Create a .def file describing the functions and data exported by your dynamic library.
Using the _ _declspec(dllexport) attribute
__declpec(dllexport) int m = 3; // Exported data definition
extern __declpec(dllexport) int n; // Exported data declaration
__declpec(dllexport) void f(); // Exported function declaration
class __declpec(dllexport) c { // Exported class definition
/* ... */
};
- Using a
.def
file has certain advantages; for instance, it can allow functions in a DLL to be accessed by number rather than name, decreasing the size of a DLL. It also eliminates the need for the messy preprocessor directives. It has some seriousdrawbacks
, however. For example, a.def
file cannot be used to export classes. Furthermore, it can be difficult to remember to update your .def file when you add, remove, or modify functions in your DLL. I thereforerecommend
that youalways use __declspec(dllexport)
. To learn the full syntax of .def files as well as how to use them, consult your toolset’s documentation.
Importing symbols from a DLL
- There are two ways to import symbols:
- In the headers included by source code that uses your DLL, use the attribute
__declspec(dllimport)
and pass an import library to the linker when linking code that uses your DLL. -
Specify a
.def
file when linking code which depends on you DLL. -
Just as with exporting symbols, I
recommend
that you use the attribute__declspec(dllimport)
in your source code instead of using .def files. The attribute __declspec(dllimport) is used exactly like the attribute __declspec(dllexport), discussed earlier. Like__declspec(dllexport)
,__declspec(dllimport)
isnot
part of theC++ language
, butan extension implemented by most Windows compilers
. - If you choose to use __declspec(dllexport) and __declspec(dllimport), you must be sure to use
__declspec(dllexport)
when building your DLL and__declspec(dllimport)
when compiling code that uses your DLL. One approach would be to use two sets of headers: one for building your DLL and the other for compiling code that uses your DLL. This is not satisfactory, however, since it is difficult to maintain two separate versions of the same headers. Instead
, the usual approach is to define a macro that expands to __declspec(dllexport) when building your DLL and to __declspec(dllimport) otherwise. In Example, I used the macro GEORGERINGO_DECL for this purpose. On Windows, GEORGERINGO_DECL expands to __declspec(dllexport) if the macro GEORGERING_SOURCE is defined and to __declspec(dllimport) otherwise. By defining GEORGERING_SOURCE when building the DLL libgeorgeringo.dll but not when compiling code that uses libgeorgeringo.dll, you obtain the desired result.
Example
#ifndef GEORGERINGO_HPP_INCLUDED
#define GEORGERINGO_HPP_INCLUDED
// define GEORGERINGO_DLL when building libgerogreringo.dll
# if defined(_WIN32) && !defined(__GNUC__)
# ifdef GEORGERINGO_DLL
# define GEORGERINGO_DECL __declspec(dllexport)
# else
# define GEORGERINGO_DECL __declspec(dllimport)
# endif
# endif // WIN32
#ifndef GEORGERINGO_DECL
# define GEORGERINGO_DECL
#endif
// Prints "George, and Ringo\n"
#ifdef __MWERKS__
# pragma export on
#endif
GEORGERINGO_DECL void georgeringo();
#ifdef __MWERKS__
# pragma export off
#endif
#endif // GEORGERINGO_HPP_INCLUDED
Building DLLs with GCC
- The Cygwin and MinGW ports of GCC, handle DLLs
differently
than other Windows toolsets. When you build a DLL with GCC, all functions, classes, and data are exported by default. This behavior can be modified by passing the option --no-export-all-symbols to the linker, by using the attribute __declspec(dllexport) in your source files, or by using a .def file. In each of these three cases, unless you use the option --export-all-symbols to force the linker to export all symbols, the only exported functions, classes, and data will be those marked __declspec(dllexport) or listed in the .def file. - It’s therefore possible to use the GCC toolset to build DLLs in two ways: like an ordinary Windows toolset, exporting symbols explicitly using __declspec, or like a Unix toolset, exporting all symbols automatically. If you choose this method, you should consider using the option --export-all-symbols as a safety measure, in case you happen to include headers containing __declspec(dllexport).
- GCC differs from other Windows toolsets in a second way: rather than passing the linker an import library associated with a DLL, you can pass the DLL itself. This is usually faster than using an import library. It can also create problems, however, since several versions of a DLL may exist on your system, and you must ensure that the linker selects the correct version.
GCC 4.0’s -fvisibility option
- See C++ Cookbook 30 page
Building a Complex Application from the Command Line
- Step
- Start by building the static and dynamic libraries on which your application depends. Or use the third party libraries
- Next, compile your application’s .cpp files into object files. You may need to use the -I option to tell your compiler where to search for the headers needed by your application
- Finally, use your linker to produce an executable from the collection of object files and libraries. For each library, you must either provide a full pathname or tell the linker where to search for it
- At each stage of this process, if you are using a toolset which comes with static and dynamic variants of its runtime libraries, and if your program uses at least one dynamic library, you should direct the compiler or linker to use a dynamically linked runtime library
Commands for linking the application hellobeatle.exe
| Toolset | Input files | Command line |
|---|---|---|
| GCC (Unix) | hellobeatles.o libjohnpaul.a libgeorgeringo.so |
g++ -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo or g++ -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a ../georgeringo/libgeorgeringo.so |
| GCC (Mac OS X) | hellobeatles.o libjohnpaul.a libgeorgeringo.dylib |
g++ -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo or g++ -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a ../georgeringo/libgeorgeringo.dylib |
| GCC (Cygwin) | hellobeatles.o libjohnpaul.a libgeorgeringo.dll.a |
g++ -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo or g++ -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a ../georgeringo/libgeorgeringo.dll.a |
| GCC (MinGW) | hellobeatles.o libjohnpaul.a libgeorgeringo.a |
g++ -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo or g++ --o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a ../georgeringo/libgeorgeringo.a |
| Visual C++ | hellobeatles.obj libjohnpaul.lib libgeorgeringo.lib |
link -nologo -out:hellobeatles.exe -libpath:../johnpaul -libpath:../georgeringo libjohnpaul.lib libgeorgeringo.lib hellobeatles.obj |
- On both Windows and Unix, libraries can be passed to the linker in two ways:
- By specifying a pathname on the command line
- By specifying the simple name of the library together with a location to search for the library
The locations to search for libraries can usually be specified on the command line. Most linkers use the option
-L<directory>
for this purpose, but Visual C++ use-lipath:<directory>
- The way the name of a library is specified to the linker differs between Unix and Windows.
On Windows
, the full name of the library is specified, including the file extension.On Unix—and on Windows when using the GCC toolset—libraries
are specified using the -l option followed by the name of the library, with the file extension and the lib prefix removed. This means that the name ofa library must begin with lib to be automatically found by the linker
. More interestingly, it gives the linker the opportunity to choose between several versions of a library. If the linker finds both static and dynamic version of a library, the dynamic library is selected, unless otherwise specified. On some systems, the linker may choose between several versions of a dynamic library based on the portion of the file name following .so. - Be aware that Unix linkers can be very sensitive to the order in which object files and static libraries are specified on the command line: if a static library or object file references a symbol defined in a second static library or object file, the first file must appear before the second file on the command line. To resolve circular dependencies, it is sometimes necessary to specify a given library or object file more than once. Another solution is to pass a sequence of object files and static libraries to linker bracketed by
-(
and-)
; this causes the file to be searched repeatedly until all references are resolved. This option should be avoided if possible because it can significantly degrade performance.
Running your application
- If your application uses a dynamic variant of your toolset’s runtime library, the runtime library must be available when your application is run and in a location where it will be found automatically by the operating system’s dynamic loader.
Typically, this means that the dynamic runtime library must be placed either in the same directory as your application or in one of a list of system-specific directories.
This is more of a concern when developing for Windows than when developing for Unix, since on Unix the appropriate runtime libraries are often already installed in the correct locations.
Boost.Build
Build process
Jamfiles
and an interpreter calledb2
- 每一个包含配置文件的目录都是一个项目, 如果这个目录中没有配置文件, 什么都不会发生.
- 当
b2
启动时, 它只在当前目录中搜索配置文件, 如果没有它不会做任何事情. b2
搜索的文件名为Jamfile.jam
. 如果在当前目录中找到了Jamfile
, 它将继续在父目录中搜索更多的Jamfile
.b2
向上搜索知道找到一个配置文件名为Jamroot.jam
.Jamroot.jam
和Jamfile.jam
没有区别, 它仅仅用于指示b2
不用再向上继续搜索了.b2
在父文件夹中搜索配置文件的原因是: 便于分组配置. 如果一些组件有相似的配置, 可以将相似的配置写入配置文件放入父文件夹中, 在子文件夹的组件构建时, 父文件夹的中配置将自动被使用- 注意:
b2
必须找到Jamroot.jam
文件. 如果Jamroot.jam
文件存在于当前文件夹下, 那么就不需要Jamfile.jam
文件了. 如果Jamroot.jam
文件在父文件夹下, 那么Jamfile.jam
就必须存在于当前文件夹下, 否则b2
不做任何事情 - 如果将
b2
复制到不包含Jamfile
的目录，并启动程序，b2
将抛出找不到构建系统的错误.b2
首先做的是加载构建系统
而不是搜索Jamfile
b2
是一个解释器(解释Jamfile
), 它并不知道怎么构建程序.Boost.Build
是Jamfile
的真实执行者,Jamfile
包含使Boost.Build
成为强大工具的所有执行逻辑.b2
仅仅读取Jamfile
的内容, 所以它需要知道到哪里去寻找Jamfiles Boost.Build
b2
启动后, 首先在当前目录寻找boost-build.jam
, 如果没有找到就在所有的父文件夹. 这个文件中只需要告诉b2
到什么地方去寻找构建系统boost-build /Users/Liu-Mac/CODE/C++/boost_1_65_1/tools/build/src ;
. 包含构建系统的文件中必须包含bootstrap.jam
文件, 这就是b2
加载构建系统需要的文件- 如果启动
b2
时, 没有指定使用的工具集,b2
会自行检测并决定使用哪个工具集. 手动指定方法b2 toolset = gcc
orb2 toolset = msvc
- 一旦构建系统被发现, 加载, 锁定工具集,
b2
在当前目录搜索Jamfile.jam
, 如果没有找到就抛出错误 - 如果你创建了一个空的
Jamfile.jam
, 启动b2
后, 另一个错误将抛出,b2
最终需要寻找一个叫Jamroot.jam
的Jamfile
- 注意: 如果你的项目很小, 那么你只需要一个存放于当前目录的配置文件
Jamroot.jam
. - 构建过程总结:
-
- 在当前目录创建
boost-build.jam
文件, 用于指示构建系统
地址, 保证构建系统目录中存在bootstrap.jam
文件
- 在当前目录创建
-
- 编写
Jamfiles
. 小项目: 直接在当前项目中创建Jamroot.jam
文件; 大项目: 当前目录中创建Jamfile.jam
, 将各个组件公共的配置项, 抽出放入父目录的Jamfile.jam
文件中, 工程根目录必须存在Jamroot.jam
文件
- 编写
-
- 启动
b2
程序, 进行构建b2 toolset = gcc
- 启动
-
| Toolset Name | Vendor | Notes |
|---|---|---|
| acc | Hewlett Packard | Only very recent versions are known to work well with Boost |
| borland | Borland | |
| como | Comeau Computing | Using this toolset may require configuring another toolset to act as its backend. |
| darwin | Apple Computer | Apple's version of the GCC toolchain with support for Darwin and MacOS X features such as frameworks. |
| gcc | The Gnu Project | Includes support for Cygwin and MinGW compilers. |
| hp_cxx | Hewlett Packard | Targeted at the Tru64 operating system. |
| intel | Intel | |
| msvc | Microsoft | |
| sun | Oracle | Only very recent versions are known to work well with Boost. Note that the Oracle/Sun compiler has a large number of options which effect binary compatibility: it is vital that the libraries are built with the same options that your appliction will use. In particular be aware that the default standard library may not work well with Boost, unless you are building for C++11. The particular compiler options you need can be injected with the b2 command line options cxxflags=and linkflags=. For example to build with the Apache standard library in C++03 mode use b2 cxxflags=-library=stdcxx4 linkflags=-library=stdcxx4. |
| vacpp | IBM | The VisualAge C++ compiler. |
Basic tasks
Rules
andfeatures
Boost.Build
提供了很多内置的规则(函数).exe
就是最常用的一个.Boost.Build
基于的编程语言, 只有一种数据类型, 就是字符串数组
. 数组可以为空或包含一个或多个字符串.- 函数调用的规则: 字符串如果有空格就要使用双引号包裹. 参数之间用
:
隔开, 函数调用结尾使用;
. 语句中, 严格使用空格隔开,:
左右,;
左侧.
exe规则
exe hello : hello.cpp ;
# 指定生成 `release` 版本, 默认是生成 `debug` 版本
exe hello : hello.cpp : <variant>release ;
# `b2 variant = debug` 在上面的 Jamfile 下, 这条命令会报错.
# `exe` 的第四个参数包含默认使用, 但是可以被覆盖的功能
exe hello : hello.cpp : : <variant>release ;
# 同时构建 `debug` `release` 版本
# 第四个参数值不能放在第三个参数, 这会抛出错误. 不能将互相排斥的值传入第三个参数
exe hello : hello.cpp : : <variant>debug <variant>release ;
# 在 exe 中内置两个预处理指令 WIN32 、 _WIN32
# <define> 用于定义预处理指令
exe hello : hello.cpp : <define>WIN32 <define>_WIN32 : <variant>debug <variant>release ;
# <define> 并不互斥, 所以这里将其放在第四个参数和第三个参数的唯一区别就是: 第四个参数的是默认值, 可以被覆盖丢弃, 第三个参数传递的任何东西是不可改变的
exe hello : hello.cpp : : <variant>debug <variant>release <define>WIN32 <define>_WIN32 ;
# <optimization> 互斥. 所以这里会生成 2 * 2 (4) 个版本
exe hello : hello.cpp : : <variant>debug <variant>release <optimization>speed <optimization>off ;
lib规则
# 构建动态链接库(默认)
lib world : world.cpp ;
# 设置 <link> 标签为 static, 可以生成静态库
lib world : world.cpp : <link>static ;
# 同时构建静态和动态链接库. 第三个和第四个参数的规则和 exe 一样
lib hello : hello.cpp : : <link>static <link>shared ;
install规则
exe hello : hello.cpp ;
# hello 是对第一个语句中的 hello 的引用
install "/Users/Liu-Mac/Desktop/bin" : hello ;
# 使用 <locatin> 标签将安装目录放到第三个参数
# 将引用上一个语句的 hello 尽量放在前面的参数位置上
install install-bin : hello : <location>"/Users/Liu-Mac/Desktop/bin" ;
# 通过 <target-os> 确定操作系统, 然后指定不同的安装目录
install install-bin : hello : <target-os>windows:<location>"C:/Program Files/hello" <target-os>linux:<location>/usr/local/bin ;
glob规则
# glob 规则允许你使用通配符
# 这是一个嵌套的函数调用, glob 规则的结果作为 exe 规则的第二个参数传入. 嵌套调用的时候使用 `[` `]`
exe hello : [ glob *.cpp ] ;
Project management
Multiple Jamfiles
Best practices
How Boost.Build is used by others
Rule reference
Building blocks for Jamfiles
Feature reference
Configuration options for the build process
GNU make
- 待续...


--- layout: page use-site-title: false ---
I am an Assistant Professor in Computer Science at Weber State University. Previously, I was a research scientist at Snap Inc. Also, I got my Ph.D. from University of Pittsburgh working with Computer Vision. My research interests are computer vision, machine learning and natural language processing. I am advised by Prof. Adriana Kovashka. I mainly work with attribute recognition. Many of my projects involve deep learning, gaze prediction, transfer learning, reinforcement learning, and metric learning.
I received my Master from the Mathematics and Computer Science Institute (ICMC-USP) at University of Sao Paulo, Brasil. My advisor was Prof. Alneu Lopes, and I was part of the Computational Intelligence Laboratory (LABIC). I mainly worked with ensemble algorithms applied to graph-based classifiers. I got my undergrad from National University of Trujillo, Peru with a major in computer science. Also, I was a member of the Computer Science Students Society (SECC).


Page
public abstract class Page
| Field Summary | |
|---|---|
| protected mixed | The configuration */ |
| protected mixed | The content of the requested page as DOMDocument. |
| protected mixed | Name of the folder where the content is placed. |
| protected mixed | Reference to the Site. |
| Constructor Summary | |
|---|---|
Page() Constructor. |
| Method Summary | |
|---|---|
| protected true, | Check if user authentication is activated and whether the requested page has restrictions. |
| abstract the | Processes the contents of the page. |
| protected Cache | getCache() Returns cache instance. |
| the | Returns the content of this page. |
| void | setConfiguration(Configuration configuration) Sets the configuration Injected by dependency injection. |
| void | setContentPath(mixed path, string contentPath) Sets the name of the folder where the content is placed. |
| void | Sets the reference to the Site. |
protected mixed $configuration = null
The configuration */
protected mixed $content = null
The content of the requested page as DOMDocument. */
protected mixed $contentPath = null
Name of the folder where the content is placed. */
protected mixed $site = null
Reference to the Site. */
public Page()
Constructor. /
protected true, checkPermissions()
Check if user authentication is activated and whether the requested page has restrictions.
public abstract the generateContent()
Processes the contents of the page.
protected Cache getCache()
Returns cache instance.
public the getContent()
Returns the content of this page.
public void setConfiguration(Configuration configuration)
Sets the configuration Injected by dependency injection.
public void setContentPath(mixed path, string contentPath)
Sets the name of the folder where the content is placed.
public void setSite(Site site)
Sets the reference to the Site. Injected by dependency injection.
Renders the requested page and creates the navigation. /


{% extends 'layouts/application.html' %} {% from 'macros/helpers.html' import sprite %} {% import "items/messages/message-items.html" as messageItems %} {% import "items/messages/message-button-container.html" as buttonContainer %} {% block content %}


Commitment sent to Acme Coventry Ltd for approval
{% include "includes/account-name-number.html" %}Commitments in progress
You have 4 contracts in progress with employers
Acme Coventry Ltd
Reference:
98HGS3F
Status:
Needs provider input
Date started:
14th August 2018
15 Aeronautical engineers
Acme Coventry Ltd
Reference:
55HGS3F
Status:
Employer updaing
Date started:
30th June 2018
196 Mechatronics maintenance engineers
96 Manufacturing engineers
1 Survival equipment fitter
Cyberdyne Systems Inc
Reference:
MGF897F
Status:
New
Date started:
21th August 2018
5 Network engineers
6 Cyber intrusion analysts
1 Cyber security technologist
Tyrell Corp
Reference:
999GHY4
Status:
New
Date started:
21th August 2018
55 Embedded Electronic Systems Design and Development Engineer
43 Cyber intrusion analysts
25 Embedded Electronic Systems Design and Development Engineer


File an Issue
Documentation
Install
wasm-pack
📦✨ your favorite rust -> wasm workflow tool!
✨ Install wasm-pack 0.12.0 ✨
17 June 2023 |
Release Notes


pprofile_dev.Rmd
The patient profile has been packaged as a shiny module to facilitate deployment. It can be added to any app that uses standard ADaM datasets with only a couple of lines.
Server side, ADaM datasets are passed in the module call.
callModule(patientProfile_mod, id = "pp_module1",
ADSL = myADSL, ADAE = myADAE, ADCM = myADCM, ADLB = myADLB,
ADEG = myADEG, ADEX = myADEX, ADPC = myADPC)
Aside from ADSL
, all other datasets can be left NULL. Missing datasets simply disable some of the functionalities of the module. Moreover, whenever informative columns are missing, the submodules will attempt to find alternative sources within the given data.
While the patient profile is meant to be used as a single top level module that will adapt to the data available, submodules are exported by the package and can be used individually. They are currently impplemented as tabPanel
, so their use is restricted to compatible containers (navbarPage
/avaNavbarPage
, tabsetPanel
/avaTabPanel
, …).
For example, to include the Exposure & Lab values module alone
# Server
callModule(module = exlb_mod, id = "exlb_auto", uid = uid,
ADSL = ADSL, ADLB = ADLB, ADEX = ADEX, ADPC = ADPC)
# UI (within a tabset or menubar)
exlb_UI(ns("exlb_auto"))
When used in this manner, it is the developer’s responsibility to add the appropritate data checks to ensure correct behaviour.
Refer to the individual submodules documentation for details on the required inputs.
A uid
argument can be passed to the patient profile. By creating a new input binding in the server code and linking it to a Shiny.onInputChange
event, we can set the participant profile to automatically select a participant of interest targeted from another plot.
# Server code
uid <- reactiveVal()
observe({
ns <- session$ns
if(!is.null(input$patient_js)){
print("Updating selected patient")
uid(input$patient_selector)
}
})
# Module call
callModule(patientProfile_mod, id = "pp_module1", uid = uid, ADSL = myADSL)
The AVA safety explorer is linked with the patient profile, such that when a participant is clicked in the timelines or safety outlier explorer, the subject is pre-selected in the patient profile module.
Likewise, if the eDISH plot is also part of the app, it will have the same interaction with the participant profile.
An example is available in the pp-template
shiny app embeded within the package.
Using plots from the plotly
package and the onRender
function of the htmlwidgets
package, javascript code can be added to plot events. We can use this to link a custom plot with the patient profile
# p is a plotly object
p <- p %>% onRender("
function(el){
el.on('plotly_click', function(d){
selsub = d.points[0].data.key[d.points[0].pointNumber];
console.log('Click: ', selsub);
Shiny.onInputChange('pp_module1-patient_js', selsub);
})
}
")
The chunk of code assume that the module id is “pp_module1”. If the module is named differently, the render string can be built
module_id <- "pp_module2"
render <- paste0("
function(el){
el.on('plotly_click', function(d){
selsub = d.points[0].data.key[d.points[0].pointNumber];
console.log('Click: ', selsub);
Shiny.onInputChange('", module_id, "-patient_js', selsub);
})
}
")
If the plot function is part of its own module, then the namespace must be passed instead of the module name.
target <- ns("patient_js")
render <- paste0("
function(el){
el.on('plotly_click', function(d){
selsub = d.points[0].data.key[d.points[0].pointNumber];
console.log('Click: ', selsub);
Shiny.onInputChange('", target, "', selsub);
})
}
")
All visualization tools were created as self contained submodules, making it trivial to extend the functionalities of the patient profile by adding new submodules.
Developers are encouraged to submit merge requests with their own shiny modules or open issues to suggest new visualization on the package’s GitLab page.