Extracting Ngrams with ml.net - n-gram

I have the following pipeline:
var mlContext = new MLContext();
var data = mlContext.Data.LoadFromEnumerable(new[]
{
new Input {Message = "one two three one two three"},
new Input {Message = "one two"},
new Input {Message = "two three"}
});
var pipeline =
mlContext.Transforms.Text.FeaturizeText("TextFeatures", "Message")
.Append(mlContext.Transforms.Text.TokenizeCharacters(
"MessageTokens", "Message"))
.Append(mlContext.Transforms.Text.ProduceNgrams(
"MessageNgrams", "MessageTokens", 2));
var transformedData = pipeline.Fit(data).Transform(data);
"MessageNgrams" column after pipe execution contains float vectors. How can I get actual Ngrams i.e. "one two", "two tree"?

List<string> getNgram(string str, int nsize)
{
var mlContext = new MLContext();
var dataview = mlContext.Data.LoadFromEnumerable(new List<TextData>() { new TextData { Text = str } });
var textPipeline = mlContext.Transforms.Text.TokenizeIntoWords("Tokens", "Text")
.Append(mlContext.Transforms.Conversion.MapValueToKey("Tokens"))
.Append(mlContext.Transforms.Text.ProduceNgrams("NgramFeatures", "Tokens",
ngramLength: nsize,
useAllLengths: false,
weighting: NgramExtractingEstimator.WeightingCriteria.Tf));
var textTransformer = textPipeline.Fit(dataview);
var transformedDataView = textTransformer.Transform(dataview);
VBuffer<ReadOnlyMemory<char>> slotNames = default;
transformedDataView.Schema["NgramFeatures"].GetSlotNames(ref slotNames);
var NgramFeaturesColumn = transformedDataView.GetColumn<VBuffer<float>>(transformedDataView.Schema["NgramFeatures"]);
var ngrams = slotNames.GetValues().ToArray().Select(x=>x.Span.ToString().Replace('|',' '));
return ngrams.ToList();
}

Here is a code snippet which works for my SCDA, should be very similar or give you hints on how to achieve it.
var slotLabelBuffer = default(VBuffer<ReadOnlyMemory<char>>);
transformedData.Schema["MessageNgrams"].GetSlotNames(ref slotLabelBuffer);
var slotLabels = new Dictionary<int, string>();
for (int i = 0; i < slotLabelBuffer.Length; i++)
slotLabels.Add(i, slotLabelBuffer.GetItemOrDefault(i).ToString());
Index of slotLabels corresponds to your float vector.

Related

how to to convert for to foreach

