问:
writing multiple lines back to a file, wrong file length
I want to get the a multiline text file's content, and put it back to the file.

However, I have an issue with the file length.
The null terminator (0) that I add is after some strange characters.

Something wrong with my f_length ?

Edit : If I set the line-endings of my file to Unix (LF), I don't have the issue. So it seems that my code is incompatible with Windows line endings. How can I account for Windows text files ?

```<code>int main()
{
    FILE *fp = NULL;
    int f_length;
    char *buffer = NULL;
    size_t size = 0;

    fp = fopen(FILENAME, "r+");
    fseek(fp, 0, SEEK_END);
    f_length = ftell(fp);
    rewind(fp);

    buffer = malloc((f_length + 1) * sizeof(*buffer));
    fread(buffer, f_length, 1, fp);
    buffer[f_length] = 0;
    printf("%s\n", buffer);

    fp = fopen(FILENAME, "w+");
    fputs(buffer, fp);
    fclose(fp);

    return 0;
}
</code>```

答:
Use fp = fopen(FILENAME, "rb+"); instead. For text files, you'll have newline characters replaced while reading (you've already noticed that in comments). In some cases, new format is shorter ("\r" or "\n" while the file itself contains "\r\n"), so f_length will be bigger than the actual data read.

Or you can use line-by-line reading functions, they are made for text-mode files.

Body:
I want to get the a multiline text file's content, and put it back to the file.

However, I have an issue with the file length.
The null terminator (0) that I add is after some strange characters.

Something wrong with my f_length ?

Edit : If I set the line-endings of my file to Unix (LF), I don't have the issue. So it seems that my code is incompatible with Windows line endings. How can I account for Windows text files ?

int main()
{
    FILE *fp = NULL;
    int f_length;
    char *buffer = NULL;
    size_t size = 0;

    fp = fopen(FILENAME, "r+");
    fseek(fp, 0, SEEK_END);
    f_length = ftell(fp);
    rewind(fp);

    buffer = malloc((f_length + 1) * sizeof(*buffer));
    fread(buffer, f_length, 1, fp);
    buffer[f_length] = 0;
    printf("%s\n", buffer);

    fp = fopen(FILENAME, "w+");
    fputs(buffer, fp);
    fclose(fp);

    return 0;
}


来源: stackexchange

问:
Recognize a number from an image
I'm trying to write an application to find the numbers inside an image and add them up.

How can I identify the written number in an image?

There are many boxes in the image I need to get the numbers in the left side and sum them to give total. How can I achieve this?

Edit: i did a java tesseract ocr on the image but i didnt get any correct results. how can i train it?

also

i did a edge detection i got this:

答:
Here's a simple approach:

Obtain binary image. Load the image, convert to grayscale, then Otsu's threshold to get a 1-channel binary image with pixels ranging from [0...255].

Detect horizontal and vertical lines. Create horizontal and vertical structuring elements then draw lines onto a mask by performing morphological operations.

Remove horizontal and vertical lines. Combine horizontal and vertical masks using a bitwise_or operation then remove the lines using a bitwise_and operation.

Perform OCR. Apply a slight Gaussian blur then OCR using Pytesseract.

Here's a visualization of each step:

Input image -> Binary image -> Horizontal mask -> Vertical mask

Combined masks -> Result -> Applied slight blur

Result from OCR

```<code>38
18
78
</code>```

I implemented it with Python but you can adapt a similar approach using Java

```<code>import cv2
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Detect horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1))
horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=1)

# Detect vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,25))
vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=1)

# Remove horizontal and vertical lines
lines = cv2.bitwise_or(horizontal, vertical)
result = cv2.bitwise_not(image, image, mask=lines)

# Perform OCR with Pytesseract
result = cv2.GaussianBlur(result, (3,3), 0)
data = pytesseract.image_to_string(result, lang='eng', config='--psm 6')
print(data)

# Display
cv2.imshow('thresh', thresh)
cv2.imshow('horizontal', horizontal)
cv2.imshow('vertical', vertical)
cv2.imshow('lines', lines)
cv2.imshow('result', result)
cv2.waitKey()
</code>```

ContentLicense: CC BY-SA 3.0

Title: Recognize a number from an image

Body:
Here's a simple approach:

Obtain binary image. Load the image, convert to grayscale, then Otsu's threshold to get a 1-channel binary image with pixels ranging from [0...255].

Detect horizontal and vertical lines. Create horizontal and vertical structuring elements then draw lines onto a mask by performing morphological operations.

Remove horizontal and vertical lines. Combine horizontal and vertical masks using a bitwise_or operation then remove the lines using a bitwise_and operation.

Perform OCR. Apply a slight Gaussian blur then OCR using Pytesseract.

Here's a visualization of each step:

Input image -> Binary image -> Horizontal mask -> Vertical mask

Combined masks -> Result -> Applied slight blur

Result from OCR

38
18
78

I implemented it with Python but you can adapt a similar approach using Java

import cv2
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Detect horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1))
horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=1)

# Detect vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,25))
vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=1)

# Remove horizontal and vertical lines
lines = cv2.bitwise_or(horizontal, vertical)
result = cv2.bitwise_not(image, image, mask=lines)

# Perform OCR with Pytesseract
result = cv2.GaussianBlur(result, (3,3), 0)
data = pytesseract.image_to_string(result, lang='eng', config='--psm 6')
print(data)

# Display
cv2.imshow('thresh', thresh)
cv2.imshow('horizontal', horizontal)
cv2.imshow('vertical', vertical)
cv2.imshow('lines', lines)
cv2.imshow('result', result)
cv2.waitKey()

ContentLicense: CC BY-SA 4.0


问:
Why this code is working only with button type attribute?
I have code where on click i am putting value in the input on the form.

This code here works fine.Will put value in the input.

```<code>
    <form>
        <label for="fname">First name:</label><br>
        <input id="fname" type="text" id="fname"><br>
        <button id="btn" type="button">Submit</button>
    </form>

var inputs = document.getElementsByTagName("input");
var submitButton = document.getElementById("btn");

submitButton.addEventListener("click"  , function() {
    inputs[0].value = "fill in value in the input";
})

</code>```

But my questions is why if i use

```<code><button id="btn">Submit</button>
OR
 <input id="btn" type="submit" value="Submit">
instead of
<button id="btn" type="button">Submit</button>
like in the first example

</code>```

THEN the input will be not filled with the desired value from the JS.
When i click the button for one milisecond the input gets the value and then disappear.

答:
You add the click EventListener for the element with ID btn. <input type="submit" value="Submit"> does not have ID btn, and the eventListener is not applied to it. <input id="btn" ...> should work.

For <button id="btn">Submit</button>, it defaults to type="submit", so the page is reloaded when you click it. You could use e.preventDefault() in the click handler to stop that if you wanted.

Body:
I have code where on click i am putting value in the input on the form.

This code here works fine.Will put value in the input.

    <form>
        First name:

        <input id="fname" type="text" id="fname">

        <button id="btn" type="button">Submit</button>
    </form>

var inputs = document.getElementsByTagName("input");
var submitButton = document.getElementById("btn");

submitButton.addEventListener("click"  , function() {
    inputs[0].value = "fill in value in the input";
})

But my questions is why if i use

<button id="btn">Submit</button>
OR
 <input id="btn" type="submit" value="Submit">
instead of
<button id="btn" type="button">Submit</button>
like in the first example

THEN the input will be not filled with the desired value from the JS.
When i click the button for one milisecond the input gets the value and then disappear.


问:
Download Large File with PHP readfile(); Downloading is stopping around 890mb
I write some small script and it is working ok! however when i try download large file such a more than 1GB Download is stopping around ~880MB

Am i doing something wrong?  or is there any better solution for download big file with PHP

This is my code

```<code><?php

set_time_limit(0);
ini_set('memory_limit', '5000M');

//This File is 4GB size
$url = 'example.com/files/file_name.zip';

$headers = get_headers($url, TRUE); //collectind header information from file Url

$filesize = $headers['Content-Length']; //File size

while (ob_get_level()) ob_end_clean();
header('Content-Type: application/zip');
header('Content-Disposition: filename=' . basename($url));
header('Content-length: ' . $filesize);
header('Cache-Control: no-cache');
header("Content-Transfer-Encoding: chunked");
ob_flush();
flush();
readfile($url);
exit;

</code>```

答:
I suspect that you're hitting a memory limit error. Normally readfile avoids using much memory, but depending on your settings it can consume RAM in the process. Check your error logs to confirm that you're seeing a memory allocation error, and if you are seeing it, try getting rid of the while and ob_flush and flush and just add something like this after the headers:

```<code>if (ob_get_level()) {
    ob_end_clean();
}

readfile($url);
</code>```

Also, don't pump your memory limit up to 5GB... if this is working correctly you shouldn't require hardly any memory.