jslint tell Unexpected 'for'.
so i think that i must convert for with foreach
but how?
if someone can help
thanks
// Grab the original element
var original = document.getElementsByTagName("noscript")[0];
// Create a replacement tag of the desired type
var replacement = document.createElement("span");
var i;
// Grab all of the original's attributes, and pass them to the replacement
for(i = 0, l = original.attributes.length; i < l; ++i){
var nodeName = original.attributes.item(i).nodeName;
var nodeValue = original.attributes.item(i).nodeValue;
replacement.setAttribute(nodeName, nodeValue);
}
// Persist contents
replacement.innerHTML = original.innerHTML;
// Switch!
original.parentNode.replaceChild(replacement, original);
You have a comma after i = 0, <========
it should be semicolon.
Another issue is declaring l = original.attributes.length you don't need the variable l
just use it as for(i = 0; i < original.attributes.length; ++i){
if you still wanna use a forEach you can do it as:
original.attributes.forEach(element => {
var nodeName = element.nodeName;
var nodeValue = element.nodeValue;
replacement.setAttribute(nodeName, nodeValue);
});
thanks for your answer, i got Uncaught TypeError: original.attributes.forEach is not a function
function Switch() {
var original = document.getElementsByTagName("noscript")[0];
var replacement = document.createElement("span");
original.attributes.forEach(element => {
var nodeName = element.nodeName;
var nodeValue = element.nodeValue;
replacement.setAttribute(nodeName, nodeValue);
});
// Persist contents
replacement.innerHTML = original.innerHTML;
// Switch!
original.parentNode.replaceChild(replacement, original);
}

Is there a way to speed up this for loop in Google Script?

I have a for loop which is working on my google sheet but it takes around 5 minutes to filter through the 2100 rows of data. I have read about using filters and getting rid of the for loop all together but I'm fairly new to coding in Google Script and haven't been able to get my head around the syntax for this. Any advice greatly appreciated.
Code below:
function Inspect() {a
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("Inventory");
var tarSheet = sSheet.getSheetByName("Inspections");
var lastRow = srcSheet.getLastRow();
for (var i = 2; i <= lastRow; i++) {
var cell = srcSheet.getRange("A" + i);
var val = cell.getValue();
if (val == true) {
var srcRange = srcSheet.getRange("B" + i + ":I" + i);
var clrRange = srcSheet.getRange("A" + i);
var tarRow = tarSheet.getLastRow();
tarSheet.insertRowAfter(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow+1) + ":H" + (tarRow+1));
var now = new Date();
var timeRange = tarSheet.getRange("I"+(tarRow+1));
timeRange.setValue(now);
srcRange.copyTo(tarRange);
clrRange.clear();
//tarRange.activate();
timeRange.offset(0, 1).activate();
}
}
};
Yes, to speed-up you will need to get all the values first and apply your logic to the obtained 2D-arrays instead of cells, at the end you will use setValues to update your sheet. I would go for something like this:
function Inspect() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("Inventory");
var tarSheet = sSheet.getSheetByName("Inspections");
var srcLastRow = srcSheet.getLastRow();
var tarLastRow = tarSheet.getLastRow();
var srcArray = srcSheet.getRange(1,1,srcLastRow,9).getValues();//(A1:I(lastrow))
var tarArray = tarSheet.getRange(1,1,tarLastRow,9).getValues();//(A1:I(lastrow))
for (var i = 1; i < srcArray.length; i++) {
var val = srcArray[i][0];
if (val == true) {
var copyValues = srcArray[i].slice(1);//Get all elements from the row excluding first column (srcSheet.getRange("B" + i + ":I" + i);)
var now = new Date();
copyValues[8]=now;//set the time on column 9 (array starts at position 0!)
var tarNewLine = copyValues;
tarArray.push(tarNewLine);
//clear values on source (except column A):
for(var j=1;j<srcArray[i].length;j++){
srcArray[i][j]="";
}
}
}
tarSheet.clear();
tarSheet.getRange(1, 1,tarArray.length,tarArray[0].length).setValues(tarArray);
srcSheet.clear();
srcSheet.getRange(1, 1,srcArray.length,srcArray[0].length).setValues(srcArray);
};
You cannot get around a loop, but you should reduce the number of calls to the SpreadsheetApp to a minimum, see Apps Script Best Practices
It is not the for loop, but those calls that make your code slow. Instead, work with arrays as much as you can. Loops become of a problem if they are nested - this is also something you should avoid.
Sample how to perform most calls to SpreadsheetApp outside of the loop and work with arrays:
function Inspect() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("Inventory");
var tarSheet = sSheet.getSheetByName("Inspections");
var lastRow = srcSheet.getLastRow();
var Acolumn = srcSheet.getRange("A2:A" + lastRow);
var Avalues = Acolumn.getValues();
var srcRange = srcSheet.getRange("B2:I" + lastRow);
var srcValues = srcRange.getValues();
var array = [];
var now = new Date();
for (var i = 0; i < lastRow-1; i++) {
var val = Avalues[i][0];
if (val == true) {
srcValues[i].push(now);
array.push(srcValues[i]);
var clrRange = Acolumn.getCell(i+1, 1);
clrRange.clear();
}
}
var tarRow = tarSheet.getLastRow();
tarSheet.insertRowAfter(tarRow);
if(array.length!=0){
var tarRange = tarSheet.getRange("A" + (tarRow+1) + ":I" + (tarRow + array.length));
tarRange.setValues(array);
}
};

how to remove lines from amcharts map Dynamically

I want to remove Lines from amcharts maps dynamically. I can add lines dynamically but not able to remove it dynamically
var chart = am4core.create("chartdiv", am4maps.MapChart);
chart.geodata = am4geodata_worldLow;
chart.projection = new am4maps.projections.Miller();
var markerPoints = [];
// Create map polygon series
var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
polygonSeries.useGeodata = true;
polygonSeries.mapPolygons.template.fill = chart.colors.getIndex(0).lighten(0.5);
polygonSeries.mapPolygons.template.nonScalingStroke = true;
polygonSeries.exclude = ["AQ"];
var points = chart.series.push(new am4maps.MapImageSeries());
points.mapImages.template.nonScaling = true;
var marker = points.mapImages.template.createChild(am4core.Circle);
marker.radius = 1;
marker.fill = am4core.color("yellow");
marker.strokeWidth = 0;
marker.stroke = am4core.color("yellow");
marker.tooltipText = '{title}';
points.mapImages.template.propertyFields.latitude = "latitude";
points.mapImages.template.propertyFields.longitude = "longitude";
function addPoint(coords, title) { // this is function to add points on map
var marker = points.mapImages.create();
marker.latitude = coords.latitude;
marker.longitude = coords.longitude;
return marker;
}
var paris = addPoint({ "latitude": 48.8567, "longitude": 2.3510 }, "Paris");
var toronto = addPoint({ "latitude": 43.8163, "longitude": -79.4287 }, "Toronto");
var lineSeries = chart.series.push(new am4maps.MapArcSeries());
lineSeries.mapLines.template.line.strokeWidth = 2;
lineSeries.mapLines.template.line.strokeOpamarker = 0.5;
lineSeries.mapLines.template.line.stroke = marker.fill;
lineSeries.mapLines.template.line.nonScalingStroke = true;
lineSeries.mapLines.template.line.strokeDasharray = "1,5";
function addLine(from, to) {
var line = lineSeries.mapLines.create();
line.imagesToConnect = [from, to];
line.line.controlPointDistance = -0.3;
return line;
}
addLine(paris, toronto);
setInterval(function(){
addLine(somePoint,somePoint);
removeLine()//how to implement this one
},1000);
I want to implement a function or line of code that remove those lines which has already drawn inside setInterval ..
for bullets var bulletAttack = bullet.createChild(am4core.Sprite); I use:
bullet.hide();
bullet.kill();
maybe it will help you.
try below command before adding new line and it will fix your issue.
lineSeries.mapLines.removeIndex(0)

Enhancing Performance in Student Info App