If that's not it, can you confirm that you're serving a remotely hosted ZIP file (i.e. you don't have direct access to the ZIP file on the current server)?

Body:
I write some small script and it is working ok! however when i try download large file such a more than 1GB Download is stopping around ~880MB

Am i doing something wrong?  or is there any better solution for download big file with PHP

This is my code

<?php

set_time_limit(0);
ini_set('memory_limit', '5000M');

//This File is 4GB size
$url = 'example.com/files/file_name.zip';

$headers = get_headers($url, TRUE); //collectind header information from file Url

$filesize = $headers['Content-Length']; //File size

while (ob_get_level()) ob_end_clean();
header('Content-Type: application/zip');
header('Content-Disposition: filename=' . basename($url));
header('Content-length: ' . $filesize);
header('Cache-Control: no-cache');
header("Content-Transfer-Encoding: chunked");
ob_flush();
flush();
readfile($url);
exit;

Body:
I suspect that you're hitting a memory limit error. Normally readfile avoids using much memory, but depending on your settings it can consume RAM in the process. Check your error logs to confirm that you're seeing a memory allocation error, and if you are seeing it, try getting rid of the while and ob_flush and flush and just add something like this after the headers:

if (ob_get_level()) {
    ob_end_clean();
}

readfile($url);

Also, don't pump your memory limit up to 5GB... if this is working correctly you shouldn't require hardly any memory.

If that's not it, can you confirm that you're serving a remotely hosted ZIP file (i.e. you don't have direct access to the ZIP file on the current server)?


问:
How display images from Google Drive on Gsheet cell?
I would like to display easily an image on Gsheet cell based from URL of image stored in Gdrive.

I have tried with the Gsheet function =IMAGE("URL") and it does not work.

The objective is to display an image picture as the example below
(example of picture in 5th row was done manually)

答:
You want to put the image in your Google Drive to your Google Spreadsheet.

You want to achieve this using Google Apps Script.

If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.

Pattern 1:

In this pattern, the image is put using =IMAGE("URL").

When =IMAGE("URL") is used, the image is required to publicly shared. So please share the images with publicly shared as On - Anyone with the link.

And also, please modify the endpoint as follows.

From:

```<code>https://drive.google.com/open?id=###
</code>```

to:

```<code>https://drive.google.com/uc?export=download&id=###
</code>```

In this case, you can put the image with =IMAGE("https://drive.google.com/uc?export=download&id=###") after the image is shared publicly.

Pattern 2:

If you don't want to share publicly the images, how about this pattern? In this pattern, the image is put as the blob without sharing publicly.

Here, please check the following sample script.

Sample script:

```<code>var fileId = "###";  // Please set the file ID of the image.

var sheet = SpreadsheetApp.getActiveSheet();
var blobSource = DriveApp.getFileById(fileId).getBlob();
var image = sheet.insertImage(blobSource, 1, 1);
image.setWidth(100).setHeight(100);
sheet.setColumnWidth(1, 100).setRowHeight(1, 100);
</code>```

When you run the script, the image is put to the cell "A1". And the image size is resized to 100 x 100 pixels. And then, the row and column size is changed for the image size.

This is a simple sample script. So please modify this for your actual situation.

References:

insertImage()

Class OverGridImage

setColumnWidth()

setRowHeight()

If I misunderstood your question and this was not the direction you want, I apologize.

Added:

From your replying, it was found that the image size is over than the limitation size (1,048,576 pixels^2) Ref The reason of your current is is this.

In this case, in order to put the image, it is required to resize the image. The following sample script puts the image by resizing image size. For this, I used a Google Apps Script library. So please install it to the script editor.

Sample script:

```<code>var fileId = "###";  // Please set the file ID of the image.

var sheet = SpreadsheetApp.getActiveSheet();
var blobSource = DriveApp.getFileById(fileId).getBlob();
var obj = ImgApp.getSize(blobSource);
var height = obj.height;
var width = obj.width;
if (height * width > 1048576) {
  var r = ImgApp.doResize(fileId, 512);
  blobSource = r.blob;
}
var image = sheet.insertImage(blobSource, 1, 1);
image.setWidth(100).setHeight(100);
sheet.setColumnWidth(1, 100).setRowHeight(1, 100);
</code>```

In this sample script, when the image size is over than 1,048,576 pixels^2, the image is resized and put to the Spreadsheet.

This is a simple sample script. So please modify it for your actual situation.

References:

Limitations for Inserting Images to Google Docs

ImgApp

Body:
You want to put the image in your Google Drive to your Google Spreadsheet.

You want to achieve this using Google Apps Script.

If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.

Pattern 1:

In this pattern, the image is put using =IMAGE("URL").

When =IMAGE("URL") is used, the image is required to publicly shared. So please share the images with publicly shared as On - Anyone with the link.

And also, please modify the endpoint as follows.

From:

https://drive.google.com/open?id=###

to:

https://drive.google.com/uc?export=download&id=###

In this case, you can put the image with =IMAGE("https://drive.google.com/uc?export=download&id=###") after the image is shared publicly.

Pattern 2:

If you don't want to share publicly the images, how about this pattern? In this pattern, the image is put as the blob without sharing publicly.

Here, please check the following sample script.

Sample script:

var fileId = "###";  // Please set the file ID of the image.

var sheet = SpreadsheetApp.getActiveSheet();
var blobSource = DriveApp.getFileById(fileId).getBlob();
var image = sheet.insertImage(blobSource, 1, 1);
image.setWidth(100).setHeight(100);
sheet.setColumnWidth(1, 100).setRowHeight(1, 100);

When you run the script, the image is put to the cell "A1". And the image size is resized to 100 x 100 pixels. And then, the row and column size is changed for the image size.

This is a simple sample script. So please modify this for your actual situation.

References:

insertImage()

Class OverGridImage

setColumnWidth()

setRowHeight()

If I misunderstood your question and this was not the direction you want, I apologize.

Added:

From your replying, it was found that the image size is over than the limitation size (1,048,576 pixels^2) Ref The reason of your current is is this.

In this case, in order to put the image, it is required to resize the image. The following sample script puts the image by resizing image size. For this, I used a Google Apps Script library. So please install it to the script editor.

Sample script:

var fileId = "###";  // Please set the file ID of the image.

var sheet = SpreadsheetApp.getActiveSheet();
var blobSource = DriveApp.getFileById(fileId).getBlob();
var obj = ImgApp.getSize(blobSource);
var height = obj.height;
var width = obj.width;
if (height * width > 1048576) {
  var r = ImgApp.doResize(fileId, 512);
  blobSource = r.blob;
}
var image = sheet.insertImage(blobSource, 1, 1);
image.setWidth(100).setHeight(100);
sheet.setColumnWidth(1, 100).setRowHeight(1, 100);

In this sample script, when the image size is over than 1,048,576 pixels^2, the image is resized and put to the Spreadsheet.

This is a simple sample script. So please modify it for your actual situation.

References:

Limitations for Inserting Images to Google Docs

ImgApp


问:
jQuery event after a PDF loads?
I have a modal dialog that allows users to generate a customized PDF. After they click a "Start" button, the page redirects with window.location to a controller, which then creates the PDF and returns it.

Because of how long it takes the PDF to return, I want to display a modal "Generating PDF" dialog that automatically closes once the PDF is complete and is returned.

The problem is I can't figure out how/when to execute that final function to close the "Generating PDF" dialog. Since the controller returns an application/pdf type, there is no document object event to attach to, right? What is the best way to do this?

答: redirect to a controller, that creates your pdf and saves it. the controller should return after saving the pdf a js that closes the modal and redirects to another control, that only reads and response the pdf file.

Title: jQuery event after a PDF loads?


问:
How to understand the usage of rep() in this case?
There's a dataset randomdat contains 299 obs, two categorical variables, var 9 contains the values like With XYZ and Without XYZ, var8 contains values like Group A/ Group B/Group C, var1 is a numerical variable.

Then there's a model:

m7 <- lm(var3~var1+I(var1^2)+I(var1^3)+var9, data=randomdat)

Check summary(m7), it shows Without XYZ is always 34451.4 less than With XYZ.

```<code>> summary(m7)

Call:
lm(formula = var3 ~ var1 + I(var1^2) + I(var1^3) + var9, data = randomdat)

Residuals:
    Min      1Q  Median      3Q     Max
-391506  -75127    4799   77175  323856

Coefficients:
                     Estimate    Std. Error t value            Pr(>|t|)
(Intercept)     -162934.42035   18571.30251  -8.773 <0.0000000000000002 ***
var1              10927.87454     741.36511  14.740 <0.0000000000000002 ***
I(var1^2)          -180.82979      10.44006 -17.321 <0.0000000000000002 ***
I(var1^3)             0.99499       0.04223  23.562 <0.0000000000000002 ***
var9Without XYZ  -34451.43378   14570.55030  -2.364              0.0187 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 117500 on 294 degrees of freedom
Multiple R-squared:  0.8642,    Adjusted R-squared:  0.8624
F-statistic: 467.9 on 4 and 294 DF,  p-value: < 0.00000000000000022
</code>```

Then there're two predict models:

```<code>m7_predictwith <- predict(m7,list(var1=randomdat$var1, var9 = rep("With XYZ",299)))
m7_predictwout <- predict(m7,list(var1=randomdat$var1, var9 = rep("Without XYZ",299)))
</code>```

If you plot them, you will see the the two lines are not overlapping.

```<code>ggplot(randomdat, aes(x = var1, y = var3)) +
    geom_point(aes(colour = var8, shape = var8)) +
    geom_line(aes(x=randomdat$var1,y=m7_predictwith), color = 'red', lty = 2) +
    geom_line(aes(x=randomdat$var1,y=m7_predictwout), color = 'black', lty = 3)
</code>```

Now it comes with the question, how to understand var9 = rep("With XYZ",299) or var9 = rep("Without XYZ",299) in this case? Aren't them mean replace all the values in var9 to With XYZ or Without XYZ? The var1 is the same in m7_predictwith and m7_predictwout, the plot lines of them should be just one same line? Very confused about the syntax usage of rep() in this case.

答:
rep() repeats values:

> rep("With XYZ", 5)
[1] "With XYZ" "With XYZ" "With XYZ" "With XYZ" "With XYZ"
```

Here it's being used to created data sets that contain:

The observed values of var1

A fixed value of var9.

var9 is a factor variable, and in the regression its estimated coefficient is -34451.43378. So if you predict one line with a fixed value for var9 of "With XYZ", and then another line with a fixed value of "Without XYZ", the "Without XYZ" line will be shifted down by a constant value of 34451, creating parallel lines.

Body:
There's a dataset randomdat contains 299 obs, two categorical variables, var 9 contains the values like With XYZ and Without XYZ, var8 contains values like Group A/ Group B/Group C, var1 is a numerical variable.

Then there's a model:

m7 <- lm(var3~var1+I(var1^2)+I(var1^3)+var9, data=randomdat)

Check summary(m7), it shows Without XYZ is always 34451.4 less than With XYZ.

> summary(m7)

Call:
lm(formula = var3 ~ var1 + I(var1^2) + I(var1^3) + var9, data = randomdat)

Residuals:
    Min      1Q  Median      3Q     Max
-391506  -75127    4799   77175  323856

Coefficients:
                     Estimate    Std. Error t value            Pr(>|t|)
(Intercept)     -162934.42035   18571.30251  -8.773 <0.0000000000000002 ***
var1              10927.87454     741.36511  14.740 <0.0000000000000002 ***
I(var1^2)          -180.82979      10.44006 -17.321 <0.0000000000000002 ***
I(var1^3)             0.99499       0.04223  23.562 <0.0000000000000002 ***
var9Without XYZ  -34451.43378   14570.55030  -2.364              0.0187 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 117500 on 294 degrees of freedom
Multiple R-squared:  0.8642,    Adjusted R-squared:  0.8624
F-statistic: 467.9 on 4 and 294 DF,  p-value: < 0.00000000000000022

Then there're two predict models:

m7_predictwith <- predict(m7,list(var1=randomdat$var1, var9 = rep("With XYZ",299)))
m7_predictwout <- predict(m7,list(var1=randomdat$var1, var9 = rep("Without XYZ",299)))

If you plot them, you will see the the two lines are not overlapping.

ggplot(randomdat, aes(x = var1, y = var3)) +
    geom_point(aes(colour = var8, shape = var8)) +
    geom_line(aes(x=randomdat$var1,y=m7_predictwith), color = 'red', lty = 2) +
    geom_line(aes(x=randomdat$var1,y=m7_predictwout), color = 'black', lty = 3)

Now it comes with the question, how to understand var9 = rep("With XYZ",299) or var9 = rep("Without XYZ",299) in this case? Aren't them mean replace all the values in var9 to With XYZ or Without XYZ? The var1 is the same in m7_predictwith and m7_predictwout, the plot lines of them should be just one same line? Very confused about the syntax usage of rep() in this case.

Body:
rep() repeats values:

> rep("With XYZ", 5)
[1] "With XYZ" "With XYZ" "With XYZ" "With XYZ" "With XYZ"

Here it's being used to created data sets that contain:

The observed values of var1

A fixed value of var9.

var9 is a factor variable, and in the regression its estimated coefficient is -34451.43378. So if you predict one line with a fixed value for var9 of "With XYZ", and then another line with a fixed value of "Without XYZ", the "Without XYZ" line will be shifted down by a constant value of 34451, creating parallel lines.


问:
How to get a date range prompt using a SQL connection in Excel
So I have created a connection in MS Query and am now using it in Excel. I want to create a macro button that when I click it the query automatically runs.

However when it runs I want you to be allowed to select the input for some fields. For example the two date fields and the entry field here:

```<code>WHERE
    (ENTERED_ON BETWEEN {ts '2020-02-01 00:00:00'} AND {ts '2020-02-14 00:00:00'})
    AND (ENTRY = 'apple')
</code>```

Any help would be greatly appreciated. Also just to note the date and time has to be specifically in that format. I also want to keep the prompt as simple as possible for users so ideally with something like:

```<code>Dim sUserInput As String
sUserInput = InputBox("Enter Number:", "Collect User Input")
</code>```

答:
Instead of an input prompt, I use a cell range to refer to my date range (which is much easier to format in the way you want it) and VBA coding that updates the command text of the SQL query within the excel workbook. So something like this:

```<code>Sql = Sql & " .... SELECT... FROM... " & vbCrLf 'enter your FROM and SELECT statements
Sql = Sql & "WHERE " & vbCrLf
Sql = Sql & "ENTERED_ON BETWEEN '" & Range("A1") & "' AND '" & Range("A2") & "' " & vbCrLf
Sql = Sql & "AND (ENTRY = 'apple')"

With ThisWorkbook.Connections("Your Connection Name Here").ODBCConnection
    .CommandText = Sql
    .Refresh
End With
</code>```

You can then attach the command to a macro button which will update your command text string with your date ranges. For bigger queries, I would suggest using a SQL to VBA string online convert like here: http://www.dpriver.com/pp/sqlformat.htm

Saves alot of time!

Body:
So I have created a connection in MS Query and am now using it in Excel. I want to create a macro button that when I click it the query automatically runs.

However when it runs I want you to be allowed to select the input for some fields. For example the two date fields and the entry field here:

WHERE
    (ENTERED_ON BETWEEN {ts '2020-02-01 00:00:00'} AND {ts '2020-02-14 00:00:00'})
    AND (ENTRY = 'apple')

Any help would be greatly appreciated. Also just to note the date and time has to be specifically in that format. I also want to keep the prompt as simple as possible for users so ideally with something like:

Dim sUserInput As String
sUserInput = InputBox("Enter Number:", "Collect User Input")

Body:
Instead of an input prompt, I use a cell range to refer to my date range (which is much easier to format in the way you want it) and VBA coding that updates the command text of the SQL query within the excel workbook. So something like this:

Sql = Sql & " .... SELECT... FROM... " & vbCrLf 'enter your FROM and SELECT statements
Sql = Sql & "WHERE " & vbCrLf
Sql = Sql & "ENTERED_ON BETWEEN '" & Range("A1") & "' AND '" & Range("A2") & "' " & vbCrLf
Sql = Sql & "AND (ENTRY = 'apple')"

With ThisWorkbook.Connections("Your Connection Name Here").ODBCConnection
    .CommandText = Sql
    .Refresh
End With

You can then attach the command to a macro button which will update your command text string with your date ranges. For bigger queries, I would suggest using a SQL to VBA string online convert like here: http://www.dpriver.com/pp/sqlformat.htm

Saves alot of time!


问:
IBM Domino - delete shared view & convert NSF application to NTF (template)
I have a very simple IBM Domino database with an XPages Java application and nothing else inside, I want to export it  as a template (ntf) instead of a database. If I just rename the nsf file with ntf extension, I can see the template in the application list when trying to create a new application, but it's icon is still a database icon and not the green template one. I tried searching online and looking through designer/admin options but found nothing that would help me.

Another question is, in the nsf I have one blank view and it's being displayed every time I open the application, I want to get rid of this view but I'm getting an error that I cannot delete the last shared view. It's annoying me because when opening the application for the first time it's being shown together with my about page, despite the launch options in application configuration are set to only display the "about" page.

How can I achieve these two things in IBM Domino 10?

答:
In addtion to Per Henrik's recommendation, if you want to create a template, you need to create a new copy of the database and select to only copy the design elements and then use the NTF extension to createa template instead of the NSF. </p>

<p>With your Launch settings, you've only selected to open the About document by default every time the database is opened, you're not "only" opening the About document. The shared view is still being opened behind the About doc and you can't get rid of the only view. If you don't want users accessing the database via the Notes client, in order to avoid the view being opened, you might look at creating a Frameset that opens one Page that tells users to use the Web view. On the web side, you'll want to set the XPage that should be opened when accessing it via a browser. </p>

Body:
In addtion to Per Henrik's recommendation, if you want to create a template, you need to create a new copy of the database and select to only copy the design elements and then use the NTF extension to createa template instead of the NSF.

With your Launch settings, you've only selected to open the About document by default every time the database is opened, you're not "only" opening the About document. The shared view is still being opened behind the About doc and you can't get rid of the only view. If you don't want users accessing the database via the Notes client, in order to avoid the view being opened, you might look at creating a Frameset that opens one Page that tells users to use the Web view. On the web side, you'll want to set the XPage that should be opened when accessing it via a browser.


问:
How to add new markers and calculate the new route
I have a map with a route that contains a series of waypoints. I would like to be able to add new markers by clicking on the map, and to automatically calculate the route with the previous and new markers, taking into account the settings of optimizeWaypoints: true.

I've tried but I don't understand how to do it.

Anyone know how to do this?

     function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
          zoom: 4,
          center: {lat: -32.949798, lng: -60.681911}
        });

        var directionsService = new google.maps.DirectionsService;
        var directionsRenderer = new google.maps.DirectionsRenderer({
          draggable: true,
          map: map,
          panel: document.getElementById('right-panel')
        });

        directionsRenderer.addListener('directions_changed', function() {
          computeTotalDistance(directionsRenderer.getDirections());
        });

       google.maps.event.addListener(map, 'click', function(event) {
           placeMarker(event.latLng);
       });

        function placeMarker(location) {
            var marker = new google.maps.Marker({
                position: location,
                map: map
            });
        }

        displayRoute(new google.maps.LatLng(-32.949798, -60.681911), new google.maps.LatLng(-32.949798, -60.681911), directionsService,
            directionsRenderer);
      }

      function displayRoute(origin, destination, service, display) {
        service.route({
          origin: origin,
          destination: destination,
          waypoints: [{location: new google.maps.LatLng(-32.930572, -60.662137)},
                      {location: new google.maps.LatLng(-32.923554, -60.665930)},
                      {location: new google.maps.LatLng(-32.936270, -60.652841
)},],
          optimizeWaypoints: true,
          travelMode: 'DRIVING',
          avoidTolls: true,
          avoidHighways: true
        }, function(response, status) {
          if (status === 'OK') {
            display.setDirections(response);
          } else {
            alert('Could not display directions due to: ' + status);
          }
        });
      }

      function computeTotalDistance(result) {
        var totalDistance = 0;
        var totalDuration = 0;
        var minutes = 0;
        var hours = 0;
        var myroute = result.routes[0];
        for (var i = 0; i < myroute.legs.length; i++) {
          totalDistance += myroute.legs[i].distance.value;
          totalDuration += myroute.legs[i].duration.value;
        }
        totalDistance = totalDistance / 1000;

        var hours = Math.floor( totalDuration / 3600 );
        var minutes = Math.floor( (totalDuration % 3600) / 60 );
        var seconds = totalDuration % 60;

        hours = hours < 10 ? '0' + hours : hours;
        minutes = minutes < 10 ? '0' + minutes : minutes;
        seconds = seconds < 10 ? '0' + seconds : seconds;
        if(hours == 0) {
          var result = minutes + " min";
        } else {
          var result = hours + ':' + minutes + " hs";
        }

        document.getElementById('total_distance').innerHTML = totalDistance.toFixed(2) + ' km ';
        document.getElementById('total_duration').innerHTML = result;
      }```
<pre class="snippet-code-css lang-css prettyprint-override"><code>      #right-panel {
        font-family: 'Roboto','sans-serif';
        line-height: 30px;
        padding-left: 10px;
      }

      #right-panel select, #right-panel input {
        font-size: 15px;
      }

      #right-panel select {
        width: 100%;
      }

      #right-panel i {
        font-size: 12px;
      }
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
        float: left;
        width: 63%;
        height: 100%;
      }
      #right-panel {
        float: right;
        width: 34%;
        height: 100%;
      }
      .panel {
        height: 100%;
        overflow: auto;
      }</code>```

<!DOCTYPE html>

    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Direcciones</title>

Distance:

Duration:

```

答:
When you click on the map, add the location of the click to an array of "added waypoints".

```<code>var addedWaypoints = [];

function addWaypoint(latLng) {
  addedWaypoints.push(latLng);
}
</code>```

Call the directions service again, adding the new waypoints in to the request.

```<code>google.maps.event.addListener(map, 'click', function(event) {
  addWaypoint(event.latLng);
  displayRoute(start, end, directionsService, directionsRenderer);
});

function displayRoute(origin, destination, service, display) {
  var waypoints = [
    {location: new google.maps.LatLng(-32.930572, -60.662137)},
    {location: new google.maps.LatLng(-32.923554, -60.665930)},
    {location: new google.maps.LatLng(-32.936270, -60.652841)}
  ];
  for (var i=0; i<addedWaypoints.length;i++) {
    waypoints.push({
      location: addedWaypoints[i]
    });
  }
  service.route({
    origin: origin,
    destination: destination,
    waypoints: waypoints,
    optimizeWaypoints: true,
    travelMode: 'DRIVING',
    avoidTolls: true,
    avoidHighways: true
  }, function(response, status) {
    if (status === 'OK') {
      display.setDirections(response);
    } else {
      alert('Could not display directions due to: ' + status);
    }
  });
}
</code>```

proof of concept fiddle

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {
      lat: -32.949798,
      lng: -60.681911
    }
  });

  var directionsService = new google.maps.DirectionsService();
  var directionsRenderer = new google.maps.DirectionsRenderer({
    draggable: true,
    map: map,
    panel: document.getElementById('right-panel')
  });

  directionsRenderer.addListener('directions_changed', function() {
    computeTotalDistance(directionsRenderer.getDirections());
  });
  var start = new google.maps.LatLng(-32.949798, -60.681911);
  var end = new google.maps.LatLng(-32.949798, -60.681911);

  google.maps.event.addListener(map, 'click', function(event) {
    // placeMarker(event.latLng);
    addWaypoint(event.latLng);
    displayRoute(start, end, directionsService, directionsRenderer);
  });

  function placeMarker(location) {
    var marker = new google.maps.Marker({
      position: location,
      map: map
    });
  }

  displayRoute(start, end, directionsService, directionsRenderer);
}