I've built a simple Student Information platform using Google Sheets. It allows the user to query, update and create new student info on a user interface. Please refer to this sheet to see how it works.
The functions to Refresh/Update/Save are inside the Actions button on a menu bar. Everything seems to work well however when the number of records increases, say above 100 records, all the functions slow down and it gets extremely slow with 200+ records.
Appreciate if anyone could help to take a look at the scripts as I suspect they need to be optimized.
Many thanks in advance!
function UpdateDataIntoMaster() { //This script is used in the SAVE button in UPDATE sheet)
/*Get data from UPDATE Sheet*/
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY");
var sheet = ss.getSheetByName('UPDATE');
var range = sheet.getRange("D30:AE30"); //All data transposed into this line. MUST be updated if more fields are added into the Data sheet
var values = range.getValues();
var rangeForKey = sheet.getRange("D30") //Student Name is used as the
key identifier
var keyValue = rangeForKey.getValue();
/*Pass in keyValue(identifier = Student Name)
and all data in the function below in order
to update master data sheet*/
updDbase(keyValue,values);
function updDbase(keyValue,values) {
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY")
var sheet = ss.getSheetByName('Data');
var data = sheet.getDataRange().getValues();
var noOfRow = values.length
var noOfCol = values[0].length
for (var i=0; i < data.length; i++) { // going through all the rows in Data sheet
var keyData = ss.getSheetByName("Data").getRange(i+1,1).getValue(); //Get the Student Name from Data sheet
if (keyData == keyValue) {
// for (var j=0; j < data[i].length; j++) { // this is going through all the cell of a row
var row = Number(i)+1;
var sh = SpreadsheetApp.getUi();
var response = sh.alert("Update Information","Are you sure you want to update the student information?", sh.ButtonSet.YES_NO);
if (response == sh.Button.YES)
{
var sheets = ss.getSheetByName("Data").getRange(row,1,noOfRow,noOfCol).setValues(values);
}//If response == YES
}
}
}
}
function CreateNew() {
/*Get data from Inquiry Sheet*/
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY");
var sheetNew = ss.getSheetByName('Create New');
var range = sheetNew.getRange("D30:AZE30"); //All data transposed into
this line
var values = range.getValues();
var rangeForKey = sheetNew.getRange("E30") //Using Student ID as key identifier
var keyValue = rangeForKey.getValue();
var noOfRow = values.length
var noOfCol = values[0].length
var sheetData = ss.getSheetByName('Data');
var lastRow = sheetData.getLastRow();
var data = sheetData.getDataRange().getValues();
for (var i=0; i < data.length; i++) { // going through all the rows in Data sheet
var keyData = sheetData.getRange(i+1,2).getValue(); //Get the Student ID from Data sheet
if (keyData == keyValue) {
AlertBox();//If Student ID is found, to prompt Student ID already
exist
return;
} //If
} //For
/*Confirming with user whether to proceed to create new entry*/
var sh = SpreadsheetApp.getUi();
var response = sh.alert("Create New Record","Are you sure you want to
create new student information?", sh.ButtonSet.YES_NO);
if (response == sh.Button.YES){
if (keyValue == ""){
var response = sh.alert("Create New Record","Unable to proceed
because Student ID is empty", sh.ButtonSet.OK);
return;}
else {
//var response = sh.alert("Create New Record","Unable to
proceed because Student ID is empty", sh.ButtonSet.OK);
var sheets =
sheetData.getRange(lastRow+1,1,1,noOfCol).setValues(values)
}
}//If
}
function EditStudentInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Inquiry");
//var ss = SpreadsheetApp.getActive();
var protections = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var protection = protections[i];
if (protection.canEdit()) {
protection.remove();
}
}
}
function EditContent() {
var s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Update");
var rangeContentCol1 = s.getRange("E3:E23");
var CopyContentCol1 = s.getRange("E3:E23").getValues();
var rangeContentCol2 = s.getRange("I3:I23");
var CopyContentCol2 = s.getRange("I3:I23").getValues();
rangeContentCol1.clearContent();
rangeContentCol2.clearContent();
var PasteContentCol1 =
s.getRange("E3:E23").setValues(CopyContentCol1);
var PasteContentCol2 = s.getRange("I3:I23").setValues(CopyContentCol2);
}
A common performance mistake people with Apps Script is doing the .getRange().getValues() within their for loops. Performance-wise these get and set calls are quite expensive.
Lucky the fix for this is quite easy - get all the data at once first, then loops through it. You actually do this already, sort of. In your script you get the whole data range, but then only use a part of the data and instead do another getValues call. I've updated the two areas in your script that had getRange() calls in a for loop --> var keyData = data[i][0];
function UpdateDataIntoMaster() { //This script is used in the SAVE button in UPDATE sheet)
/*Get data from UPDATE Sheet*/
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY");
var sheet = ss.getSheetByName('UPDATE');
var range = sheet.getRange("D30:AE30"); //All data transposed into this line. MUST be updated if more fields are added into the Data sheet
var values = range.getValues();
var rangeForKey = sheet.getRange("D30") //Student Name is used as the
key identifier
var keyValue = rangeForKey.getValue();
/*Pass in keyValue(identifier = Student Name)
and all data in the function below in order
to update master data sheet*/
updDbase(keyValue,values);
function updDbase(keyValue,values) {
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY")
var sheet = ss.getSheetByName('Data');
var data = sheet.getDataRange().getValues();
var noOfRow = values.length
var noOfCol = values[0].length
for (var i=0; i < data.length; i++) { // going through all the rows in Data sheet
var keyData = data[i][0]; //Use the data that is already loaded.
if (keyData == keyValue) {
// for (var j=0; j < data[i].length; j++) { // this is going through all the cell of a row
var row = Number(i)+1;
var sh = SpreadsheetApp.getUi();
var response = sh.alert("Update Information","Are you sure you want to update the student information?", sh.ButtonSet.YES_NO);
if (response == sh.Button.YES)
{
var sheets = ss.getSheetByName("Data").getRange(row,1,noOfRow,noOfCol).setValues(values);
}//If response == YES
}
}
}
}
function CreateNew() {
/*Get data from Inquiry Sheet*/
var ss = SpreadsheetApp.openById("11Djp9UmXbtWv7VitZFfo0X4Ctet3O8Amh4xADNKOZgY");
var sheetNew = ss.getSheetByName('Create New');
var range = sheetNew.getRange("D30:AZE30"); //All data transposed into
this line
var values = range.getValues();
var rangeForKey = sheetNew.getRange("E30") //Using Student ID as key identifier
var keyValue = rangeForKey.getValue();
var noOfRow = values.length
var noOfCol = values[0].length
var sheetData = ss.getSheetByName('Data');
var lastRow = sheetData.getLastRow();
var data = sheetData.getDataRange().getValues();
for (var i=0; i < data.length; i++) { // going through all the rows in Data sheet
var keyData = data[i][0]; //Use the data that is already loaded.
if (keyData == keyValue) {
AlertBox();//If Student ID is found, to prompt Student ID already
exist
return;
} //If
} //For
/*Confirming with user whether to proceed to create new entry*/
var sh = SpreadsheetApp.getUi();
var response = sh.alert("Create New Record","Are you sure you want to
create new student information?", sh.ButtonSet.YES_NO);
if (response == sh.Button.YES){
if (keyValue == ""){
var response = sh.alert("Create New Record","Unable to proceed
because Student ID is empty", sh.ButtonSet.OK);
return;}
else {
//var response = sh.alert("Create New Record","Unable to
proceed because Student ID is empty", sh.ButtonSet.OK);
var sheets =
sheetData.getRange(lastRow+1,1,1,noOfCol).setValues(values)
}
}//If
}
function EditStudentInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Inquiry");
//var ss = SpreadsheetApp.getActive();
var protections = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var protection = protections[i];
if (protection.canEdit()) {
protection.remove();
}
}
}
function EditContent() {
var s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Update");
var rangeContentCol1 = s.getRange("E3:E23");
var CopyContentCol1 = s.getRange("E3:E23").getValues();
var rangeContentCol2 = s.getRange("I3:I23");
var CopyContentCol2 = s.getRange("I3:I23").getValues();
rangeContentCol1.clearContent();
rangeContentCol2.clearContent();
var PasteContentCol1 =
s.getRange("E3:E23").setValues(CopyContentCol1);
var PasteContentCol2 = s.getRange("I3:I23").setValues(CopyContentCol2);
}
Give this a test and let me know if it helps!