function displayRoute(origin, destination, service, display) {
  var waypoints = [{
      location: new google.maps.LatLng(-32.930572, -60.662137)
    },
    {
      location: new google.maps.LatLng(-32.923554, -60.665930)
    },
    {
      location: new google.maps.LatLng(-32.936270, -60.652841)
    },
  ];
  for (var i=0; i<addedWaypoints.length;i++) {
    waypoints.push({
      location: addedWaypoints[i]
    });
  }
  var wayptsStr = "";
  for (var i=0; i<waypoints.length; i++) {
     wayptsStr += waypoints[i].location.toUrlValue(6)+",";
  }
  console.log("displayRoute: origin="+origin.toUrlValue(6)+" dest="+destination.toUrlValue(6)+" waypoints="+wayptsStr);
  service.route({
    origin: origin,
    destination: destination,
    waypoints: waypoints,
    optimizeWaypoints: true,
    travelMode: 'DRIVING',
    avoidTolls: true,
    avoidHighways: true
  }, function(response, status) {
    if (status === 'OK') {
      display.setDirections(response);
    } else {
      alert('Could not display directions due to: ' + status);
    }
  });
}
var addedWaypoints = [];

function addWaypoint(latLng) {
  addedWaypoints.push(latLng);
}

function computeTotalDistance(result) {
  var totalDistance = 0;
  var totalDuration = 0;
  var minutes = 0;
  var hours = 0;
  var myroute = result.routes[0];
  for (var i = 0; i < myroute.legs.length; i++) {
    totalDistance += myroute.legs[i].distance.value;
    totalDuration += myroute.legs[i].duration.value;
  }
  totalDistance = totalDistance / 1000;

  var hours = Math.floor(totalDuration / 3600);
  var minutes = Math.floor((totalDuration % 3600) / 60);
  var seconds = totalDuration % 60;

  hours = hours < 10 ? '0' + hours : hours;
  minutes = minutes < 10 ? '0' + minutes : minutes;
  seconds = seconds < 10 ? '0' + seconds : seconds;
  if (hours == 0) {
    var result = minutes + " min";
  } else {
    var result = hours + ':' + minutes + " hs";
  }

  document.getElementById('total_distance').innerHTML = totalDistance.toFixed(2) + ' km ';
  document.getElementById('total_duration').innerHTML = result;
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#right-panel {
        font-family: 'Roboto','sans-serif';
        line-height: 30px;
        padding-left: 10px;
      }

      #right-panel select, #right-panel input {
        font-size: 15px;
      }

      #right-panel select {
        width: 100%;
      }

      #right-panel i {
        font-size: 12px;
      }
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
        float: left;
        width: 63%;
        height: 100%;
      }
      #right-panel {
        float: right;
        width: 34%;
        height: 100%;
      }
      .panel {
        height: 100%;
        overflow: auto;
      }</code>```

Distance:

Duration:

```

Body:
I have a map with a route that contains a series of waypoints. I would like to be able to add new markers by clicking on the map, and to automatically calculate the route with the previous and new markers, taking into account the settings of optimizeWaypoints: true.

I've tried but I don't understand how to do it.

Anyone know how to do this?

     function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
          zoom: 4,
          center: {lat: -32.949798, lng: -60.681911}
        });

        var directionsService = new google.maps.DirectionsService;
        var directionsRenderer = new google.maps.DirectionsRenderer({
          draggable: true,
          map: map,
          panel: document.getElementById('right-panel')
        });

        directionsRenderer.addListener('directions_changed', function() {
          computeTotalDistance(directionsRenderer.getDirections());
        });

       google.maps.event.addListener(map, 'click', function(event) {
           placeMarker(event.latLng);
       });

        function placeMarker(location) {
            var marker = new google.maps.Marker({
                position: location,
                map: map
            });
        }

        displayRoute(new google.maps.LatLng(-32.949798, -60.681911), new google.maps.LatLng(-32.949798, -60.681911), directionsService,
            directionsRenderer);
      }

      function displayRoute(origin, destination, service, display) {
        service.route({
          origin: origin,
          destination: destination,
          waypoints: [{location: new google.maps.LatLng(-32.930572, -60.662137)},
                      {location: new google.maps.LatLng(-32.923554, -60.665930)},
                      {location: new google.maps.LatLng(-32.936270, -60.652841
)},],
          optimizeWaypoints: true,
          travelMode: 'DRIVING',
          avoidTolls: true,
          avoidHighways: true
        }, function(response, status) {
          if (status === 'OK') {
            display.setDirections(response);
          } else {
            alert('Could not display directions due to: ' + status);
          }
        });
      }

      function computeTotalDistance(result) {
        var totalDistance = 0;
        var totalDuration = 0;
        var minutes = 0;
        var hours = 0;
        var myroute = result.routes[0];
        for (var i = 0; i < myroute.legs.length; i++) {
          totalDistance += myroute.legs[i].distance.value;
          totalDuration += myroute.legs[i].duration.value;
        }
        totalDistance = totalDistance / 1000;

        var hours = Math.floor( totalDuration / 3600 );
        var minutes = Math.floor( (totalDuration % 3600) / 60 );
        var seconds = totalDuration % 60;

        hours = hours < 10 ? '0' + hours : hours;
        minutes = minutes < 10 ? '0' + minutes : minutes;
        seconds = seconds < 10 ? '0' + seconds : seconds;
        if(hours == 0) {
          var result = minutes + " min";
        } else {
          var result = hours + ':' + minutes + " hs";
        }

        document.getElementById('total_distance').innerHTML = totalDistance.toFixed(2) + ' km ';
        document.getElementById('total_duration').innerHTML = result;
      }

      #right-panel {
        font-family: 'Roboto','sans-serif';
        line-height: 30px;
        padding-left: 10px;
      }

      #right-panel select, #right-panel input {
        font-size: 15px;
      }

      #right-panel select {
        width: 100%;
      }

      #right-panel i {
        font-size: 12px;
      }
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
        float: left;
        width: 63%;
        height: 100%;
      }
      #right-panel {
        float: right;
        width: 34%;
        height: 100%;
      }
      .panel {
        height: 100%;
        overflow: auto;
      }

<!DOCTYPE html>

    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Direcciones</title>

Distance:

Duration:

Body:
When you click on the map, add the location of the click to an array of "added waypoints".

var addedWaypoints = [];

function addWaypoint(latLng) {
  addedWaypoints.push(latLng);
}

Call the directions service again, adding the new waypoints in to the request.

google.maps.event.addListener(map, 'click', function(event) {
  addWaypoint(event.latLng);
  displayRoute(start, end, directionsService, directionsRenderer);
});

function displayRoute(origin, destination, service, display) {
  var waypoints = [
    {location: new google.maps.LatLng(-32.930572, -60.662137)},
    {location: new google.maps.LatLng(-32.923554, -60.665930)},
    {location: new google.maps.LatLng(-32.936270, -60.652841)}
  ];
  for (var i=0; i<addedWaypoints.length;i++) {
    waypoints.push({
      location: addedWaypoints[i]
    });
  }
  service.route({
    origin: origin,
    destination: destination,
    waypoints: waypoints,
    optimizeWaypoints: true,
    travelMode: 'DRIVING',
    avoidTolls: true,
    avoidHighways: true
  }, function(response, status) {
    if (status === 'OK') {
      display.setDirections(response);
    } else {
      alert('Could not display directions due to: ' + status);
    }
  });
}

proof of concept fiddle

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {
      lat: -32.949798,
      lng: -60.681911
    }
  });

  var directionsService = new google.maps.DirectionsService();
  var directionsRenderer = new google.maps.DirectionsRenderer({
    draggable: true,
    map: map,
    panel: document.getElementById('right-panel')
  });

  directionsRenderer.addListener('directions_changed', function() {
    computeTotalDistance(directionsRenderer.getDirections());
  });
  var start = new google.maps.LatLng(-32.949798, -60.681911);
  var end = new google.maps.LatLng(-32.949798, -60.681911);

  google.maps.event.addListener(map, 'click', function(event) {
    // placeMarker(event.latLng);
    addWaypoint(event.latLng);
    displayRoute(start, end, directionsService, directionsRenderer);
  });

  function placeMarker(location) {
    var marker = new google.maps.Marker({
      position: location,
      map: map
    });
  }

  displayRoute(start, end, directionsService, directionsRenderer);
}

function displayRoute(origin, destination, service, display) {
  var waypoints = [{
      location: new google.maps.LatLng(-32.930572, -60.662137)
    },
    {
      location: new google.maps.LatLng(-32.923554, -60.665930)
    },
    {
      location: new google.maps.LatLng(-32.936270, -60.652841)
    },
  ];
  for (var i=0; i<addedWaypoints.length;i++) {
    waypoints.push({
      location: addedWaypoints[i]
    });
  }
  var wayptsStr = "";
  for (var i=0; i<waypoints.length; i++) {
     wayptsStr += waypoints[i].location.toUrlValue(6)+",";
  }
  console.log("displayRoute: origin="+origin.toUrlValue(6)+" dest="+destination.toUrlValue(6)+" waypoints="+wayptsStr);
  service.route({
    origin: origin,
    destination: destination,
    waypoints: waypoints,
    optimizeWaypoints: true,
    travelMode: 'DRIVING',
    avoidTolls: true,
    avoidHighways: true
  }, function(response, status) {
    if (status === 'OK') {
      display.setDirections(response);
    } else {
      alert('Could not display directions due to: ' + status);
    }
  });
}
var addedWaypoints = [];

function addWaypoint(latLng) {
  addedWaypoints.push(latLng);
}

function computeTotalDistance(result) {
  var totalDistance = 0;
  var totalDuration = 0;
  var minutes = 0;
  var hours = 0;
  var myroute = result.routes[0];
  for (var i = 0; i < myroute.legs.length; i++) {
    totalDistance += myroute.legs[i].distance.value;
    totalDuration += myroute.legs[i].duration.value;
  }
  totalDistance = totalDistance / 1000;

  var hours = Math.floor(totalDuration / 3600);
  var minutes = Math.floor((totalDuration % 3600) / 60);
  var seconds = totalDuration % 60;

  hours = hours < 10 ? '0' + hours : hours;
  minutes = minutes < 10 ? '0' + minutes : minutes;
  seconds = seconds < 10 ? '0' + seconds : seconds;
  if (hours == 0) {
    var result = minutes + " min";
  } else {
    var result = hours + ':' + minutes + " hs";
  }

  document.getElementById('total_distance').innerHTML = totalDistance.toFixed(2) + ' km ';
  document.getElementById('total_duration').innerHTML = result;
}

#right-panel {
        font-family: 'Roboto','sans-serif';
        line-height: 30px;
        padding-left: 10px;
      }

      #right-panel select, #right-panel input {
        font-size: 15px;
      }

      #right-panel select {
        width: 100%;
      }

      #right-panel i {
        font-size: 12px;
      }
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
        float: left;
        width: 63%;
        height: 100%;
      }
      #right-panel {
        float: right;
        width: 34%;
        height: 100%;
      }
      .panel {
        height: 100%;
        overflow: auto;
      }

<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBMZqunCMWco2noEHk5BlWyJExOPn1XCRU&callback=initMap"></script>
<div id="map"></div>
<div id="right-panel">
  <p>Distance: <span id="total_distance"></span></p>
  <p>Duration: <span id="total_duration"></span></p>
</div>


问:
How to implement routed tabs with angular material, within a child route?
I want to use Angular Material tabs https://material.angular.io/components/tabs with a router navigation in the tabs.

I tried to use  as indicated in the doc, and I found this tutorial: https://nirajsonawane.github.io/2018/10/27/Angular-Material-Tabs-with-Router/
where I can find a template like that:

```<code><nav mat-tab-nav-bar>
  <a mat-tab-link
    *ngFor="let link of navLinks"
    [routerLink]="link.link"
    routerLinkActive #rla="routerLinkActive"
    [active]="rla.isActive">
    {{link.label}}
  </a>
</nav>
<router-outlet></router-outlet>
</code>```

But the problem is, that my tabs are not at the root of my application, but are in a submodule in a child route. I have something like that:

In app-routing-module:

```<code>const routes: Routes = [
  ...
  { path: 'subpath', loadChildren: () => import('./path-to-module/submodule.module').then(m => m.SubmoduleModule) },
  ...
];
</code>```

In submodule-routing-module I should have something like that:

```<code>const routes: Routes = [
  { path: '', component: FirstTabComponent },
  { path: 'tab2', component: SecondTabComponent },
]
</code>```

What I would like is that, if I go to url /subpath I see the tabs with the first tab selected, and if I go to url /subpath/tab2 I see the tabs with the second tab selected.

Any idea how to do that?

答:
I had the same issue.
The problem came from the routing module.

In order to inherit the imported Material classes,
the path for children must be lazy-loaded instead of being directed from the component.

This caused the problem:

```<code>import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: 'customers',
    // Don't use this method in order to link to children!
    component: 'CustomerListComponent'

  }
</code>```

The 'customer list' template loaded, but without formatting. Also, Angular threw an error because it could not find the 'mat-tab' directive anywhere, even though it was being imported in the parent component, orders.module.ts.

This was the solution: src > app > app-routing.module.ts

```<code>const routes: Routes = [{
      path: 'customers',
      loadChildren: () =>
        import ('./customers/customers.module').then(m => m.CustomersModule)
    }
</code>```

Here are the related files from the project:
src > app > orders > orders.module.ts

```<code>import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { OrdersRoutingModule } from './orders-routing.module';
import { OrderListComponent } from './order-list/order-list.component';

// Material components
import { MatTabsModule } from '@angular/material/tabs';

@NgModule({
  imports: [
    CommonModule,
    OrdersRoutingModule,
    MatTabsModule
  ],
  declarations: [
    OrderListComponent
  ]
})
export class OrdersModule { }
</code>```

src > app > orders > orders-list > orders-list.component.html

```<code><mat-tab-group>
  <mat-tab label="Orders">
    <ng-template matTabContent>
      <p>Orders here.</p>
    </ng-template>
  </mat-tab>
  <mat-tab label="Shipments">
    <ng-template matTabContent>
      <p>Shipments here.</p>
    </ng-template>
  </mat-tab>
  <mat-tab label="Archived">
    <ng-template matTabContent>
      <p>Really old orders here.</p>
    </ng-template>
  </mat-tab>
</mat-tab-group>
</code>```

Body:
I want to use Angular Material tabs https://material.angular.io/components/tabs with a router navigation in the tabs.

I tried to use  as indicated in the doc, and I found this tutorial: https://nirajsonawane.github.io/2018/10/27/Angular-Material-Tabs-with-Router/
where I can find a template like that:

    {{link.label}}

<router-outlet></router-outlet>

But the problem is, that my tabs are not at the root of my application, but are in a submodule in a child route. I have something like that:

In app-routing-module:

const routes: Routes = [
  ...
  { path: 'subpath', loadChildren: () => import('./path-to-module/submodule.module').then(m => m.SubmoduleModule) },
  ...
];

In submodule-routing-module I should have something like that:

const routes: Routes = [
  { path: '', component: FirstTabComponent },
  { path: 'tab2', component: SecondTabComponent },
]

What I would like is that, if I go to url /subpath I see the tabs with the first tab selected, and if I go to url /subpath/tab2 I see the tabs with the second tab selected.

Any idea how to do that?

Body:
I had the same issue.
The problem came from the routing module.

In order to inherit the imported Material classes,
the path for children must be lazy-loaded instead of being directed from the component.

This caused the problem:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: 'customers',
    // Don't use this method in order to link to children!
    component: 'CustomerListComponent'

  }

The 'customer list' template loaded, but without formatting. Also, Angular threw an error because it could not find the 'mat-tab' directive anywhere, even though it was being imported in the parent component, orders.module.ts.

This was the solution: src > app > app-routing.module.ts

const routes: Routes = [{
      path: 'customers',
      loadChildren: () =>
        import ('./customers/customers.module').then(m => m.CustomersModule)
    }

Here are the related files from the project:
src > app > orders > orders.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { OrdersRoutingModule } from './orders-routing.module';
import { OrderListComponent } from './order-list/order-list.component';

// Material components
import { MatTabsModule } from '@angular/material/tabs';

@NgModule({
  imports: [
    CommonModule,
    OrdersRoutingModule,
    MatTabsModule
  ],
  declarations: [
    OrderListComponent
  ]
})
export class OrdersModule { }

src > app > orders > orders-list > orders-list.component.html

<mat-tab-group>
  <mat-tab label="Orders">
    <ng-template matTabContent>
      <p>Orders here.</p>
    </ng-template>
  </mat-tab>
  <mat-tab label="Shipments">
    <ng-template matTabContent>
      <p>Shipments here.</p>
    </ng-template>
  </mat-tab>
  <mat-tab label="Archived">
    <ng-template matTabContent>
      <p>Really old orders here.</p>
    </ng-template>
  </mat-tab>
</mat-tab-group>


问:
How to investigate Xamarin/libmonosgen-2.0.so native crash?
My latest release is crashing at a rate of about 99 per 1000 devices - significantly higher than the release before it. New crashes come in 2 flavors in libmonosgen:

Cluster 1: libmonosgen-2.0.so

```<code>signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)
libmonosgen-2.0.so

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.dailybits.foodjournal <<<

backtrace:
  #00  pc 0000000000192304  /data/app/com.dailybits.foodjournal-KapbLS3Zx20G2S79yI3CTw==/lib/arm/libmonosgen-2.0.so
</code>```

Cluster 2: libmonosgen-2.0.so (mono_class_get_flags)

```<code>signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)
mono_class_get_flags
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.dailybits.foodjournal <<<

backtrace:
  #00  pc 000000000014f310  /data/app/com.dailybits.foodjournal-rwLqwfyotHI-Ulk481Wk8g==/lib/arm64/libmonosgen-2.0.so (mono_class_get_flags)
</code>```

Pre-release report is looking all green, and App Center has none of these crashes, they only show up in Google Play.

Questions:

Does anyone know what pid:0 and tid:0 mean? Does this mean these crashes are occurring before the application code is loaded, or is that unrelated?

If this isn't at app startup, can I somehow find out after how long the crash occurs? Or even better, can I correlate the crashes to app generated session logs?

Is there a way to configure Play, or the App to collect better traces?

Configuration details below

(both build options appear to result in the same problem)

Version info

```<code>Microsoft Visual Studio Professional 2019
Version 16.4.2
VisualStudio.16.Release/16.4.2+29613.14
Microsoft .NET Framework
Version 4.8.03752

Xamarin   16.4.000.307 (d16-4@e031886)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android SDK   10.1.1.0 (d16-4/f2c9364)
Xamarin.Android Reference Assemblies and MSBuild support.
    Mono: bef1e63
    Java.Interop: xamarin/java.interop/d16-4@c4e569f
    ProGuard: xamarin/proguard/master@905836d
    SQLite: xamarin/sqlite/3.28.0@46204c4
    Xamarin.Android Tools: xamarin/xamarin-android-tools/master@9f4ed4b
</code>```

Edit 2/17/2020

Some of my investigation to date:

Looks like libmonosgen contains the Xamarin garbage collector.

SEGV_ACCERR is an access denied on a platform object (IE object already disposed). A good way to get these apparently is to have static objects accessed from multiple threads.  I'm thinking this may mean one of the threads disposes the underlaying Java object, without telling the Mono runtime.

Third party libraries, as well as new Java objects (IE changes to UI controls I'm using) are suspects.

I've decided to go with a fine-toothed comb through all the changes, revert all the package updates, and re-do them one-by-one, until a release starts crashing.
If I'm unlucky, it's going to take a few weeks, but it should work to find out what causes the crash. It should also allow me to ship my new features to 100% without creating a spike in crashes for all users. Fingers crossed :)

答:
After a good amount of research (see bottom of question), I decided to strip all changes from the app, and start dishing them out again one by one. Fortunately, just as I was done doing a detailed comb-through of all changes (from 2 months of work), a user posted a 1 star review, with detailed repro instructions!.

So, the answer to the question "how to investigate crashes with no stack trace":

You have to find a repro, and one way (for on production releases) to find one is to wait for your users to tell you.

Answers to the other in-line questions:

Does anyone know what pid:0 and tid:0 mean? Does this mean these
crashes are occurring before the application code is loaded, or is
that unrelated?

This means the stack got corrupted, and process and tid are no longer available (does not mean that this is at startup). IE Weird Native Crash - pid: 0, tid: 0 signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)

If this isn't at app startup, can I somehow find out after how long
the crash occurs? Or even better, can I correlate the crashes to app
generated session logs?

I haven't found a way to add to these logs, the better way is to find a repro.

Is there a way to configure Play, or the App to collect better
traces?

Not for these kinds of crashes.

Details / root cause of the actual crash:

As it turns out, my favorite PropertyChanged.Fody and Xamarin Forms's behavior had changed since the last time I had updated it, to the point where more PropertyChanged events were generated than in the past (IE, even if the value that is being assigned is equal to the original value, a "propertychanged" event is now fired).

In one of my more interesting viewmodels (that does automatic unit conversion based on the text value from an entry control), and when combined with a custom control this results into an infinite recursion. (Meaning the value would change, which would trigger a propertychanged event, which would update the control, which would assign the value to the viewmodel, which would trigger propertychanged, etc...)

Once I had a repro, investigating and fixing the issue was trivial;
I was able to solve the issue, by decorating one of the properties with [DoNotNotify]

Body:
My latest release is crashing at a rate of about 99 per 1000 devices - significantly higher than the release before it. New crashes come in 2 flavors in libmonosgen:

Cluster 1: libmonosgen-2.0.so

signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)
libmonosgen-2.0.so

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.dailybits.foodjournal <<<

backtrace:
  #00  pc 0000000000192304  /data/app/com.dailybits.foodjournal-KapbLS3Zx20G2S79yI3CTw==/lib/arm/libmonosgen-2.0.so

Cluster 2: libmonosgen-2.0.so (mono_class_get_flags)

signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)
mono_class_get_flags
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.dailybits.foodjournal <<<

backtrace:
  #00  pc 000000000014f310  /data/app/com.dailybits.foodjournal-rwLqwfyotHI-Ulk481Wk8g==/lib/arm64/libmonosgen-2.0.so (mono_class_get_flags)

Pre-release report is looking all green, and App Center has none of these crashes, they only show up in Google Play.

Questions:

Does anyone know what pid:0 and tid:0 mean? Does this mean these crashes are occurring before the application code is loaded, or is that unrelated?

If this isn't at app startup, can I somehow find out after how long the crash occurs? Or even better, can I correlate the crashes to app generated session logs?

Is there a way to configure Play, or the App to collect better traces?

Configuration details below

(both build options appear to result in the same problem)

Version info

Microsoft Visual Studio Professional 2019
Version 16.4.2
VisualStudio.16.Release/16.4.2+29613.14
Microsoft .NET Framework
Version 4.8.03752

Xamarin   16.4.000.307 (d16-4@e031886)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android SDK   10.1.1.0 (d16-4/f2c9364)
Xamarin.Android Reference Assemblies and MSBuild support.
    Mono: bef1e63
    Java.Interop: xamarin/java.interop/d16-4@c4e569f
    ProGuard: xamarin/proguard/master@905836d
    SQLite: xamarin/sqlite/3.28.0@46204c4
    Xamarin.Android Tools: xamarin/xamarin-android-tools/master@9f4ed4b

Edit 2/17/2020

Some of my investigation to date:

Looks like libmonosgen contains the Xamarin garbage collector.

SEGV_ACCERR is an access denied on a platform object (IE object already disposed). A good way to get these apparently is to have static objects accessed from multiple threads.  I'm thinking this may mean one of the threads disposes the underlaying Java object, without telling the Mono runtime.

Third party libraries, as well as new Java objects (IE changes to UI controls I'm using) are suspects.

I've decided to go with a fine-toothed comb through all the changes, revert all the package updates, and re-do them one-by-one, until a release starts crashing.
If I'm unlucky, it's going to take a few weeks, but it should work to find out what causes the crash. It should also allow me to ship my new features to 100% without creating a spike in crashes for all users. Fingers crossed :)


问:
Use beautifulsoup4 in Alexa developer console
I need beautifulsoup4 to scrape through a websites HTML and get information. I want to use that information in my Alexa-skill.

How do I import/use bs4 in my Alexa developer console?

I've already read how to make a deployment package (https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html), but I don't understand how to download/zip bs4.

I am new to Python, AWS and Alexa developer console, so I am sorry if that question is very easy to answer.

Kind regards,
Dany

答: I think you'll find all you need here at this documentation url: https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html</p>


问:
Finding if the x and y coordinate is within a view is enclosed by two intersecting rectangles, in java
Say I have this view with two subviews A and B, A and B has a color property mColor,

I want a function in the parent view that has this signature: int getColor(int x, int y), which for any given x and y coordinate, return the color at that position, if the x and y coordinates land and the two shapes are overlapped, return the average color of A and B

The problem I am running into is i see myself doing a lot of conditional checks, checking if A is left of B or if A is right of B etc. I feel like I am missing some key intuition

I have a Point class that handles the coordinates"

```<code>public class Point {
    private final int mX;
    private final int mY;

    public Point(int mX, int mY) {
        this.mX = mX;
        this.mY = mY;
    }

    public int getX() {
        return mX;
    }

    public int getY() {
        return mY;
    }
}
</code>```

Here is my subview class:

```<code>public class Chart  {

    private int mColor;
    private Point mTopLeft;
    private Point mBottomRight;

    public Point getTopLeft() {
        return mTopLeft;
    }

    public Point getBottomRight() {
        return mBottomRight;
    }

    public Chart(int mColor, Point topLeft, Point bottomRight) {
        this.mColor = mColor;
        this.mTopLeft = topLeft;
        this.mBottomRight = bottomRight;
    }

    public int getColor() {
        return mColor;
    }

    public Point getTopRightCorner() {
        return new Point(getBottomRight().getX(), getTopLeft().getY());
    }

    public Point getBottomLeftCorner() {
        return new Point(getTopLeft().getX(), getBottomRight().getY());
    }
}
</code>```

My parent view class:

```<code>public class View {

    private Chart mChartA;
    private Chart mChartB;

    public View(Chart chartA,
                Chart chartB) {
        mChartA = chartA;
        mChartB = chartB;
    }

    public boolean doChartsOverlap() {
        boolean isOverlapped = true;

        if(isChartALeftOfChartBInX() || isChartARightOfChartBInX()) {
            isOverlapped = false;
        }

        if(isChartABottomOfChartBInY() || isChartATopOfChartBInY()) {
            isOverlapped = false;
        }
        return isOverlapped;
    }

    public final boolean isChartALeftOfChartBInX() {
        return mChartA.getBottomRight().getX() <= mChartB.getTopLeft().getX();
    }

    public final boolean isChartARightOfChartBInX() {
        return mChartA.getTopLeft().getX() >= mChartB.getBottomRight().getX();
    }

    public final boolean isChartATopOfChartBInY() {
        return mChartA.getBottomRight().getY() <= mChartB.getTopLeft().getY();
    }

    public final boolean isChartABottomOfChartBInY() {
        return mChartA.getTopLeft().getY() >= mChartB.getBottomRight().getY();
    }

    public void setChartA(Chart mChartA) {
        this.mChartA = mChartA;
    }

    public void setChartB(Chart mChartB) {
        this.mChartB = mChartB;
    }
}
</code>```

答:
Logically, you want to test if the point is in both rectangles; so test if it is in one rectangle and also in the other rectangle. Everything else about whether one rectangle is above, below, left or right of the other is a red herring.

Add this method to the Chart class (use < instead of <= if you only want to paint the interiors):

public boolean contains(Point p) {
    return mTopLeft.getX() <= p.getX() && p.getX() <= mBottomRight.getX()
        && mTopLeft.getY() <= p.getY() && p.getY() <= mBottomRight.getY();
}
```

<p>And this method to the <code>View</code> class:</p>

<pre class="lang-java prettyprint-override"><code>public int getColor(Point p) {
    boolean inA = mChartA.contains(p), inB = mChartB.contains(p);
    if(inA && inB) {
        // ...
    } else if(inA) {
        // ...
    } else if(inB) {
        // ...
    } else {
        // ...
    }
}
</code>```

You can then overload public int getColor(int x, int y) to return getColor(new Point(x, y)).

Body:
Say I have this view with two subviews A and B, A and B has a color property mColor,

I want a function in the parent view that has this signature: int getColor(int x, int y), which for any given x and y coordinate, return the color at that position, if the x and y coordinates land and the two shapes are overlapped, return the average color of A and B

The problem I am running into is i see myself doing a lot of conditional checks, checking if A is left of B or if A is right of B etc. I feel like I am missing some key intuition

I have a Point class that handles the coordinates"

public class Point {
    private final int mX;
    private final int mY;

    public Point(int mX, int mY) {
        this.mX = mX;
        this.mY = mY;
    }

    public int getX() {
        return mX;
    }

    public int getY() {
        return mY;
    }
}

Here is my subview class:

public class Chart  {

    private int mColor;
    private Point mTopLeft;
    private Point mBottomRight;

    public Point getTopLeft() {
        return mTopLeft;
    }

    public Point getBottomRight() {
        return mBottomRight;
    }

    public Chart(int mColor, Point topLeft, Point bottomRight) {
        this.mColor = mColor;
        this.mTopLeft = topLeft;
        this.mBottomRight = bottomRight;
    }

    public int getColor() {
        return mColor;
    }

    public Point getTopRightCorner() {
        return new Point(getBottomRight().getX(), getTopLeft().getY());
    }

    public Point getBottomLeftCorner() {
        return new Point(getTopLeft().getX(), getBottomRight().getY());
    }
}

My parent view class:

public class View {

    private Chart mChartA;
    private Chart mChartB;

    public View(Chart chartA,
                Chart chartB) {
        mChartA = chartA;
        mChartB = chartB;
    }

    public boolean doChartsOverlap() {
        boolean isOverlapped = true;

        if(isChartALeftOfChartBInX() || isChartARightOfChartBInX()) {
            isOverlapped = false;
        }

        if(isChartABottomOfChartBInY() || isChartATopOfChartBInY()) {
            isOverlapped = false;
        }
        return isOverlapped;
    }

    public final boolean isChartALeftOfChartBInX() {
        return mChartA.getBottomRight().getX() <= mChartB.getTopLeft().getX();
    }

    public final boolean isChartARightOfChartBInX() {
        return mChartA.getTopLeft().getX() >= mChartB.getBottomRight().getX();
    }

    public final boolean isChartATopOfChartBInY() {
        return mChartA.getBottomRight().getY() <= mChartB.getTopLeft().getY();
    }

    public final boolean isChartABottomOfChartBInY() {
        return mChartA.getTopLeft().getY() >= mChartB.getBottomRight().getY();
    }

    public void setChartA(Chart mChartA) {
        this.mChartA = mChartA;
    }

    public void setChartB(Chart mChartB) {
        this.mChartB = mChartB;
    }
}

Body:
Logically, you want to test if the point is in both rectangles; so test if it is in one rectangle and also in the other rectangle. Everything else about whether one rectangle is above, below, left or right of the other is a red herring.

Add this method to the Chart class (use < instead of <= if you only want to paint the interiors):

public boolean contains(Point p) {
    return mTopLeft.getX() <= p.getX() && p.getX() <= mBottomRight.getX()
        && mTopLeft.getY() <= p.getY() && p.getY() <= mBottomRight.getY();
}

And this method to the View class:

public int getColor(Point p) {
    boolean inA = mChartA.contains(p), inB = mChartB.contains(p);
    if(inA && inB) {
        // ...
    } else if(inA) {
        // ...
    } else if(inB) {
        // ...
    } else {
        // ...
    }
}

You can then overload public int getColor(int x, int y) to return getColor(new Point(x, y)).


问:
Using self_value in another class
I'm trying to learn more about classes so I've built a deck of cards using multiple classes. The goal is to be able to play multiple card games with the deck.
I have a basic class, called PlayingCard:

```<code>class PlayingCard:
def __init__(self, suit, value):
    self.suit = suit
    self.value = value
</code>```

And different sub-classes for the numbered cards, the jack cards, the queen cards etc. defined as:

```<code>class NumberedCards(PlayingCard):
def __init__(self, suit, value):
    self.value = value
    super().__init__(suit, self.value)

class JackCard(PlayingCard):
    def __init__(self, suit):
        self.value = 11
        super().__init__(suit, self.value)

...and so on
</code>```

I then build my deck of cards in a new class, 'Deck':

```<code>class Deck:
def __init__(self):
    self.deck = []

def create_deck(self):
    for suit in Suit:
        for i in range(2, 11):
            self.deck.append(NumberedCards(suit.value, i))
        self.deck.append(JackCard(suit.value))
        ...
</code>```

Lastly, I have a class called Hand:

```<code>class Hand:
def __init__(self):
    self.hand = []
</code>```

where I have functions to draw cards from the deck and place them in self.hand

I now want to create yet another class with different functions, where I can use a Hand()-instance to check if there's for example any pairs in the hand or if there's a straight etc.
I have something like this in mind:

```<code>class BestHand:
def __init__(self):
    ...

def check_pairs(self, cards):
    """Here, for example, I want to extract the value of
    each card on hand and put them in a new list for easier comparison"""
</code>```

where I then can check the cards in the hand by calling something in the style of

```<code>hand = Hand()
test = BestHand()
test.check_pairs(hand)
</code>```

The problem is that I can't extract the value from the hand-cards. I realize they're only defined as self.value in the class PlayingCard, but is there a way to extract them to use in the BestHand class?

答: You have an object called hand, it is of type Hand meaning it has an attribute called hand which is  list of Card objects. hand.hand is the list of Card objects in that object. [card.value for card in hand.hand] will get the value for each card in that list of cards

Title: Using self_value in another class

Body:
I'm trying to learn more about classes so I've built a deck of cards using multiple classes. The goal is to be able to play multiple card games with the deck.
I have a basic class, called PlayingCard:

class PlayingCard:
def __init__(self, suit, value):
    self.suit = suit
    self.value = value

And different sub-classes for the numbered cards, the jack cards, the queen cards etc. defined as:

class NumberedCards(PlayingCard):
def __init__(self, suit, value):
    self.value = value
    super().__init__(suit, self.value)

class JackCard(PlayingCard):
    def __init__(self, suit):
        self.value = 11
        super().__init__(suit, self.value)

...and so on

I then build my deck of cards in a new class, 'Deck':

class Deck:
def __init__(self):
    self.deck = []

def create_deck(self):
    for suit in Suit:
        for i in range(2, 11):
            self.deck.append(NumberedCards(suit.value, i))
        self.deck.append(JackCard(suit.value))
        ...

Lastly, I have a class called Hand:

class Hand:
def __init__(self):
    self.hand = []

where I have functions to draw cards from the deck and place them in self.hand

I now want to create yet another class with different functions, where I can use a Hand()-instance to check if there's for example any pairs in the hand or if there's a straight etc.
I have something like this in mind:

class BestHand:
def __init__(self):
    ...

def check_pairs(self, cards):
    """Here, for example, I want to extract the value of
    each card on hand and put them in a new list for easier comparison"""

where I then can check the cards in the hand by calling something in the style of

hand = Hand()
test = BestHand()
test.check_pairs(hand)

The problem is that I can't extract the value from the hand-cards. I realize they're only defined as self.value in the class PlayingCard, but is there a way to extract them to use in the BestHand class?


问:
Separating Docker files and application source files to optimize production environment
I have a bunch of (Ruby) scripts stored on a server. Up until now, my team has used them by opening an accessor app that launches a list of the script names, and they select the script they want to run in that instance on the files in their working folder. The scripts are run directly from the server, so updates made to the script files are automatically reflected when a user runs the script.

The scripts require a fair amount of specific dependencies, so I'm trying to move to a Docker-based workflow to eliminate the problems we encounter with incongruent computer environments. I've been able to successfully build an image with our script library and run an instance of it on my computer.

However, all of the documentation and tutorials include the application source files when building an image, so that all the files are copied over by the Dockerfile. From my understanding, this means that any time the code in the application files needs to be updated, all the users will need to rebuild the image before trying to run anything. I would very rarely ever need to make changes to the environment settings/dependencies, but the app code is changed relatively frequently, so it seems like having every user rebuild an image every single time a line of app code is changed would actually slow down everyone's workflow considerably.

My question is this: Is it not possible to have Docker simply create the environment that a user must have to run the applications, but have the applications themselves still run directly off the server where they were originally stored? And does a new container need to be created every single time a user wants to run any one of the scripts? (The users are not tech-savvy.)

答:
Is it not possible to have Docker simply create the environment that a user must have to run the applications, but have the applications themselves still run directly off the server where they were originally stored?

You can build an image with all the environment already installed then mount the directory with the scripts so the container can read the scripts from the host. Something like

```<code>docker run -it --rm -v /opt/myscripts:/myscripts myimage somescript.rb
</code>```

Then your image Dockerfile would end with:

```<code>WORKDIR /myscripts
ENTRYPOINT ["/usr/bin/ruby"]
</code>```

And does a new container need to be created every single time a user wants to run any one of the scripts?

Of course, a container is just an isolated process managed by docker, you could make a wrapper so the users wouldn't need to type the full docker run command.

Body:
Is it not possible to have Docker simply create the environment that a user must have to run the applications, but have the applications themselves still run directly off the server where they were originally stored?

You can build an image with all the environment already installed then mount the directory with the scripts so the container can read the scripts from the host. Something like

docker run -it --rm -v /opt/myscripts:/myscripts myimage somescript.rb

Then your image Dockerfile would end with:

WORKDIR /myscripts
ENTRYPOINT ["/usr/bin/ruby"]

And does a new container need to be created every single time a user wants to run any one of the scripts?

Of course, a container is just an isolated process managed by docker, you could make a wrapper so the users wouldn't need to type the full docker run command.


问:
how do i Delay a component html from loading till all images are gotten?
i have a home page where i want to display the first 3 images as a slider which are called from an API.
this is my controller

```<code>export class ClientComponent implements OnInit {   public event;   public imgePAth: any;   public singleImg: any;   public secondImg: any;   public isAv: boolean = false;   filtersLoaded: Promise<boolean>;

  constructor(private servive: TycketService, private http: HttpClient,private route: Router) { }

  ngOnInit() {
    this.servive.allEvent().subscribe(data => {
      this.event = data;
      console.log(this.event);

      this.imgePAth = this.servive.imagebaseUrl(this.event[0]['image']);
      this.singleImg = this.servive.imagebaseUrl(this.event[1]['image']);
      this.secondImg = this.servive.imagebaseUrl(this.event[2]['image']);
      this.isAv = true;
      this.filtersLoaded = Promise.resolve(true);
      console.log(this.imgePAth);
    });   } }
</code>```

my api service

```<code>  imagebaseUrl(data){
    return (this.imageUrl + data);
  }
</code>```

my html ignore the event index, i am setting the background image w the [ngStyle], when i inspect i get an undefined path of the variable, but when i console.log the path in my ngOnInit i get the right path

```<code><div class="cover_slider owl-carousel owl-theme" *ngIf="filtersLoaded | async">
        <div class="overlay">
            <div class="cover_item" [ngStyle]="{'background-image':'url('+imgePAth+')'}">
                <div class="slider_content">
                    <div class="slider-content-inner">
                        <div class="container">
                            <div class="slider-content-center" *ngIf="event && event[0]">
                                <h2 class="cover-title">
                                    Prepare yourself for
                                </h2>
                                <strong class="cover-xl-text">{{event[0]['name']}}</strong>
                                <p class="cover-date">
                                    {{event[0]['date']}}  - {{event[0]['venue']}} {{event[0]['location']}}.
                                </p>
                                <button class=" btn btn-primary btn-rounded" (click)="onClickBuy(event[0])">Buy Tickets Now</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
</div>
</code>```

what is the solution for this?
enter image description here

答:
I guess it was erased by DomSanitazer in order to prevent XSS attacks on your application.
to turn it off you can </p>

```<code>constructor(private sanitizer: DomSanitizer){}
.....
this.imgePAth = this.sanitizer.bypassSecurityTrustResourceUrl(someUrl)
</code>```

Body:
i have a home page where i want to display the first 3 images as a slider which are called from an API.
this is my controller

export class ClientComponent implements OnInit {   public event;   public imgePAth: any;   public singleImg: any;   public secondImg: any;   public isAv: boolean = false;   filtersLoaded: Promise<boolean>;

  constructor(private servive: TycketService, private http: HttpClient,private route: Router) { }

  ngOnInit() {
    this.servive.allEvent().subscribe(data => {
      this.event = data;
      console.log(this.event);

      this.imgePAth = this.servive.imagebaseUrl(this.event[0]['image']);
      this.singleImg = this.servive.imagebaseUrl(this.event[1]['image']);
      this.secondImg = this.servive.imagebaseUrl(this.event[2]['image']);
      this.isAv = true;
      this.filtersLoaded = Promise.resolve(true);
      console.log(this.imgePAth);
    });   } }

my api service

  imagebaseUrl(data){
    return (this.imageUrl + data);
  }

my html ignore the event index, i am setting the background image w the [ngStyle], when i inspect i get an undefined path of the variable, but when i console.log the path in my ngOnInit i get the right path

                                    Prepare yourself for

                                {{event[0]['name']}}

                                    {{event[0]['date']}}  - {{event[0]['venue']}} {{event[0]['location']}}.

                                <button class=" btn btn-primary btn-rounded" (click)="onClickBuy(event[0])">Buy Tickets Now</button>

what is the solution for this?
enter image description here

Body:
I guess it was erased by DomSanitazer in order to prevent XSS attacks on your application.
to turn it off you can

constructor(private sanitizer: DomSanitizer){}
.....
this.imgePAth = this.sanitizer.bypassSecurityTrustResourceUrl(someUrl)


问:
Java, using an array of points
I am writing a program in Java, in which I define a class

```<code>class Point
{
    double x;
    double y;
}
</code>```

Then in a method, I define an array of points, as follows:

```<code>Point[]     line = new Point[6];
</code>```

In the same method, I have the line

```<code>line[SampleSize - i + 1].x = i;
</code>```

The first time this statement is hit, the value of its array index is 1;
but the program throws a null pointer exception at this point.

This would seem like the correct way to index the field of an object within an
array of objects.  What am I doing wrong?

Thanks in advance for any suggestions.

John Doner

答:
java has a built in Point class