How do I fix charset problems in .gs script?

I have a problem with charsets.
I parsed a csv file in google-app-engine and I'm posting to an uiapp table.
But I checked special characters like áéíóú and those are not well displayed (?square symbol).
When I was setting up my code I played writing the string imported to a google docs document and it worked the same.
some advice please?
I search for:
a global charset definition to the code. or
string var transformation that makes the chars appear like I want to. (avoiding html &number definitions.
Is this related to the blob object?
The thing is important i come from spain and we need such characters.
app that get's a csv ';' delimited file and shows it's content
I post all my code, it's barely as the tutorial that is given.
function arreglaUrl(cadena){
var texto = cadena[cadena.length - 2]
if (texto == ''){
cadena[cadena.length - 2] = 'Sin enlace';
}
else{
cadena[cadena.length - 2] = '<center>Link.</center>' ;
};
}
function parsedCSV(){
var listaArchivos = DocsList.getFolderById('XXXXX').getFiles()
for (var i = 0; i < listaArchivos.length; i++) {
if (listaArchivos[i].getName() == 'baul.csv'){
var origen = listaArchivos[i];
};
}
var texto = origen.getContentAsString();
var arra = Utilities.parseCsv(texto,";");
return(arra);
}
function doGet() {
var datos = parsedCSV()
var baul = Charts.newDataTable()
for (i = 0; i < datos[0].length; i++){
baul.addColumn(Charts.ColumnType.STRING, datos[0][i])
}
for (i = 1; i < datos.length; i++){
arreglaUrl(datos[i]) // this only makes some html i need to post some links
baul.addRow(datos[i])
}
baul.build();
var sectorFilter = Charts.newCategoryFilter()
.setFilterColumnLabel("sector")
.build();
var tipoFilter = Charts.newCategoryFilter()
.setFilterColumnLabel("tipo")
.build();
var searchFilter = Charts.newStringFilter()
.setFilterColumnLabel("Titulo")
.build();
var searchDesc = Charts.newStringFilter()
.setFilterColumnLabel("descripcion")
.build();
var tableChart = Charts.newTableChart().setOption('allowHtml', true).setDimensions(0,0)
.build();
var dashboard = Charts.newDashboardPanel()
.setDataTable(baul)
.bind([sectorFilter, tipoFilter, searchFilter, searchDesc], [tableChart])
.build();
var uiApp = UiApp.createApplication().setTitle('Baul de Recursos');
var anchoTotal = '100%';
dashboard.add(uiApp.createVerticalPanel()
.add(uiApp.createHorizontalPanel()
.add(sectorFilter)
.add(tipoFilter)
.setSpacing(15)
)
.add(uiApp.createHorizontalPanel()
.add(searchFilter)
.add(searchDesc)
.setSpacing(15)
)
.add(uiApp.createHorizontalPanel()
.add(tableChart).setBorderWidth(1).setHorizontalAlignment(UiApp.HorizontalAlignment.CENTER).setWidth(anchoTotal)
)
);
uiApp.add(dashboard);
return uiApp;
}
I found it, we need to get the content of the file first with a Blob object.
This function is the one I use to parse some csv info into an array:
function parsedCSV(){
//searching the file. This gets only one file in var origen
var listaArchivos = DocsList.getFolderById('XXXXXXX').getFiles()
for (var i = 0; i < listaArchivos.length; i++) {
if (listaArchivos[i].getName() == 'baul.csv'){
var origen = listaArchivos[i];
};
}
// HERE IS THE GOOD DEFINITION OF CHAR:
var texto2= origen.getBlob().getDataAsString('ISO-8859-1');
// I put all the corrected text in an array
var arra = Utilities.parseCsv(texto2,";");
return(arra);
}
This is the solved thing: https://script.google.com/macros/s/AKfycbyHa-bLWBHBr3qifbvzxecqGgGUYX8mhyo-TKoyfGvy/exec
The trick:
var textVariableName = fileObjectVariableName.getBlob().getDataAsString('ISO-8859-1');

Resources