import java.awt.Point;
```

https://docs.oracle.com/javase/7/docs/api/java/awt/Point.html

ContentLicense: CC BY-SA 2.5

Title: Java, using an array of points

Body:
I am writing a program in Java, in which I define a class

class Point
{
    double x;
    double y;
}

Then in a method, I define an array of points, as follows:

Point[]     line = new Point[6];

In the same method, I have the line

line[SampleSize - i + 1].x = i;

The first time this statement is hit, the value of its array index is 1;
but the program throws a null pointer exception at this point.

This would seem like the correct way to index the field of an object within an
array of objects.  What am I doing wrong?

Thanks in advance for any suggestions.

John Doner

Body:
java has a built in Point class

import java.awt.Point;

https://docs.oracle.com/javase/7/docs/api/java/awt/Point.html


问:
writing multiple lines back to a file, wrong file length
I want to get the a multiline text file's content, and put it back to the file.

However, I have an issue with the file length.
The null terminator (0) that I add is after some strange characters.

Something wrong with my f_length ?

Edit : If I set the line-endings of my file to Unix (LF), I don't have the issue. So it seems that my code is incompatible with Windows line endings. How can I account for Windows text files ?

```<code>int main()
{
    FILE *fp = NULL;
    int f_length;
    char *buffer = NULL;
    size_t size = 0;

    fp = fopen(FILENAME, "r+");
    fseek(fp, 0, SEEK_END);
    f_length = ftell(fp);
    rewind(fp);

    buffer = malloc((f_length + 1) * sizeof(*buffer));
    fread(buffer, f_length, 1, fp);
    buffer[f_length] = 0;
    printf("%s\n", buffer);

    fp = fopen(FILENAME, "w+");
    fputs(buffer, fp);
    fclose(fp);

    return 0;
}
</code>```

答:
You are assuming the size of the file on disk is going to be equal to the number of bytes you will read. That is a valid assumption for a clean, binary file. It is not a valid assumption for a text file.

I'd suggest using the return value from fread instead of f_length as it reports the number of objects you actually read after any required read processing. You'll need to adjust your fread parameters to read 1-byte sized objects.

Body:
I want to get the a multiline text file's content, and put it back to the file.

However, I have an issue with the file length.
The null terminator (0) that I add is after some strange characters.

Something wrong with my f_length ?

Edit : If I set the line-endings of my file to Unix (LF), I don't have the issue. So it seems that my code is incompatible with Windows line endings. How can I account for Windows text files ?

int main()
{
    FILE *fp = NULL;
    int f_length;
    char *buffer = NULL;
    size_t size = 0;

    fp = fopen(FILENAME, "r+");
    fseek(fp, 0, SEEK_END);
    f_length = ftell(fp);
    rewind(fp);

    buffer = malloc((f_length + 1) * sizeof(*buffer));
    fread(buffer, f_length, 1, fp);
    buffer[f_length] = 0;
    printf("%s\n", buffer);

    fp = fopen(FILENAME, "w+");
    fputs(buffer, fp);
    fclose(fp);

    return 0;
}


问:
Using a dynamic list in ELT
Using MySQL version 5.7.12

Getting an error trying the following:

```<code>SELECT ELT(
    3,
    SELECT GROUP_CONCAT(id) AS IDs FROM user_table a WHERE IsActive
) AS IDs
</code>```

Where the 3 in the first spot I can make it random eventually but the IDs from the user_table will be dynamic. Any idea on how I can make this work? Seems like ELT is kind of useless if I have to use it like:

```<code>SELECT ELT(4,'this','is','the','elt');
</code>```

Just be sure, the following code works:

```<code>SELECT GROUP_CONCAT(id) AS IDs FROM user_table a WHERE IsActive
</code>```

which returns 3,4,6,7 as does:

```<code>SELECT ELT(3,3,4,6,7 ) AS IDs
</code>```

which returns 6

答:
I don't really see the point for aggregating just to select a single value.

Also, since there is no order by option to your group_concat(), you actually get ids in an undefined ordering, which makes the final id that will be selected also undefined (meaning: two consecutive executions of the same query might, or might not, give different results).

If you want a (well-defined) id out of the list of active users, you can do a regular select statement, with order by and limit:

```<code>select id
from user_table
where isActive
order by id
limit 3, 1
</code>```

This gives you the id of the third active user in the table, ordered by id.

If you want a random id out of active users (which is not the same thing as undefined), then:

```<code>select id
from user_table
where isActive
order by rand()
limit 1
</code>```

Title: Using a dynamic list in ELT

Body:
Using MySQL version 5.7.12

Getting an error trying the following:

SELECT ELT(
    3,
    SELECT GROUP_CONCAT(id) AS IDs FROM user_table a WHERE IsActive
) AS IDs

Where the 3 in the first spot I can make it random eventually but the IDs from the user_table will be dynamic. Any idea on how I can make this work? Seems like ELT is kind of useless if I have to use it like:

SELECT ELT(4,'this','is','the','elt');

Just be sure, the following code works:

SELECT GROUP_CONCAT(id) AS IDs FROM user_table a WHERE IsActive

which returns 3,4,6,7 as does:

SELECT ELT(3,3,4,6,7 ) AS IDs

which returns 6

Body:
I don't really see the point for aggregating just to select a single value.

Also, since there is no order by option to your group_concat(), you actually get ids in an undefined ordering, which makes the final id that will be selected also undefined (meaning: two consecutive executions of the same query might, or might not, give different results).

If you want a (well-defined) id out of the list of active users, you can do a regular select statement, with order by and limit:

select id
from user_table
where isActive
order by id
limit 3, 1

This gives you the id of the third active user in the table, ordered by id.

If you want a random id out of active users (which is not the same thing as undefined), then:

select id
from user_table
where isActive
order by rand()
limit 1


问:
How to call tryton from jsonrpc
I'm trying to connect via json-rpc to the trytond isntance using this class

```<code>class HttpClient:
    """HTTP Client to make JSON RPC requests to Tryton server.
    User is logged in when an object is created.
    """

    def __init__(self, url, database_name, user, passwd):
        self._url = '{}/{}/'.format(url, database_name)
        self._user = user
        self._passwd = passwd
        self._login()
        self._id = 0

    def get_id(self):
        self._id += 1
        return self._id

    def _login(self):
        """
        Returns list, where
        0 - user id
        1 - session token
        """
        payload = json.dumps({
            'params': [self._user, {'password': self._passwd}],
            'jsonrpc': "2.0",
            'method': 'common.db.login',
            'id': 1,
        })
        headers = {'content-type': 'application/json'}
        result = requests.post(self._url, data=payload, headers=headers)
        if result.status_code in [500, 401]:
            raise Exception(result.text)

        if 'json' in result:
            self._session = result.json()['result']
        else:
            self._session = json.loads(result.text)

        return self._session

    def call(self, prefix, method, params=[[], {}]):
        """RPC Call
        """
        method = '{}.{}'.format(prefix, method)
        payload = json.dumps({
            'params': params,
            'method': method,
            'id': self.get_id(),

        })

        authorization = base64.b64encode(self._session[1].encode('utf-8'))
        headers = {
        'Content-Type': 'application/json',
        'Authorization': b'Session ' + authorization
        }

        response = requests.post(self._url, data=payload, headers=headers)
        if response.status_code in [500, 401]:
            raise Exception(response.text)
        return response.json()

    def model(self, model, method, args=[], kwargs={}):
        return self.call('model.%s' % model, method, [args, kwargs])

    def system(self, method):
        return self.call('system', method, params=[])
</code>```

and I call it in this way

```<code>def notifieToMainServer(self):
    url = "http://%s:%s" % (HOST, PORT)
    headers = {'content-type': 'application/json'}
    client = HttpClient(url, "tryton", CREDENTIALS[0], CREDENTIALS[1])
    client.model('main.register',
                 'ActivateService',
                 {'code': self.code,
                  'name': self.nome,
                  'surname': self.cognome,
                  'service_type': 'registry',
                  'service_url': '' # qui andra messa l'url di chimata
                  }
                 )
</code>```

the creatin of the HttpClient works well and I'm able to login, but when I try to call the method ActivateService I recive a 401 responce.

I also add the ActivateService into the rpc class

```<code>@classmethod
def __setup__(cls):
    super(MainRegister, cls).__setup__()
    cls.__rpc__.update({
            'ActivateService': RPC(instantiate=0)})
</code>```

and the function is like

```<code>def ActivateService(self,
                    code,
                    name,
                    surname,
                    service_type,
                    service_url):
    """
        activate the service for the given code and the given service
    """
</code>```

what I did wrong ?

best regards,
Matteo

答:
The Authorization header should be:

'Authorization': : b'Bearer ' + authorization

Title: How to call tryton from jsonrpc

Body:
I'm trying to connect via json-rpc to the trytond isntance using this class

class HttpClient:
    """HTTP Client to make JSON RPC requests to Tryton server.
    User is logged in when an object is created.
    """

    def __init__(self, url, database_name, user, passwd):
        self._url = '{}/{}/'.format(url, database_name)
        self._user = user
        self._passwd = passwd
        self._login()
        self._id = 0

    def get_id(self):
        self._id += 1
        return self._id

    def _login(self):
        """
        Returns list, where
        0 - user id
        1 - session token
        """
        payload = json.dumps({
            'params': [self._user, {'password': self._passwd}],
            'jsonrpc': "2.0",
            'method': 'common.db.login',
            'id': 1,
        })
        headers = {'content-type': 'application/json'}
        result = requests.post(self._url, data=payload, headers=headers)
        if result.status_code in [500, 401]:
            raise Exception(result.text)

        if 'json' in result:
            self._session = result.json()['result']
        else:
            self._session = json.loads(result.text)

        return self._session

    def call(self, prefix, method, params=[[], {}]):
        """RPC Call
        """
        method = '{}.{}'.format(prefix, method)
        payload = json.dumps({
            'params': params,
            'method': method,
            'id': self.get_id(),

        })

        authorization = base64.b64encode(self._session[1].encode('utf-8'))
        headers = {
        'Content-Type': 'application/json',
        'Authorization': b'Session ' + authorization
        }

        response = requests.post(self._url, data=payload, headers=headers)
        if response.status_code in [500, 401]:
            raise Exception(response.text)
        return response.json()

    def model(self, model, method, args=[], kwargs={}):
        return self.call('model.%s' % model, method, [args, kwargs])

    def system(self, method):
        return self.call('system', method, params=[])

and I call it in this way

def notifieToMainServer(self):
    url = "http://%s:%s" % (HOST, PORT)
    headers = {'content-type': 'application/json'}
    client = HttpClient(url, "tryton", CREDENTIALS[0], CREDENTIALS[1])
    client.model('main.register',
                 'ActivateService',
                 {'code': self.code,
                  'name': self.nome,
                  'surname': self.cognome,
                  'service_type': 'registry',
                  'service_url': '' # qui andra messa l'url di chimata
                  }
                 )

the creatin of the HttpClient works well and I'm able to login, but when I try to call the method ActivateService I recive a 401 responce.

I also add the ActivateService into the rpc class

@classmethod
def __setup__(cls):
    super(MainRegister, cls).__setup__()
    cls.__rpc__.update({
            'ActivateService': RPC(instantiate=0)})

and the function is like

def ActivateService(self,
                    code,
                    name,
                    surname,
                    service_type,
                    service_url):
    """
        activate the service for the given code and the given service
    """

what I did wrong ?

best regards,
Matteo