问:
SaveFileDialog producing unrecognized character
My program is supposed to create a text file, but it is adding invisible unrecognized char(s) to the beginning of the text file. I can only see the invisible unrecognized char(s) when scanned. I was able to get the char(s) to go away by opening with word pad instead of notepad, typing a char, and backspacing then saving. That fixed the file, but I need to correct the code causing it. Am I messing up the file type and its adding a random char?

Here is code for dialog and file name/type:

```<code>                Try
            Dim strLocalFilePath As String
            Dim today As String = String.Format("{0:yyyy-MM-dd}", DateTime.Now)

            Dim dlgSaveFile As New SaveFileDialog
            dlgSaveFile.InitialDirectory = CustomSettings.UserSettings.Settings.EligibilityExport_LocalFilePath
            dlgSaveFile.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
            dlgSaveFile.FilterIndex = 1
            dlgSaveFile.OverwritePrompt = True
            dlgSaveFile.FileName = "WWW_EligibilityExport-" & today

            'Dim saveToFolder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "SISCO")
            'If Not (System.IO.Directory.Exists(saveToFolder)) Then
            'System.IO.Directory.CreateDirectory(saveToFolder)
            'End If

            If dlgSaveFile.ShowDialog = System.Windows.Forms.DialogResult.OK Then
                strLocalFilePath = dlgSaveFile.FileName
                CustomSettings.UserSettings.Settings.EligibilityExport_LocalFilePath = My.Computer.FileSystem.GetFileInfo(strLocalFilePath).Directory.FullName
                CustomSettings.UserSettings.Settings.Save()
            Else
                Exit Sub
            End If

            If intSelectedCount > 0 Then
                Me.bsEligibilityExportExportCurrentEmployeeDataSelect.EndEdit()
                If ExportFile(strLocalFilePath) Then
                    MessageBox.Show("Export file successfully created!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information)
                    Me.RefreshData()
                Else
                    MessageBox.Show("Unable to create export file.", "Error...", MessageBoxButtons.OK)
                End If
            Else
                MessageBox.Show("No rows selected for export.", "Error...", MessageBoxButtons.OK)
            End If
</code>```

Here is code for building the text:

```<code>     Dim blnReturn As Boolean = False
        Dim objHeader = CType(CType(Me.dgvExportSummary.CurrentRow.DataBoundItem, DataRowView).Row, dsEmployee.EligibilityExport_ExportCurrentEmployeeData_SelectRow)
        Try
            Dim siscoService As Sisco834Service = New Sisco834Service()

            bsEligibilityExportExportCurrentEmployeeDataSelect.EndEdit()
            Dim isaID As Integer = 100000000
            Dim rand As New Random()
            Dim header As SiscoHeader = New SiscoHeader(Now, isaID)
            header.BeginningStatement.ReferenceIdentification = rand.Next(11110, 99999).ToString()
            Dim footer As SiscoFooter = New SiscoFooter(header)
            Dim document As SiscoDocument = New SiscoDocument()
            document.Header = header
            document.Footer = footer
            For Each dgvr As DataGridViewRow In Me.dgvExportSummary.Rows
                Dim objRowExportSummary = CType(CType(dgvr.DataBoundItem, DataRowView).Row, dsEmployee.EligibilityExport_ExportCurrentEmployeeData_SelectRow)
                If objRowExportSummary.Selected Then
                    Dim eligibilityExport As EligibilityExportCurrent = New EligibilityExportCurrent()
                    With eligibilityExport
                        .Address1 = If(objRowExportSummary.IsAddress1Null, String.Empty, objRowExportSummary.Address1)
                        .City = If(objRowExportSummary.IsCityNull, String.Empty, objRowExportSummary.City)
                        .DepartmentName = If(objRowExportSummary.IsDepartmentNameNull, String.Empty, objRowExportSummary.DepartmentName)
                        .DivisionName = If(objRowExportSummary.IsDivisionNameNull, String.Empty, objRowExportSummary.DivisionName)
                        .DivisionNumber = If(objRowExportSummary.IsDivisionNumberNull, Nothing, objRowExportSummary.DivisionNumber)
                        .EmployeeID = objRowExportSummary.EmployeeID
                        .ExportRowData = If(objRowExportSummary.IsExportRowDataNull, String.Empty, objRowExportSummary.ExportRowData)
                        .FirstName = objRowExportSummary.FirstName
                        .Header = If(objRowExportSummary.IsHeaderNull, String.Empty, objRowExportSummary.Header)
                        .HireDate = If(objRowExportSummary.IsHireDateNull, Date.MinValue, objRowExportSummary.HireDate)
                        .LastName = objRowExportSummary.LastName
                        .MiddleName = If(objRowExportSummary.IsMiddleNameNull, String.Empty, objRowExportSummary.MiddleName)
                        .Selected = If(objRowExportSummary.IsSelectedNull, True, objRowExportSummary.Selected)
                        .State = If(objRowExportSummary.IsStateNull, String.Empty, objRowExportSummary.State)
                        .WorkcenterName = If(objRowExportSummary.IsWorkcenterNameNull, String.Empty, objRowExportSummary.WorkcenterName)
                        .ZipCode = If(objRowExportSummary.IsZipCodeNull, String.Empty, objRowExportSummary.ZipCode)
                    End With
                    document.Subscribers.Add(siscoService.ConvertEligibilityExportCurrentToSiscoSubscriber(eligibilityExport, footer))
                End If
            Next
            Dim str As String = siscoService.CreateSiscoDocumentString(document)
            My.Computer.FileSystem.WriteAllText(strLocalFilePath, str + Environment.NewLine + Environment.NewLine, True)
            blnReturn = True
</code>```

答: Thank you @Chase Rocker ... Here is his answer: I'm guessing it's a Byte Order Mark (BOM). The WriteAllText method adds a BOM if no encoding is specified. After your True param, try adding this encoding param: New System.Text.UTF8Encoding(False) – Chase Rocker 18 mins ago</p>

Body:
My program is supposed to create a text file, but it is adding invisible unrecognized char(s) to the beginning of the text file. I can only see the invisible unrecognized char(s) when scanned. I was able to get the char(s) to go away by opening with word pad instead of notepad, typing a char, and backspacing then saving. That fixed the file, but I need to correct the code causing it. Am I messing up the file type and its adding a random char?

Here is code for dialog and file name/type:

                Try
            Dim strLocalFilePath As String
            Dim today As String = String.Format("{0:yyyy-MM-dd}", DateTime.Now)

            Dim dlgSaveFile As New SaveFileDialog
            dlgSaveFile.InitialDirectory = CustomSettings.UserSettings.Settings.EligibilityExport_LocalFilePath
            dlgSaveFile.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
            dlgSaveFile.FilterIndex = 1
            dlgSaveFile.OverwritePrompt = True
            dlgSaveFile.FileName = "WWW_EligibilityExport-" & today

            'Dim saveToFolder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "SISCO")
            'If Not (System.IO.Directory.Exists(saveToFolder)) Then
            'System.IO.Directory.CreateDirectory(saveToFolder)
            'End If

            If dlgSaveFile.ShowDialog = System.Windows.Forms.DialogResult.OK Then
                strLocalFilePath = dlgSaveFile.FileName
                CustomSettings.UserSettings.Settings.EligibilityExport_LocalFilePath = My.Computer.FileSystem.GetFileInfo(strLocalFilePath).Directory.FullName
                CustomSettings.UserSettings.Settings.Save()
            Else
                Exit Sub
            End If

            If intSelectedCount > 0 Then
                Me.bsEligibilityExportExportCurrentEmployeeDataSelect.EndEdit()
                If ExportFile(strLocalFilePath) Then
                    MessageBox.Show("Export file successfully created!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information)
                    Me.RefreshData()
                Else
                    MessageBox.Show("Unable to create export file.", "Error...", MessageBoxButtons.OK)
                End If
            Else
                MessageBox.Show("No rows selected for export.", "Error...", MessageBoxButtons.OK)
            End If

Here is code for building the text:

     Dim blnReturn As Boolean = False
        Dim objHeader = CType(CType(Me.dgvExportSummary.CurrentRow.DataBoundItem, DataRowView).Row, dsEmployee.EligibilityExport_ExportCurrentEmployeeData_SelectRow)
        Try
            Dim siscoService As Sisco834Service = New Sisco834Service()

            bsEligibilityExportExportCurrentEmployeeDataSelect.EndEdit()
            Dim isaID As Integer = 100000000
            Dim rand As New Random()
            Dim header As SiscoHeader = New SiscoHeader(Now, isaID)
            header.BeginningStatement.ReferenceIdentification = rand.Next(11110, 99999).ToString()
            Dim footer As SiscoFooter = New SiscoFooter(header)
            Dim document As SiscoDocument = New SiscoDocument()
            document.Header = header
            document.Footer = footer
            For Each dgvr As DataGridViewRow In Me.dgvExportSummary.Rows
                Dim objRowExportSummary = CType(CType(dgvr.DataBoundItem, DataRowView).Row, dsEmployee.EligibilityExport_ExportCurrentEmployeeData_SelectRow)
                If objRowExportSummary.Selected Then
                    Dim eligibilityExport As EligibilityExportCurrent = New EligibilityExportCurrent()
                    With eligibilityExport
                        .Address1 = If(objRowExportSummary.IsAddress1Null, String.Empty, objRowExportSummary.Address1)
                        .City = If(objRowExportSummary.IsCityNull, String.Empty, objRowExportSummary.City)
                        .DepartmentName = If(objRowExportSummary.IsDepartmentNameNull, String.Empty, objRowExportSummary.DepartmentName)
                        .DivisionName = If(objRowExportSummary.IsDivisionNameNull, String.Empty, objRowExportSummary.DivisionName)
                        .DivisionNumber = If(objRowExportSummary.IsDivisionNumberNull, Nothing, objRowExportSummary.DivisionNumber)
                        .EmployeeID = objRowExportSummary.EmployeeID
                        .ExportRowData = If(objRowExportSummary.IsExportRowDataNull, String.Empty, objRowExportSummary.ExportRowData)
                        .FirstName = objRowExportSummary.FirstName
                        .Header = If(objRowExportSummary.IsHeaderNull, String.Empty, objRowExportSummary.Header)
                        .HireDate = If(objRowExportSummary.IsHireDateNull, Date.MinValue, objRowExportSummary.HireDate)
                        .LastName = objRowExportSummary.LastName
                        .MiddleName = If(objRowExportSummary.IsMiddleNameNull, String.Empty, objRowExportSummary.MiddleName)
                        .Selected = If(objRowExportSummary.IsSelectedNull, True, objRowExportSummary.Selected)
                        .State = If(objRowExportSummary.IsStateNull, String.Empty, objRowExportSummary.State)
                        .WorkcenterName = If(objRowExportSummary.IsWorkcenterNameNull, String.Empty, objRowExportSummary.WorkcenterName)
                        .ZipCode = If(objRowExportSummary.IsZipCodeNull, String.Empty, objRowExportSummary.ZipCode)
                    End With
                    document.Subscribers.Add(siscoService.ConvertEligibilityExportCurrentToSiscoSubscriber(eligibilityExport, footer))
                End If
            Next
            Dim str As String = siscoService.CreateSiscoDocumentString(document)
            My.Computer.FileSystem.WriteAllText(strLocalFilePath, str + Environment.NewLine + Environment.NewLine, True)
            blnReturn = True


来源: stackexchange

问:
Error with bmp file-Exception thrown at 0x0FDD053F (ucrtbased.dll) in project 2017.1.exe: 0xC0000005: Access violation writing location 0xCDCDCDCD
In this code I tried to get the first byte in each pixel, from a bmp file where the RGB values for each pixel are the same (like ff ff ff), and put these values into a matrix for further manipulations. The debugging process was terminated when the debugger reached "getting the first byte from each pixel"
and "Exception thrown at 0x0FDD053F (ucrtbased.dll) in project 2017.1.exe: 0xC0000005: Access violation writing location 0xCDCDCDCD" appeared. What is the problem?(this is the first time I am working with bmp)  Thanks for helping!</p>

```<code>#include <stdio.h>
#include <stdlib.h>

main() {
    int width, height, w_count, h_count, padding;
    int **pix_mat;
    int a;
    FILE * dust_pic;
    fopen_s(&dust_pic, "d2.bmp", "rb");
    if (!dust_pic)
        printf_s("not found");
    fseek(dust_pic, 18, SEEK_SET);
    fread(&width, sizeof(int), 1, dust_pic);// getting width
    fread(&height, sizeof(int), 1, dust_pic);// getting height
    // FIND PADDING
    a = width;
    if (a % 4 != 0)
        padding = 4 - (a % 4);
    else
    padding = 0;

    //making matrix for pixels
    pix_mat = (int**)malloc(sizeof(int*)*height);
    for (h_count = 0; h_count < height; h_count++)
        pix_mat[h_count] = (int*)malloc(sizeof(int)*width);

    fseek(dust_pic, 54, SEEK_SET);
    // getting the first byte from each pixel
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
        {
            fread(pix_mat[w_count][h_count], sizeof(char), 1, dust_pic);
            fseek(dust_pic, 2, SEEK_CUR);
        }
        fseek(dust_pic, padding, SEEK_CUR);
    }
    fclose(dust_pic);
    // print the matrix.
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
            printf_s("[%d],[%d]=%d  ", w_count, h_count, pix_mat[w_count][h_count]);
        printf("\n");
    }
    // free array
    for (h_count = 0; h_count < height; h_count++)
        free(pix_mat[h_count]);
    free(pix_mat);
}
</code>```

答:
the following proposed code:

cleanly compiles

properly checks for errors

properly cleans up, before exiting after any error events

properly reads the right size of data  from the file and saves that data into a properly declared array

properly references the rows and columns of the pixel matrix in memory

does not correct the assumptions about pixel width, offset to the pixels in the file, etc.

and now the code

```<code>#include <stdio.h>  // fopen(), fclose(), perror(), fseek(), SEEK_SET
#include <stdlib.h> // exit(), EXIT_FAILURE, malloc(), calloc(), free()

// prototypes
void cleanup( FILE *dust_pic, size_t height, char **pix_mat );

int main( void )
{
    size_t width, height, w_count, h_count;
    long padding;
    char **pix_mat;

    FILE * dust_pic;
    dust_pic = fopen("d2.bmp", "rb");
    if (!dust_pic)
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen_s successful

    fseek(dust_pic, 18, SEEK_SET);
    // check for error

    if( 1 != fread(&width, sizeof(int), 1, dust_pic) )// getting width
    {
        perror( "fread for width of image, in pixels, failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, fread successful

    if( 1 != fread(&height, sizeof(int), 1, dust_pic) )// getting height
    {
        perror( "fread for height of image, in pixels, failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, fread successful

    // calculate PADDING
    if ( width % 4 != 0)
        padding = (long)(4 - (width % 4));
    else
        padding = 0;

    //making matrix for pixels
    pix_mat = calloc(height, sizeof(char*));
    // check for malloc status
    if( !pix_mat )
    {
        perror( "calloc for array of pointers to char failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    for (h_count = 0; h_count < height; h_count++)
    {
        pix_mat[h_count] = malloc(sizeof(char)*width);
        // check for malloc status
        if( !pix_mat[h_count] )
        {
            perror( "malloc failed" );
            fclose( dust_pic );
            exit( EXIT_FAILURE );
        }

        // implied else, malloc successful
    }

    // jump to beginning of pixel data in file
    if( -1 == fseek(dust_pic, 54, SEEK_SET) )
    {
        perror( "fseek to start of pixel data failed" );
        cleanup( dust_pic, height, pix_mat );
        exit( EXIT_FAILURE );
    }

    // implied else, fseek successful

    // get the first byte (red) from each pixel
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
        {
            if( 1 != fread( &((pix_mat[h_count])[w_count]), sizeof(char), 1, dust_pic) )
            {
                perror( "fread of 'red' pixel value failed" );
                cleanup( dust_pic, height, pix_mat );
                exit( EXIT_FAILURE );
            }

            // implied else, fread successful

            if( -1 == fseek(dust_pic, 2, SEEK_CUR) )
            {
                perror( "fseek to skip green/blue pixels failed" );
                cleanup( dust_pic, height, pix_mat );
                exit( EXIT_FAILURE );
            }

            // implied else, fseek successful
        }

        if( -1 == fseek(dust_pic, padding, SEEK_CUR) )
        {
            perror( "fseek to skip padding failed" );
            cleanup( dust_pic, height, pix_mat );
            exit( EXIT_FAILURE );
        }

        // implied else, fseek successful
    }

    // print the matrix.
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
            printf("[%lu],[%lu]=%3.3d  ", h_count, w_count, (pix_mat[h_count])[w_count]);
        printf("\n");
    }

    cleanup( dust_pic, height, pix_mat );
} // end function: main

void cleanup( FILE *dust_pic, size_t height, char **pix_mat )
{
    // free array
    for (size_t h_count = 0; h_count < height; h_count++)
        free(pix_mat[h_count]);
    free(pix_mat);

    fclose( dust_pic );
} // end function: cleanup
</code>```

ContentLicense: CC BY-SA 3.0

Body:
In this code I tried to get the first byte in each pixel, from a bmp file where the RGB values for each pixel are the same (like ff ff ff), and put these values into a matrix for further manipulations. The debugging process was terminated when the debugger reached "getting the first byte from each pixel"
and "Exception thrown at 0x0FDD053F (ucrtbased.dll) in project 2017.1.exe: 0xC0000005: Access violation writing location 0xCDCDCDCD" appeared. What is the problem?(this is the first time I am working with bmp)  Thanks for helping!

#include <stdio.h>
#include <stdlib.h>

main() {
    int width, height, w_count, h_count, padding;
    int **pix_mat;
    int a;
    FILE * dust_pic;
    fopen_s(&dust_pic, "d2.bmp", "rb");
    if (!dust_pic)
        printf_s("not found");
    fseek(dust_pic, 18, SEEK_SET);
    fread(&width, sizeof(int), 1, dust_pic);// getting width
    fread(&height, sizeof(int), 1, dust_pic);// getting height
    // FIND PADDING
    a = width;
    if (a % 4 != 0)
        padding = 4 - (a % 4);
    else
    padding = 0;

    //making matrix for pixels
    pix_mat = (int**)malloc(sizeof(int*)*height);
    for (h_count = 0; h_count < height; h_count++)
        pix_mat[h_count] = (int*)malloc(sizeof(int)*width);

    fseek(dust_pic, 54, SEEK_SET);
    // getting the first byte from each pixel
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
        {
            fread(pix_mat[w_count][h_count], sizeof(char), 1, dust_pic);
            fseek(dust_pic, 2, SEEK_CUR);
        }
        fseek(dust_pic, padding, SEEK_CUR);
    }
    fclose(dust_pic);
    // print the matrix.
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
            printf_s("[%d],[%d]=%d  ", w_count, h_count, pix_mat[w_count][h_count]);
        printf("\n");
    }
    // free array
    for (h_count = 0; h_count < height; h_count++)
        free(pix_mat[h_count]);
    free(pix_mat);
}

Body:
the following proposed code:

cleanly compiles

properly checks for errors

properly cleans up, before exiting after any error events

properly reads the right size of data  from the file and saves that data into a properly declared array

properly references the rows and columns of the pixel matrix in memory

does not correct the assumptions about pixel width, offset to the pixels in the file, etc.

and now the code

#include <stdio.h>  // fopen(), fclose(), perror(), fseek(), SEEK_SET
#include <stdlib.h> // exit(), EXIT_FAILURE, malloc(), calloc(), free()

// prototypes
void cleanup( FILE *dust_pic, size_t height, char **pix_mat );

int main( void )
{
    size_t width, height, w_count, h_count;
    long padding;
    char **pix_mat;

    FILE * dust_pic;
    dust_pic = fopen("d2.bmp", "rb");
    if (!dust_pic)
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen_s successful

    fseek(dust_pic, 18, SEEK_SET);
    // check for error

    if( 1 != fread(&width, sizeof(int), 1, dust_pic) )// getting width
    {
        perror( "fread for width of image, in pixels, failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, fread successful

    if( 1 != fread(&height, sizeof(int), 1, dust_pic) )// getting height
    {
        perror( "fread for height of image, in pixels, failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, fread successful

    // calculate PADDING
    if ( width % 4 != 0)
        padding = (long)(4 - (width % 4));
    else
        padding = 0;

    //making matrix for pixels
    pix_mat = calloc(height, sizeof(char*));
    // check for malloc status
    if( !pix_mat )
    {
        perror( "calloc for array of pointers to char failed" );
        fclose( dust_pic );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    for (h_count = 0; h_count < height; h_count++)
    {
        pix_mat[h_count] = malloc(sizeof(char)*width);
        // check for malloc status
        if( !pix_mat[h_count] )
        {
            perror( "malloc failed" );
            fclose( dust_pic );
            exit( EXIT_FAILURE );
        }

        // implied else, malloc successful
    }

    // jump to beginning of pixel data in file
    if( -1 == fseek(dust_pic, 54, SEEK_SET) )
    {
        perror( "fseek to start of pixel data failed" );
        cleanup( dust_pic, height, pix_mat );
        exit( EXIT_FAILURE );
    }

    // implied else, fseek successful

    // get the first byte (red) from each pixel
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
        {
            if( 1 != fread( &((pix_mat[h_count])[w_count]), sizeof(char), 1, dust_pic) )
            {
                perror( "fread of 'red' pixel value failed" );
                cleanup( dust_pic, height, pix_mat );
                exit( EXIT_FAILURE );
            }

            // implied else, fread successful

            if( -1 == fseek(dust_pic, 2, SEEK_CUR) )
            {
                perror( "fseek to skip green/blue pixels failed" );
                cleanup( dust_pic, height, pix_mat );
                exit( EXIT_FAILURE );
            }

            // implied else, fseek successful
        }

        if( -1 == fseek(dust_pic, padding, SEEK_CUR) )
        {
            perror( "fseek to skip padding failed" );
            cleanup( dust_pic, height, pix_mat );
            exit( EXIT_FAILURE );
        }

        // implied else, fseek successful
    }

    // print the matrix.
    for (h_count = 0; h_count < height; h_count++)
    {
        for (w_count = 0; w_count < width; w_count++)
            printf("[%lu],[%lu]=%3.3d  ", h_count, w_count, (pix_mat[h_count])[w_count]);
        printf("\n");
    }

    cleanup( dust_pic, height, pix_mat );
} // end function: main

void cleanup( FILE *dust_pic, size_t height, char **pix_mat )
{
    // free array
    for (size_t h_count = 0; h_count < height; h_count++)
        free(pix_mat[h_count]);
    free(pix_mat);

    fclose( dust_pic );
} // end function: cleanup


问:
Bootstrap: hover over the tooltip text to click a link
I am using the tooltip tool in Bootstrap 3.x in my web app to show helpful info. It works in this way:

```<code>$('[data-toggle="tooltip"]').tooltip({
        'animation': true,
        'placement': 'top',
        'trigger': 'hover',
        'html':true,
        'container': 'body'
});
</code>```

Please note that I have to use hover to trigger the tooltip. Now I need to add a new tooltip and its tooltip text contains a HTML link. A visitor should be able to mouse over the tooltip text to click the link.

The problem is that when a visitor moves his mouse, the tooltip text disappears before he can reach the tooltip text area.

答:
This is using tooltip now.  See if this better answer your question.

var originalLeave = $.fn.tooltip.Constructor.prototype.leave;
$.fn.tooltip.Constructor.prototype.leave = function(obj) {
  var self = obj instanceof this.constructor ?
    obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
  var container, timeout;

  originalLeave.call(this, obj);

  if (obj.currentTarget) {
    container = $(obj.currentTarget).siblings('.tooltip')
    timeout = self.timeout;
    container.one('mouseenter', function() {
      //We entered the actual popover – call off the dogs
      clearTimeout(timeout);
      //Let's monitor popover content instead
      container.one('mouseleave', function() {
        $.fn.tooltip.Constructor.prototype.leave.call(self, self);
      });
    })
  }
};

$('body').tooltip({
  selector: '[data-toggle]',
  trigger: 'click hover',
  placement: 'auto',
  delay: {
    show: 50,
    hide: 400
  }
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<p>
  <button class='btn btn-primary btn-large' data-toggle="tooltip" data-html="true" title="click me, I'll try not to disappear">hover here</button>
</p></code>```

Body:
I am using the tooltip tool in Bootstrap 3.x in my web app to show helpful info. It works in this way:

$('[data-toggle="tooltip"]').tooltip({
        'animation': true,
        'placement': 'top',
        'trigger': 'hover',
        'html':true,
        'container': 'body'
});

Please note that I have to use hover to trigger the tooltip. Now I need to add a new tooltip and its tooltip text contains a HTML link. A visitor should be able to mouse over the tooltip text to click the link.

The problem is that when a visitor moves his mouse, the tooltip text disappears before he can reach the tooltip text area.

Body:
This is using tooltip now.  See if this better answer your question.

var originalLeave = $.fn.tooltip.Constructor.prototype.leave;
$.fn.tooltip.Constructor.prototype.leave = function(obj) {
  var self = obj instanceof this.constructor ?
    obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
  var container, timeout;

  originalLeave.call(this, obj);

  if (obj.currentTarget) {
    container = $(obj.currentTarget).siblings('.tooltip')
    timeout = self.timeout;
    container.one('mouseenter', function() {
      //We entered the actual popover – call off the dogs
      clearTimeout(timeout);
      //Let's monitor popover content instead
      container.one('mouseleave', function() {
        $.fn.tooltip.Constructor.prototype.leave.call(self, self);
      });
    })
  }
};

$('body').tooltip({
  selector: '[data-toggle]',
  trigger: 'click hover',
  placement: 'auto',
  delay: {
    show: 50,
    hide: 400
  }
});

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<p>
  <button class='btn btn-primary btn-large' data-toggle="tooltip" data-html="true" title="<a href='http://www.wojt.eu' target='blank' >click me, I'll try not to disappear</a>">hover here</button>
</p>


问:
Android SyncAdapter doesn't syncs on my device Samsung S6 Edge Plus Nougat(syncs periodically on API<=23)
I have a problem using my SyncAdapter. The weirdest thing about it, is it was working earlier, but now sync only works if i call it manually.

It also not works on emulator (API 24)

Here is my code of the sync adapter:

```<code> public class SmogAppSyncAdapter extends AbstractThreadedSyncAdapter {

private static final String LOG_TAG = SmogAppSyncAdapter.class.getSimpleName();

public static final int SYNC_INTERVAL =  60; // 60 * 60 = 1h to the nearest 20min.
public static final int SYNC_FLEXTIME = SYNC_INTERVAL / 3;
public static final int POLLUTION_DISTANCE = 10000; //preferred distance between prefs location and nearest measurement point
private static final int POLLUTION_NOTIFICATION_ID = 0;

private ContentResolver mContentResolver;
private SharedPreferences prefs;
private Context syncContext;
private int prefsPollutionLevel;
private double prefsHomeLocationLatitude;
private double prefsHomeLocationLongitude;
private boolean prefsNewMessageNotification;
private int currentApiPollutionLevel;
private Float currentApiPollutionLevelLatitude;
private Float currentApiPollutionLevelLongitude;

/**
 * Set up the sync adapter
 */
SmogAppSyncAdapter(Context context, boolean autoInitialize) {
    super(context, autoInitialize);
    /*
     * If your app uses a content resolver, get an instance of it
     * from the incoming Context
     */
    mContentResolver = context.getContentResolver();
    prefs = PreferenceManager.getDefaultSharedPreferences(context);
    syncContext = context;
    prefsHomeLocationLatitude = prefs.getFloat(syncContext.getResources().getString(R.string.pref_key_home_latitude), 0f);
    prefsHomeLocationLongitude = prefs.getFloat(syncContext.getResources().getString(R.string.pref_key_home_longitude), 0f);
    prefsNewMessageNotification = prefs.getBoolean(syncContext.getResources().getString(R.string.pref_key_notification_new_message), true);
    prefsPollutionLevel = Integer.valueOf(prefs.getString(syncContext.getResources().getString(R.string.pref_key_pollution_level_list), "0"));
}

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {

    // fetching remote data and insert some stuff

    Log.d(LOG_TAG, "onPerformSync was called");

}

/**
 * Helper method to schedule the sync adapter periodic execution
 */
private static void configurePeriodicSync(Context context, int syncInterval, int flexTime) {
    Account account = getSyncAccount(context);
    String authority = context.getString(R.string.content_authority);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      //   we can enable inexact timers in our periodic sync
        SyncRequest request = new SyncRequest.Builder().
                syncPeriodic(syncInterval, flexTime).
                setSyncAdapter(account, authority).
                setExtras(new Bundle()).build();
        ContentResolver.requestSync(request);
    } else {
    ContentResolver.addPeriodicSync(account,
            authority, new Bundle(), syncInterval);
    }
}

/**
 * Helper method to have the sync adapter sync immediately
 *
 * @param context The context used to access the account service
 */
private static void syncImmediately(Context context) {
    Bundle bundle = new Bundle();
    bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
    bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
    ContentResolver.requestSync(getSyncAccount(context),
            context.getString(R.string.content_authority), bundle);
}

/**
 * Helper method to get the fake account to be used with SyncAdapter, or make a new one
 * if the fake account doesn't exist yet.  If we make a new account, we call the
 * onAccountCreated method so we can initialize things.
 *
 * @param context The context used to access the account service
 * @return a fake account.
 */
public static Account getSyncAccount(Context context) {
    Log.d(LOG_TAG, "getSyncAccount");
    // Get an instance of the Android account manager
    AccountManager accountManager =
            (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);

    // Create the account type and default account
    Account newAccount = new Account(
            context.getString(R.string.app_name), context.getString(R.string.sync_account_type));

    // If the password doesn't exist, the account doesn't exist
    if (null == accountManager.getPassword(newAccount)) {

    /*
     * Add the account and account type, no password or user data
     * If successful, return the Account object, otherwise report an error.
     */
        if (!accountManager.addAccountExplicitly(newAccount, "", null)) {
            Log.d(LOG_TAG, "return null");
            return null;
        }
        /*
         * If you don't set android:syncable="true" in
         * in your <provider> element in the manifest,
         * then call ContentResolver.setIsSyncable(account, AUTHORITY, 1)
         * here.
         */

        onAccountCreated(newAccount, context);
    }
    else {
        Log.d(LOG_TAG, "If the password doesn't exist, the account doesn't exist");
    }
    Log.d(LOG_TAG, "Account name: " + newAccount.name);
    return newAccount;
}

private static void onAccountCreated(Account newAccount, Context context) {
    Log.d(LOG_TAG, "onAccountCreated");
    /*
     * Since we've created an account
     */
    SmogAppSyncAdapter.configurePeriodicSync(context, SYNC_INTERVAL, SYNC_FLEXTIME);

    /*
     * Without calling setSyncAutomatically, our periodic sync will not be enabled.
     */
    ContentResolver.setIsSyncable(newAccount, context.getString(R.string.content_authority), 1);
    ContentResolver.setSyncAutomatically(newAccount, context.getString(R.string.content_authority), true);

    /*
     * Finally, let's do a sync to get things started
     */
  //  syncImmediately(context);
}

public static void initializeSyncAdapter(Context context) {
    Log.d(LOG_TAG, "inside initializeSyncAdapter");
    getSyncAccount(context);
}
</code>```

}

My service:

```<code>public class SmogAppSyncService extends Service {

private static SmogAppSyncAdapter sSyncAdapter = null;
private static final Object sSyncAdapterLock = new Object();

@Override
public void onCreate() {
    synchronized (sSyncAdapterLock) {
        sSyncAdapter = new SmogAppSyncAdapter(getApplicationContext(), true);
    }
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return sSyncAdapter.getSyncAdapterBinder();
}
</code>```

}

In my manifest i added those:

```<code> <service android:name=".services.sync.SmogAppAuthenticatorService">
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator" />
        </intent-filter>

        <meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/authenticator" />
    </service>
    <service
        android:name=".services.sync.SmogAppSyncService"
        android:exported="true"
        android:process=":sync">
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>

        <meta-data
            android:name="android.content.SyncAdapter"
            android:resource="@xml/syncadapter" />
    </service>
</code>```

and permissions:

```<code>    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
</code>```

Here are my other xml files:

```<code><?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="@string/content_authority"
android:accountType="@string/sync_account_type"
android:userVisible="false"
android:supportsUploading="false"
android:allowParallelSyncs="false"
android:isAlwaysSyncable="true" />
</code>```

Authetnicator.xml

```<code><?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="@string/sync_account_type"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:smallIcon="@mipmap/ic_launcher" />
</code>```

I can provide more details, if it will be helpful. I really stuck with this problem and checked some answers in stackoverflow. Doesn't really helped me. Is any way to get this work? The periodic sync works on emulator but not on real device.

UPDATE: I've read about Doze Mode which could be the cause, but it is rather not in my case or i've just configured something wrong.
Basically Doze Mode with its battery optimalization can disable some background tasks on device.

答:
From SyncRequest.Builder#syncPeriodic(long, long) javadoc:

```<code> /**
     * Build a periodic sync.
     ...
     * @param pollFrequency the amount of time in seconds that you wish
     *            to elapse between periodic syncs. A minimum period of 1 hour is enforced.
     ...
     */
    public Builder syncPeriodic(long pollFrequency, long beforeSeconds) {
        ...
    }
</code>```

Note that it states that a minimum periodic sync timeout of 1 hour is enforced. That's probably your issue.

But since when? I haven't heard of such a long timeout before. Let's dig into it.

I ran the following commands:

```<code>$ cd ~/aosp/frameworks/base
$ find ./ -name SyncRequest.java | xargs git blame | grep "A minimum period of 1 hour is enforced"
</code>```

And get this result:

```<code>e96c3b7eff52 (Shreyas Basarge  2016-01-29 19:25:51 +0000 310)          *            to elapse between periodic syncs. A minimum period of 1 hour is enforced.
</code>```

Looks like the commit is from January 2016. This explains why it works on API 19 but not on 25.

I further verified that this commit added the code that increased the minimum timeout from 60 seconds to 1 hour.

And then you might ask why on earth would Google devs change the semantics of working API on which many apps rely without a proper notification to developers? And the answer is as usual - because they can.

Body:
I have a problem using my SyncAdapter. The weirdest thing about it, is it was working earlier, but now sync only works if i call it manually.

It also not works on emulator (API 24)

Here is my code of the sync adapter:

 public class SmogAppSyncAdapter extends AbstractThreadedSyncAdapter {

private static final String LOG_TAG = SmogAppSyncAdapter.class.getSimpleName();

public static final int SYNC_INTERVAL =  60; // 60 * 60 = 1h to the nearest 20min.
public static final int SYNC_FLEXTIME = SYNC_INTERVAL / 3;
public static final int POLLUTION_DISTANCE = 10000; //preferred distance between prefs location and nearest measurement point
private static final int POLLUTION_NOTIFICATION_ID = 0;

private ContentResolver mContentResolver;
private SharedPreferences prefs;
private Context syncContext;
private int prefsPollutionLevel;
private double prefsHomeLocationLatitude;
private double prefsHomeLocationLongitude;
private boolean prefsNewMessageNotification;
private int currentApiPollutionLevel;
private Float currentApiPollutionLevelLatitude;
private Float currentApiPollutionLevelLongitude;

/**
 * Set up the sync adapter
 */
SmogAppSyncAdapter(Context context, boolean autoInitialize) {
    super(context, autoInitialize);
    /*
     * If your app uses a content resolver, get an instance of it
     * from the incoming Context
     */
    mContentResolver = context.getContentResolver();
    prefs = PreferenceManager.getDefaultSharedPreferences(context);
    syncContext = context;
    prefsHomeLocationLatitude = prefs.getFloat(syncContext.getResources().getString(R.string.pref_key_home_latitude), 0f);
    prefsHomeLocationLongitude = prefs.getFloat(syncContext.getResources().getString(R.string.pref_key_home_longitude), 0f);
    prefsNewMessageNotification = prefs.getBoolean(syncContext.getResources().getString(R.string.pref_key_notification_new_message), true);
    prefsPollutionLevel = Integer.valueOf(prefs.getString(syncContext.getResources().getString(R.string.pref_key_pollution_level_list), "0"));
}

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {

    // fetching remote data and insert some stuff

    Log.d(LOG_TAG, "onPerformSync was called");

}

/**
 * Helper method to schedule the sync adapter periodic execution
 */
private static void configurePeriodicSync(Context context, int syncInterval, int flexTime) {
    Account account = getSyncAccount(context);
    String authority = context.getString(R.string.content_authority);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      //   we can enable inexact timers in our periodic sync
        SyncRequest request = new SyncRequest.Builder().
                syncPeriodic(syncInterval, flexTime).
                setSyncAdapter(account, authority).
                setExtras(new Bundle()).build();
        ContentResolver.requestSync(request);
    } else {
    ContentResolver.addPeriodicSync(account,
            authority, new Bundle(), syncInterval);
    }
}

/**
 * Helper method to have the sync adapter sync immediately
 *
 * @param context The context used to access the account service
 */
private static void syncImmediately(Context context) {
    Bundle bundle = new Bundle();
    bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
    bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
    ContentResolver.requestSync(getSyncAccount(context),
            context.getString(R.string.content_authority), bundle);
}

/**
 * Helper method to get the fake account to be used with SyncAdapter, or make a new one
 * if the fake account doesn't exist yet.  If we make a new account, we call the
 * onAccountCreated method so we can initialize things.
 *
 * @param context The context used to access the account service
 * @return a fake account.
 */
public static Account getSyncAccount(Context context) {
    Log.d(LOG_TAG, "getSyncAccount");
    // Get an instance of the Android account manager
    AccountManager accountManager =
            (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);

    // Create the account type and default account
    Account newAccount = new Account(
            context.getString(R.string.app_name), context.getString(R.string.sync_account_type));

    // If the password doesn't exist, the account doesn't exist
    if (null == accountManager.getPassword(newAccount)) {

    /*
     * Add the account and account type, no password or user data
     * If successful, return the Account object, otherwise report an error.
     */
        if (!accountManager.addAccountExplicitly(newAccount, "", null)) {
            Log.d(LOG_TAG, "return null");
            return null;
        }
        /*
         * If you don't set android:syncable="true" in
         * in your <provider> element in the manifest,
         * then call ContentResolver.setIsSyncable(account, AUTHORITY, 1)
         * here.
         */

        onAccountCreated(newAccount, context);
    }
    else {
        Log.d(LOG_TAG, "If the password doesn't exist, the account doesn't exist");
    }
    Log.d(LOG_TAG, "Account name: " + newAccount.name);
    return newAccount;
}

private static void onAccountCreated(Account newAccount, Context context) {
    Log.d(LOG_TAG, "onAccountCreated");
    /*
     * Since we've created an account
     */
    SmogAppSyncAdapter.configurePeriodicSync(context, SYNC_INTERVAL, SYNC_FLEXTIME);

    /*
     * Without calling setSyncAutomatically, our periodic sync will not be enabled.
     */
    ContentResolver.setIsSyncable(newAccount, context.getString(R.string.content_authority), 1);
    ContentResolver.setSyncAutomatically(newAccount, context.getString(R.string.content_authority), true);

    /*
     * Finally, let's do a sync to get things started
     */
  //  syncImmediately(context);
}

public static void initializeSyncAdapter(Context context) {
    Log.d(LOG_TAG, "inside initializeSyncAdapter");
    getSyncAccount(context);
}

}

My service:

public class SmogAppSyncService extends Service {

private static SmogAppSyncAdapter sSyncAdapter = null;
private static final Object sSyncAdapterLock = new Object();

@Override
public void onCreate() {
    synchronized (sSyncAdapterLock) {
        sSyncAdapter = new SmogAppSyncAdapter(getApplicationContext(), true);
    }
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return sSyncAdapter.getSyncAdapterBinder();
}

}

In my manifest i added those:

 <service android:name=".services.sync.SmogAppAuthenticatorService">
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator" />
        </intent-filter>

        <meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/authenticator" />
    </service>
    <service
        android:name=".services.sync.SmogAppSyncService"
        android:exported="true"
        android:process=":sync">
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>

        <meta-data
            android:name="android.content.SyncAdapter"
            android:resource="@xml/syncadapter" />
    </service>

and permissions:

    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />

Here are my other xml files:

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="@string/content_authority"
android:accountType="@string/sync_account_type"
android:userVisible="false"
android:supportsUploading="false"
android:allowParallelSyncs="false"
android:isAlwaysSyncable="true" />

Authetnicator.xml

<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="@string/sync_account_type"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:smallIcon="@mipmap/ic_launcher" />

I can provide more details, if it will be helpful. I really stuck with this problem and checked some answers in stackoverflow. Doesn't really helped me. Is any way to get this work? The periodic sync works on emulator but not on real device.

UPDATE: I've read about Doze Mode which could be the cause, but it is rather not in my case or i've just configured something wrong.
Basically Doze Mode with its battery optimalization can disable some background tasks on device.

Body:
From SyncRequest.Builder#syncPeriodic(long, long) javadoc:

 /**
     * Build a periodic sync.
     ...
     * @param pollFrequency the amount of time in seconds that you wish
     *            to elapse between periodic syncs. A minimum period of 1 hour is enforced.
     ...
     */
    public Builder syncPeriodic(long pollFrequency, long beforeSeconds) {
        ...
    }

Note that it states that a minimum periodic sync timeout of 1 hour is enforced. That's probably your issue.

But since when? I haven't heard of such a long timeout before. Let's dig into it.

I ran the following commands:

$ cd ~/aosp/frameworks/base
$ find ./ -name SyncRequest.java | xargs git blame | grep "A minimum period of 1 hour is enforced"

And get this result:

e96c3b7eff52 (Shreyas Basarge  2016-01-29 19:25:51 +0000 310)          *            to elapse between periodic syncs. A minimum period of 1 hour is enforced.

Looks like the commit is from January 2016. This explains why it works on API 19 but not on 25.

I further verified that this commit added the code that increased the minimum timeout from 60 seconds to 1 hour.

And then you might ask why on earth would Google devs change the semantics of working API on which many apps rely without a proper notification to developers? And the answer is as usual - because they can.


问:
Calculate new circle offset based on angle of rotation?
I have a multiplayer Javascript game where the player is a circle, and is able shoot/"eject" circle bullets in the direction that the player is rotated. My code is working perfectly, except it shoots from the middle of the player. I would like it so that the circles are shot from the top right position of the player, where the gun is located. The issue is that when the players rotation changes, you cannot simply add (1, -1) to the position of the player.

Here is my code:

```<code>GameServer.prototype.ejectMass = function(client) {

    for (var i = 0; i < client.cells.length; i++) {
        var cell = client.cells[i]; // the player

        var angle = this.toRad(client.rotation); // rotation of the player

        var d = new Vec2(Math.sin(angle), Math.cos(-angle)).scale(-180);

        var sq = (~~d.sqDist(d));

        d.x = sq > 1 ? d.x / sq : 1;
        d.y = sq > 1 ? d.y / sq : 0;

        // cell.position is the players position
        var pos = new Vec2(
            cell.position.x + d.x * cell._size,
            cell.position.y + d.y * cell._size
        );

        var ejected = 0;

        // Create cell and add it to node list

        ejected = new Entity.EjectedMass(this, null, pos, this.config.ejectSize * cell.ejectSize); // the bullet being shot

        ejected.setBoostDefault(-this.config.ejectVelocity * cell.ejectSpeed, angle);

        ejected.ejectedOwner = cell; // set the person who shot the bullet

        this.addNode(ejected); // add the bullet into the game

        if (typeof ejected !== 'undefined') {
            setTimeout(this.removeNode.bind(this, ejected), 1000); // remove the ejected bullet after 1 second
        }
    }
};
</code>```

And here is an illustration of the current way it is working:

答:
You didn't provide enough details about your layout such as what are orientations of X- and Y-axis? Where is 0 angle? Is angle clockwise or counterclockwise? Still the basic idea is the same. Let's assume that X-axis is to the right and Y-axis is down as it looks like from your attached image and adding (1, -1) to get top-right corner. Also assume that angle = 0 for X-axis and angle is clockwise i.e. angle = Pi/2 is aligned with positive direction of Y-axis = down. When the gun is pointed Up i.e. angle = -Pi/2 your starting point is (1, -1) which is at distance sqrt(2) and additionally rotated to Pi/4 corresponding to gun orientation. This is all you need to know.

```<code>    var angle = this.toRad(client.rotation); // rotation of the player
    var gunStartAngle = angle + Math.PI/4;
    var sqrt2 = Math.sqrt(2);

    // cell.position is the players position
    var pos = new Vec2(
        cell.position.x + cell._size * sqrt2 * Math.cos(gunStartAngle),
        cell.position.y + cell._size * sqrt2 * Math.sin(gunStartAngle)
    );
</code>```

Obviously if your layout is different, you should fix the details of the math but the idea remains the same.

Body:
I have a multiplayer Javascript game where the player is a circle, and is able shoot/"eject" circle bullets in the direction that the player is rotated. My code is working perfectly, except it shoots from the middle of the player. I would like it so that the circles are shot from the top right position of the player, where the gun is located. The issue is that when the players rotation changes, you cannot simply add (1, -1) to the position of the player.

Here is my code:

GameServer.prototype.ejectMass = function(client) {

    for (var i = 0; i < client.cells.length; i++) {
        var cell = client.cells[i]; // the player

        var angle = this.toRad(client.rotation); // rotation of the player

        var d = new Vec2(Math.sin(angle), Math.cos(-angle)).scale(-180);

        var sq = (~~d.sqDist(d));

        d.x = sq > 1 ? d.x / sq : 1;
        d.y = sq > 1 ? d.y / sq : 0;

        // cell.position is the players position
        var pos = new Vec2(
            cell.position.x + d.x * cell._size,
            cell.position.y + d.y * cell._size
        );

        var ejected = 0;

        // Create cell and add it to node list

        ejected = new Entity.EjectedMass(this, null, pos, this.config.ejectSize * cell.ejectSize); // the bullet being shot

        ejected.setBoostDefault(-this.config.ejectVelocity * cell.ejectSpeed, angle);

        ejected.ejectedOwner = cell; // set the person who shot the bullet

        this.addNode(ejected); // add the bullet into the game

        if (typeof ejected !== 'undefined') {
            setTimeout(this.removeNode.bind(this, ejected), 1000); // remove the ejected bullet after 1 second
        }
    }
};

And here is an illustration of the current way it is working:

Body:
You didn't provide enough details about your layout such as what are orientations of X- and Y-axis? Where is 0 angle? Is angle clockwise or counterclockwise? Still the basic idea is the same. Let's assume that X-axis is to the right and Y-axis is down as it looks like from your attached image and adding (1, -1) to get top-right corner. Also assume that angle = 0 for X-axis and angle is clockwise i.e. angle = Pi/2 is aligned with positive direction of Y-axis = down. When the gun is pointed Up i.e. angle = -Pi/2 your starting point is (1, -1) which is at distance sqrt(2) and additionally rotated to Pi/4 corresponding to gun orientation. This is all you need to know.

    var angle = this.toRad(client.rotation); // rotation of the player
    var gunStartAngle = angle + Math.PI/4;
    var sqrt2 = Math.sqrt(2);

    // cell.position is the players position
    var pos = new Vec2(
        cell.position.x + cell._size * sqrt2 * Math.cos(gunStartAngle),
        cell.position.y + cell._size * sqrt2 * Math.sin(gunStartAngle)
    );

Obviously if your layout is different, you should fix the details of the math but the idea remains the same.


问:
Javascript variable not changing inside setInterval() function?
The variable counter does not change for some reason, it stays its initial value, of 50. It's a global variable, that is tried to be changed inside a function called by setInterval().

```<code>var mode = false;
var counter = 50;
var interval = null;
var increment = false;
var MAX = 50;
var MIN = 0;
var INTERVAL_MS = 3000;

setInterval(doInterval, INTERVAL_MS);

function doInterval() {
    if(increment)
    {
        counter += 1;
    }
    else
    {
        console.log("Decrement, " + counter);
        counter -= 1;
    }

    // Set direction
    if(counter = MIN)
    {
        increment = true;
    }
    else if(counter = MAX)
    {
        increment = false;
    }

    console.log("set to " + counter + " (D) Increment next time? " + increment);

    // dosomething with the values
}
</code>```

The output from this code

decrement, 50

set to 50 (D) Increment next time? false

decrement, 50

set to 50 (D) Increment next time? false

decrement, 50

set to 50 (D) Increment next time? false

And so on

Since it's 50 and increment is false, it should become 49, 48, however it seems that I can't change the variable's value. What could be a reason? The code is run inside a NodeJS app.

答:
You were accidentally assigning values in your if statement. Try this to fix it.

At this part

```<code>  if(counter == MIN)
  {
    increment = true;
  }
  else if(counter == MAX)
  {
    increment = false;
  }
</code>```

To fix it you can use this:

```<code>var mode = false;
var counter = 50;
var interval = null;
var increment = false;
var MAX = 50;
var MIN = 0;
var INTERVAL_MS = 3000;

setInterval(doInterval, INTERVAL_MS);

function doInterval() {
  if(increment)
  {
    counter += 1;
  }
  else
  {
    console.log("Decrement, " + counter);
    counter -= 1;
  }

  // Set direction
  if(counter == MIN)
  {
    increment = true;
  }
  else if(counter == MAX)
  {
    increment = false;
  }

  console.log("set to " + counter + " (D) Increment next time? " + increment);

  // dosomething with the values
}
</code>```

Body:
The variable counter does not change for some reason, it stays its initial value, of 50. It's a global variable, that is tried to be changed inside a function called by setInterval().

var mode = false;
var counter = 50;
var interval = null;
var increment = false;
var MAX = 50;
var MIN = 0;
var INTERVAL_MS = 3000;

setInterval(doInterval, INTERVAL_MS);

function doInterval() {
    if(increment)
    {
        counter += 1;
    }
    else
    {
        console.log("Decrement, " + counter);
        counter -= 1;
    }

    // Set direction
    if(counter = MIN)
    {
        increment = true;
    }
    else if(counter = MAX)
    {
        increment = false;
    }

    console.log("set to " + counter + " (D) Increment next time? " + increment);

    // dosomething with the values
}

The output from this code

decrement, 50

set to 50 (D) Increment next time? false

decrement, 50

set to 50 (D) Increment next time? false

decrement, 50

set to 50 (D) Increment next time? false

And so on

Since it's 50 and increment is false, it should become 49, 48, however it seems that I can't change the variable's value. What could be a reason? The code is run inside a NodeJS app.

Body:
You were accidentally assigning values in your if statement. Try this to fix it.

At this part

  if(counter == MIN)
  {
    increment = true;
  }
  else if(counter == MAX)
  {
    increment = false;
  }

To fix it you can use this:

var mode = false;
var counter = 50;
var interval = null;
var increment = false;
var MAX = 50;
var MIN = 0;
var INTERVAL_MS = 3000;

setInterval(doInterval, INTERVAL_MS);

function doInterval() {
  if(increment)
  {
    counter += 1;
  }
  else
  {
    console.log("Decrement, " + counter);
    counter -= 1;
  }

  // Set direction
  if(counter == MIN)
  {
    increment = true;
  }
  else if(counter == MAX)
  {
    increment = false;
  }

  console.log("set to " + counter + " (D) Increment next time? " + increment);

  // dosomething with the values
}


问:
Drawing Polygon On Bing Map Odd Behaviour setLocations
Below is all the code I'm using to draw a polygon on my Bing maps. My issue is on Mouse Move I'm trying to delete the last point in the polygon and replace it with where the mouse currently is. When a click occurs an additional point is added to finalize said point and it should just add 1 point when clicked and should be point neutral on mouse move (since it pops once and pushes once). My issue is that for some reason when I call Polygon.setLocations(points) it internally appends an additional point to my polygon. I've verified via debugging before the call to setLocations I have 1 less point than I do after the call to setLocations. Console output is shown below the code to verify this. Seems like a bug in the library, any help would be appreciated to figure out how to prevent this, it seems to only happen if the array of points is greater than length 1 as when I have only 1 point it doesn't cause this weird behavior.

Edit: Alright figured it out, it duplicates the first element at the end rather than just internally referencing itself like one would expect you have to modify the second to last index or else it has this behaviour.

```<code>    Microsoft.Maps.Events.addHandler(map, 'mousemove', PolygonDrawMouseMove);

    Microsoft.Maps.Events.addHandler(map, 'click', function (e) {
        HideInfobox();
        HideContextInfobox();
        ClearPinSelection();
        PolygonDrawClick(e);
    });

    Microsoft.Maps.Events.addHandler(map, 'rightclick', function () {
        HideInfobox();
        HideContextInfobox();
        ClearPinSelection();
    });

var Polygon = null;
var isDrawingMode = false;

function PolygonDrawClick(event) {

    if (isDrawingMode && Polygon !== null && Polygon instanceof Microsoft.Maps.Polygon)
    {
        var locations = Polygon.getLocations();
        var location = propertyMap.tryPixelToLocation(new Microsoft.Maps.Point(event.getX(), event.getY()));
        locations.push(location);
        Polygon.setLocations(locations);
    }
}

function PolygonDrawMouseMove(event)
{
    if (isDrawingMode && Polygon !== null && Polygon instanceof Microsoft.Maps.Polygon)
    {
        var points = Polygon.getLocations();

        if (points.length > 1)
        {
            console.log('start');
            console.log(points.length);
        }

        if (points.length > 0)
        {
            points.pop();
        }

        if (points.length > 1)
            console.log(points.length);

        var location = propertyMap.tryPixelToLocation(new Microsoft.Maps.Point(event.getX(), event.getY()));
        points.push(location);

        if (points.length > 1)
            console.log(points.length);

        Polygon.setLocations(points);

        if(points.length > 1)
        {
            console.log(Polygon.getLocations().length);
        }
    }
}

function DeletePolygons() {
    if (!propertyMap)
        return;

    for (var i = propertyMap.entities.getLength() - 1; i >= 0; i--) {
        var polygon = propertyMap.entities.get(i);
        if (polygon instanceof Microsoft.Maps.Polygon)
            propertyMap.entities.removeAt(i);
    }

    Polygon = null;
}

$("#compsMap").keyup(function (event) {

    //escape
    if (event.keyCode === 27 && isDrawingMode && Polygon !== null && Polygon instanceof Microsoft.Maps.Polygon)
    {
        isDrawingMode = false;
        var locations = Polygon.getLocations();
        if (locations.length > 0) locations.pop();

        if (locations.length === 0)
            DeletePolygons();
        else
            Polygon.setLocations(locations);
    }
    else if (event.keyCode === 32 && !isDrawingMode) //space
    {
        DeletePolygons();
        isDrawingMode = true;
        Polygon = new Microsoft.Maps.Polygon([new Microsoft.Maps.Location(0,0)], { fillColor: 'rgba(255,212,42,0.6)', strokeColor: '#000000', strokeThickness: 2 });
        propertyMap.entities.push(Polygon);
    }
});

[![screen shot of console output][1]][1]
</code>```

答: This is by design. Polygons automatically close their rings in V8 to help make them valid. It's not normal to simply reference itself, nor would it work.</p>

Body:
Below is all the code I'm using to draw a polygon on my Bing maps. My issue is on Mouse Move I'm trying to delete the last point in the polygon and replace it with where the mouse currently is. When a click occurs an additional point is added to finalize said point and it should just add 1 point when clicked and should be point neutral on mouse move (since it pops once and pushes once). My issue is that for some reason when I call Polygon.setLocations(points) it internally appends an additional point to my polygon. I've verified via debugging before the call to setLocations I have 1 less point than I do after the call to setLocations. Console output is shown below the code to verify this. Seems like a bug in the library, any help would be appreciated to figure out how to prevent this, it seems to only happen if the array of points is greater than length 1 as when I have only 1 point it doesn't cause this weird behavior.

Edit: Alright figured it out, it duplicates the first element at the end rather than just internally referencing itself like one would expect you have to modify the second to last index or else it has this behaviour.

    Microsoft.Maps.Events.addHandler(map, 'mousemove', PolygonDrawMouseMove);

    Microsoft.Maps.Events.addHandler(map, 'click', function (e) {
        HideInfobox();
        HideContextInfobox();
        ClearPinSelection();
        PolygonDrawClick(e);
    });

    Microsoft.Maps.Events.addHandler(map, 'rightclick', function () {
        HideInfobox();
        HideContextInfobox();
        ClearPinSelection();
    });

var Polygon = null;
var isDrawingMode = false;

function PolygonDrawClick(event) {

    if (isDrawingMode && Polygon !== null && Polygon instanceof Microsoft.Maps.Polygon)
    {
        var locations = Polygon.getLocations();
        var location = propertyMap.tryPixelToLocation(new Microsoft.Maps.Point(event.getX(), event.getY()));
        locations.push(location);
        Polygon.setLocations(locations);
    }
}

function PolygonDrawMouseMove(event)
{
    if (isDrawingMode && Polygon !== null && Polygon instanceof Microsoft.Maps.Polygon)
    {
        var points = Polygon.getLocations();

        if (points.length > 1)
        {
            console.log('start');
            console.log(points.length);
        }

        if (points.length > 0)
        {
            points.pop();
        }

        if (points.length > 1)
            console.log(points.length);

        var location = propertyMap.tryPixelToLocation(new Microsoft.Maps.Point(event.getX(), event.getY()));
        points.push(location);

        if (points.length > 1)
            console.log(points.length);

        Polygon.setLocations(points);

        if(points.length > 1)
        {
            console.log(Polygon.getLocations().length);
        }
    }
}

function DeletePolygons() {
    if (!propertyMap)
        return;

    for (var i = propertyMap.entities.getLength() - 1; i >= 0; i--) {
        var polygon = propertyMap.entities.get(i);
        if (polygon instanceof Microsoft.Maps.Polygon)
            propertyMap.entities.removeAt(i);
    }

    Polygon = null;
}

$("#compsMap").keyup(function (event) {

    //escape
    if (event.keyCode === 27 && isDrawingMode && Polygon !== null && Polygon instanceof Microsoft.Maps.Polygon)
    {
        isDrawingMode = false;
        var locations = Polygon.getLocations();
        if (locations.length > 0) locations.pop();

        if (locations.length === 0)
            DeletePolygons();
        else
            Polygon.setLocations(locations);
    }
    else if (event.keyCode === 32 && !isDrawingMode) //space
    {
        DeletePolygons();
        isDrawingMode = true;
        Polygon = new Microsoft.Maps.Polygon([new Microsoft.Maps.Location(0,0)], { fillColor: 'rgba(255,212,42,0.6)', strokeColor: '#000000', strokeThickness: 2 });
        propertyMap.entities.push(Polygon);
    }
});

[![screen shot of console output][1]][1]


问:
Use AngularJS in chrome extension with object using JQuery Deferred
I'm completely new to angular, and I'm trying to get it to work in the context of a simple chrome extension (a simple rss feed reader) I'm trying to write.

The problem is that I already have a couple of javascript objects that handle the feed info, but those objects make use of JQuery Deferred implementation.

As far as I understand I can still use those objects if I use the $scope.$apply() function to make Angular aware that some change happened, but I can't get it to work.

These are my template and controller files:

Popup.html

```<code><html ng-app="app" ng-csp>
<head>
    <script src="lib/jquery-1.11.1.min.js"></script>
    <script src="lib/angular/angular.min.js"></script>

    <script src="js/utilities.js"></script>
    <script src="js/options/Options.js"></script>
    <script src="js/options/Feed.js"></script>
    <script src="js/options/FeedList.js"></script>
    <link rel="stylesheet" href="css/popup.css">

    <script type="text/javascript" src="app/app.js"></script>
    <script type="text/javascript" src="app/chromeStorage.js"></script>
    <script type="text/javascript" src="app/rssListCtrl.js"></script>
</head>
<body ng-controller="RssListCtrl">
    <p>{{title}}</p>
    <ul>
        <li ng-repeat="feed in feedList">
            {{feed.name}}
            <ul>
                <li ng-repeat="item in feed.items">
                    <a href="{{item.link}}" target="_blank">{{item.title}}</a>
                </li>
            </ul>
        </li>
    </ul>
    <button ng-click="check()">check</button>
</body>
</code>```

RssListCtrl.js

```<code>angular.module('app')
.controller('RssListCtrl', function ($scope) {

    $scope.feedList = FeedList().load().done(function(feedList) {
        $scope.$apply(function() {
            $scope.feedList = feedList;
        });
    });

    $scope.check = function () {
        console.log($scope.feedList);
    }

});
</code>```

I added the button to check in the console if the data loaded correctly. The strange thing is that, when I press the button, I get the correct output in the console AND the template in the chrome popup updates correctly with the loaded data.

I suppose I'm missing something (probably stupid), but I can't see it. Any help?

Update: the console for the popup doesn't show any error and I used the ng-csp

答:
Use $q.when to convert the jQuery Deferred object to an AngularJS promise:

```<code>app.controller('RssListCtrl', function ($scope, $q) {

    var feedListPromise = $q.when(FeedList().load());

    feedListPromise.then(function(feedList)
        $scope.feedList = feedList;
    });

    $scope.check = function () {
        console.log($scope.feedList);
    }

});
</code>```

AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.

The AngularJS $q Service $q.when Method creates an AngularJS promise that is integrated with the AngularJS execution context and its digest cycle.

$q.when

Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted.

— AngularJS $q Service API Reference ($q.when)

See also,

JavaScript Promises and why jQuery Implemetation is Broken

Promises/A+ specification

Body:
I'm completely new to angular, and I'm trying to get it to work in the context of a simple chrome extension (a simple rss feed reader) I'm trying to write.

The problem is that I already have a couple of javascript objects that handle the feed info, but those objects make use of JQuery Deferred implementation.

As far as I understand I can still use those objects if I use the $scope.$apply() function to make Angular aware that some change happened, but I can't get it to work.

These are my template and controller files:

Popup.html

    <link rel="stylesheet" href="css/popup.css">

{{title}}

            {{feed.name}}

                    {{item.title}}

    <button ng-click="check()">check</button>

RssListCtrl.js

angular.module('app')
.controller('RssListCtrl', function ($scope) {

    $scope.feedList = FeedList().load().done(function(feedList) {
        $scope.$apply(function() {
            $scope.feedList = feedList;
        });
    });

    $scope.check = function () {
        console.log($scope.feedList);
    }

});

I added the button to check in the console if the data loaded correctly. The strange thing is that, when I press the button, I get the correct output in the console AND the template in the chrome popup updates correctly with the loaded data.

I suppose I'm missing something (probably stupid), but I can't see it. Any help?

Update: the console for the popup doesn't show any error and I used the ng-csp

Body:
Use $q.when to convert the jQuery Deferred object to an AngularJS promise:

app.controller('RssListCtrl', function ($scope, $q) {

    var feedListPromise = $q.when(FeedList().load());

    feedListPromise.then(function(feedList)
        $scope.feedList = feedList;
    });

    $scope.check = function () {
        console.log($scope.feedList);
    }

});

AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.

The AngularJS $q Service $q.when Method creates an AngularJS promise that is integrated with the AngularJS execution context and its digest cycle.

$q.when

Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted.

— AngularJS $q Service API Reference ($q.when)

See also,

JavaScript Promises and why jQuery Implemetation is Broken

Promises/A+ specification


问:
Call function after time delay and then faster
I know about setInterval( foo, n) that it calls foo every n seconds.
But how can I do to call it faster and faster? Like after the first time, the function will be called again in n-1 seconds, then n-2 seconds, and so on.

答:
Use setTimeout instead. It will call a function with the new timeout, which will be the previous one -x ms, and so on.
I've added a stop condition, so it won't run forever.

function recall(n) {
  console.log(n);

  n -= 100;

  n < 0 || setTimeout(function() {
    recall(n);
  }, n);
}

recall(1000);```


问:
Elastic Beanstalk Instance logs not being streamed to Cloudwatch
I have log streaming ticket in my ELB Configuration page but in my Cloudwatch Logs i can only see eb-activity, httpd and nginx log groups. I am expecting to see the Tail and Bundle instance logs from the individual EC2 nodes. Isn't that the expected behaviour of ELB?

Do i need to do anything additional to get my instance logs to appear to CW?

答:
The awslogs agent looks in the configuration file for the log files which it's supposed to send. There are some defaults in it. You need to edit it and specify

You can check and edit the configuration file located at:

```<code>/etc/awslogs/awslogs.conf
</code>```

Make sure to restart the service:

```<code>sudo service awslogs restart
</code>```

You can specify your own files there and create different groups and what not.

Resources:

https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html

Body:
The awslogs agent looks in the configuration file for the log files which it's supposed to send. There are some defaults in it. You need to edit it and specify

You can check and edit the configuration file located at:

/etc/awslogs/awslogs.conf

Make sure to restart the service:

sudo service awslogs restart

You can specify your own files there and create different groups and what not.

Resources:

https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html


问:
Improving a long if-else statement in bash
Is there a way to write a more elegant code which considers multiple possible combinations than writing a lengthy if-else statement?

I have randomly generated data sets like the ones below but some of the rows can be null sometimes.

{

semester1 grade1 final_grade1

semester1a grade1a final_grade1a

}

{

semester2 grade2 final_grade2

semester2a grade2a final_grade2a

}

I have already written code for all the possible logical combinations of my data:

```<code>if [[ -n $semester1 && -z $semester1a && -z $semester2 && -z $semester2a ]]; then
echo "Section 1:$semester1=$grade1, final grade for $semester1=$final_grade1 ."

elif [[ -n $semester1 && -n $semester1a && -z $semester2 && -z $semester2a ]]; then
echo "Section 1:$semester1=$grade1, $semester1a=$grade1a, final grade for $semester1=$final_grade1, final grade for $semester1a=$final_grade1a."

elif [[ -n $semester1 && -n $semester1a && -n $semester2 && -z $semester2a ]]; then
echo "Section 1:$semester1=$grade1, $semester1a=$grade1a, final grade for $semester1=$final_grade1, final grade for $semester1a=$final_grade1a."
echo "Section 2:$semester2=$grade2, final grade for $semester2=$final_grade2 ."

elif [[ -n $semester2 && -z $semester2a && -z $semester1 && -z $semester1a ]]; then
echo "Section 2:$semester2=$grade2, final grade for $semester2=$final_grade2 ."

elif [[ -n $semester2 && -n $semester2a && -z $semester1 && -z $semester1a ]]; then
echo "Section 2:$semester2=$grade2, $semester2a=$grade2a, final grade for $semester2=$final_grade2, final grade for $semester2a=$final_grade2a, ."

elif [[ -n $semester2 && -n $semester2a && -n $semester1 && -z $semester1a ]]; then
echo "Section 1:$semester1=$grade1, final grade for $semester1=$final_grade1 ."
echo "Section 2:$semester2=$grade2, $semester2a=$grade2a, final grade for $semester2=$final_grade2, final grade for $semester2a=$final_grade2a, ."

elif [[ -n $semester2 && -n $semester2a && -n $semester1 && -n $semester1a ]]; then
echo "Section 1:$semester1=$grade1, $semester1a=$grade1a, final grade for $semester1=$final_grade1, final grade for $semester1a=$final_grade1a, ."
echo "Section 2:$semester2=$grade2, $semester2a=$grade2a, final grade for $semester2=$final_grade2, final grade for $semester2a=$final_grade2a, ."

fi
</code>```

Is there a better way for checking this?

答:
This loop might do it.  You'd need a second one for the 2nd semester or maybe turn it into a function and then make the vars local:</p>

```<code>if [[ -n $semester1 ]]; then
  section="Section 1:$semester1=$grade1"
  final="final grade for $semester1=$final_grade1"
  if [[ -n $semester1a ]]; then
    section="$section, $semester1a=$grade1a"
    final="$final, final grade for $semester1a=$final_grade1a."
  fi
  echo "$section, $final"
fi
</code>```

Body:
Is there a way to write a more elegant code which considers multiple possible combinations than writing a lengthy if-else statement?

I have randomly generated data sets like the ones below but some of the rows can be null sometimes.

{

semester1 grade1 final_grade1

semester1a grade1a final_grade1a

}

{

semester2 grade2 final_grade2

semester2a grade2a final_grade2a

}

I have already written code for all the possible logical combinations of my data:

if [[ -n $semester1 && -z $semester1a && -z $semester2 && -z $semester2a ]]; then
echo "Section 1:$semester1=$grade1, final grade for $semester1=$final_grade1 ."

elif [[ -n $semester1 && -n $semester1a && -z $semester2 && -z $semester2a ]]; then
echo "Section 1:$semester1=$grade1, $semester1a=$grade1a, final grade for $semester1=$final_grade1, final grade for $semester1a=$final_grade1a."

elif [[ -n $semester1 && -n $semester1a && -n $semester2 && -z $semester2a ]]; then
echo "Section 1:$semester1=$grade1, $semester1a=$grade1a, final grade for $semester1=$final_grade1, final grade for $semester1a=$final_grade1a."
echo "Section 2:$semester2=$grade2, final grade for $semester2=$final_grade2 ."

elif [[ -n $semester2 && -z $semester2a && -z $semester1 && -z $semester1a ]]; then
echo "Section 2:$semester2=$grade2, final grade for $semester2=$final_grade2 ."

elif [[ -n $semester2 && -n $semester2a && -z $semester1 && -z $semester1a ]]; then
echo "Section 2:$semester2=$grade2, $semester2a=$grade2a, final grade for $semester2=$final_grade2, final grade for $semester2a=$final_grade2a, ."

elif [[ -n $semester2 && -n $semester2a && -n $semester1 && -z $semester1a ]]; then
echo "Section 1:$semester1=$grade1, final grade for $semester1=$final_grade1 ."
echo "Section 2:$semester2=$grade2, $semester2a=$grade2a, final grade for $semester2=$final_grade2, final grade for $semester2a=$final_grade2a, ."

elif [[ -n $semester2 && -n $semester2a && -n $semester1 && -n $semester1a ]]; then
echo "Section 1:$semester1=$grade1, $semester1a=$grade1a, final grade for $semester1=$final_grade1, final grade for $semester1a=$final_grade1a, ."
echo "Section 2:$semester2=$grade2, $semester2a=$grade2a, final grade for $semester2=$final_grade2, final grade for $semester2a=$final_grade2a, ."

fi

Is there a better way for checking this?

Body:
This loop might do it.  You'd need a second one for the 2nd semester or maybe turn it into a function and then make the vars local:

if [[ -n $semester1 ]]; then
  section="Section 1:$semester1=$grade1"
  final="final grade for $semester1=$final_grade1"
  if [[ -n $semester1a ]]; then
    section="$section, $semester1a=$grade1a"
    final="$final, final grade for $semester1a=$final_grade1a."
  fi
  echo "$section, $final"
fi


问:
Why does C# XmlDocument.LoadXml(string) fail when an XML header is included?
Does anyone have any idea why the following code sample fails with an XmlException "Data at the root level is invalid. Line 1, position 1."</p>

```<code>var body = "<?xml version="1.0" encoding="utf-16"?><Report> ......"
XmlDocument bodyDoc = new XmlDocument();
bodyDoc.LoadXml(body);
</code>```

答:
Simple line:

bodyDoc.LoadXml(new MemoryStream(Encoding.Unicode.GetBytes(body)));

OwnerDisplayName: Gabe

Body:
Does anyone have any idea why the following code sample fails with an XmlException "Data at the root level is invalid. Line 1, position 1."

var body = "<?xml version="1.0" encoding="utf-16"?><Report> ......"
XmlDocument bodyDoc = new XmlDocument();
bodyDoc.LoadXml(body);


问:
Android - Best way to hide API clientId & clientSecret
I would like to have your opinion on the best way to hide an API key and secret key.

I found 2 ways :

Use NDK like that : https://medium.com/@abhi007tyagi/storing-api-keys-using-android-ndk-6abb0adcadad

Use Gradle like that : http://www.techjini.com/blog/securing-api-key-and-secret-key-in-android

I know that risk 0 does not exist but what is the most secure solution ?

Thank in advance

答:
The best to secure the key is by not putting your keys in app, for that purpose if you are using a server that is highly secure (eg. Amazon Server) then put your keys on server and access them on run time. And also apply public/private encryption on both app and server side.

But if you want to stay with the app then using "NDK" or using "Proguard" both are highly secure mechanisms on app level.


答:
In that case you can use setTimout recursively:

function foo () {
   console.log(new Date());
}

function fasterAndFaster(fn, seconds) {
  if (seconds <= 0) { return; }
  setTimeout(function () {
    fn();
    // Recursive call
    fasterAndFaster(fn, seconds - 1);
  }, seconds * 1000);
}

fasterAndFaster(foo, 5);
console.log("Wait 5 seconds");```

Title: Call function after time delay and then faster

Body:
I know about setInterval( foo, n) that it calls foo every n seconds.
But how can I do to call it faster and faster? Like after the first time, the function will be called again in n-1 seconds, then n-2 seconds, and so on.


问:
Python sorting question - given list of ['url', 'tag1', 'tag2',..]s and search specification ['tag3', 'tag1',...], return relevant url list
I'm quite new to programming so I'm sure there's a terser way to pose this, but I'm trying to create a personal bookmarking program. Given multiple urls each with a list of tags ordered by relevance, I want to be able to create a search consisting of a list of tags that returns a list of most relevant urls. My first solution, below, is to give the first tag a value of 1, the second 2, and so on & let the python list sort function do the rest. 2 questions:

1) Is there a much more elegant/efficient way of doing this (embarrass me!)
2) Any other general approaches to the sorting by relevance given the inputs above problem?

Much obliged.

```<code># Given a list of saved urls each with a corresponding user-generated taglist
# (ordered by relevance), the user enters a "search" list-of-tags, and is
# returned a sorted list of urls.

# Generate sample "content" linked-list-dictionary. The rationale is to
# be able to add things like 'title' etc at later stages and to
# treat each url/note as in independent entity. But a single dictionary
# approach like "note['url1']=['b','a','c','d']" might work better?

content = []
note = {'url':'url1', 'taglist':['b','a','c','d']}
content.append(note)
note = {'url':'url2', 'taglist':['c','a','b','d']}
content.append(note)
note = {'url':'url3', 'taglist':['a','b','c','d']}
content.append(note)
note = {'url':'url4', 'taglist':['a','b','d','c']}
content.append(note)
note = {'url':'url5', 'taglist':['d','a','c','b']}
content.append(note)

# An example search term of tags, ordered by importance
# I'm using a dictionary with an ordinal number system
# This seems clumsy
search = {'d':1,'a':2,'b':3}

# Create a tagCloud with one entry for each tag that occurs
tagCloud = []
for note in content:
    for tag in note['taglist']:
        if tagCloud.count(tag) == 0:
            tagCloud.append(tag)

# Create a dictionary that associates an integer value denoting
# relevance (1 is most relevant etc) for each existing tag

d={}
for tag in tagCloud:
    try:
        d[tag]=search[tag]
    except KeyError:
        d[tag]=100

# Create a [[relevance, tag],[],[],...] result list & sort
result=[]
for note in content:
    resultNote=[]
    for tag in note['taglist']:
        resultNote.append([d[tag],tag])
    resultNote.append(note['url'])
    result.append(resultNote)
result.sort()

# Remove the relevance values & recreate a list containing
# the url string followed by corresponding tags.
# Its so hacky i've forgotten how it works!
# It's mostly for display, but suggestions on "best-practice"
# intermediate-form data storage?

finalResult=[]
for note in result:
    temp=[]
    temp.append(note.pop())
    for tag in note:
        temp.append(tag[1])
    finalResult.append(temp)

print "Content: ", content
print "Search: ", search
print "Final Result: ", finalResult
</code>```

答:
I suggest you also give a weight to each tag, depending on how rare it is (e.g. a “tarantula” tag would weigh more than a “nature” tag¹). For a given URL, rare tags that are common with other URLs should mark a stronger relevance, while frequently used tags of the given URL not existing in another URL should mark down the relevance.

It's easy to convert the rules I describe above as calculations of a numerical relevance for every other URL.

¹ unless all your URLs are related to “tarantulas”, of course :)

ContentLicense: CC BY-SA 2.5

Body:
I'm quite new to programming so I'm sure there's a terser way to pose this, but I'm trying to create a personal bookmarking program. Given multiple urls each with a list of tags ordered by relevance, I want to be able to create a search consisting of a list of tags that returns a list of most relevant urls. My first solution, below, is to give the first tag a value of 1, the second 2, and so on & let the python list sort function do the rest. 2 questions:

1) Is there a much more elegant/efficient way of doing this (embarrass me!)
2) Any other general approaches to the sorting by relevance given the inputs above problem?

Much obliged.

# Given a list of saved urls each with a corresponding user-generated taglist
# (ordered by relevance), the user enters a "search" list-of-tags, and is
# returned a sorted list of urls.

# Generate sample "content" linked-list-dictionary. The rationale is to
# be able to add things like 'title' etc at later stages and to
# treat each url/note as in independent entity. But a single dictionary
# approach like "note['url1']=['b','a','c','d']" might work better?

content = []
note = {'url':'url1', 'taglist':['b','a','c','d']}
content.append(note)
note = {'url':'url2', 'taglist':['c','a','b','d']}
content.append(note)
note = {'url':'url3', 'taglist':['a','b','c','d']}
content.append(note)
note = {'url':'url4', 'taglist':['a','b','d','c']}
content.append(note)
note = {'url':'url5', 'taglist':['d','a','c','b']}
content.append(note)

# An example search term of tags, ordered by importance
# I'm using a dictionary with an ordinal number system
# This seems clumsy
search = {'d':1,'a':2,'b':3}

# Create a tagCloud with one entry for each tag that occurs
tagCloud = []
for note in content:
    for tag in note['taglist']:
        if tagCloud.count(tag) == 0:
            tagCloud.append(tag)

# Create a dictionary that associates an integer value denoting
# relevance (1 is most relevant etc) for each existing tag

d={}
for tag in tagCloud:
    try:
        d[tag]=search[tag]
    except KeyError:
        d[tag]=100

# Create a [[relevance, tag],[],[],...] result list & sort
result=[]
for note in content:
    resultNote=[]
    for tag in note['taglist']:
        resultNote.append([d[tag],tag])
    resultNote.append(note['url'])
    result.append(resultNote)
result.sort()

# Remove the relevance values & recreate a list containing
# the url string followed by corresponding tags.
# Its so hacky i've forgotten how it works!
# It's mostly for display, but suggestions on "best-practice"
# intermediate-form data storage?

finalResult=[]
for note in result:
    temp=[]
    temp.append(note.pop())
    for tag in note:
        temp.append(tag[1])
    finalResult.append(temp)

print "Content: ", content
print "Search: ", search
print "Final Result: ", finalResult


问:
How to configure ESLint so that it disallows default exports
I've been searching the web and StackOverflow for this for quite some time with no success.

What I'm trying to do have ESLint mark the following as errors:

```<code>export default ...;
</code>```

with default being the key here. So far the best I've got is a reference to eslint-plugin-import plugin and some of its rules that can make me closer to the target, namely the no-anonymous-default-export rule. But even with this rule the following default exports would be valid:

```<code>const foo = 123
export default foo

export default class MyClass() {}

export default function foo() {}
</code>```

How can I configure ESLint in such a way that these four would also be considered errors?

答:
You can do this with the no-restricted-syntax rule. Try pasting this in the demo to try it out (you'll need to change "Source Type" to "module" first in the options):

```<code>/* eslint "no-restricted-syntax": ["error", {
    "selector": "ExportDefaultDeclaration",
    "message": "Prefer named exports"
  }] */
export default class Foo { } // 5:1 - Prefer named exports (no-restricted-syntax)
</code>```

Body:
I've been searching the web and StackOverflow for this for quite some time with no success.

What I'm trying to do have ESLint mark the following as errors:

export default ...;

with default being the key here. So far the best I've got is a reference to eslint-plugin-import plugin and some of its rules that can make me closer to the target, namely the no-anonymous-default-export rule. But even with this rule the following default exports would be valid:

const foo = 123
export default foo

export default class MyClass() {}

export default function foo() {}

How can I configure ESLint in such a way that these four would also be considered errors?

Body:
You can do this with the no-restricted-syntax rule. Try pasting this in the demo to try it out (you'll need to change "Source Type" to "module" first in the options):

/* eslint "no-restricted-syntax": ["error", {
    "selector": "ExportDefaultDeclaration",
    "message": "Prefer named exports"
  }] */
export default class Foo { } // 5:1 - Prefer named exports (no-restricted-syntax)


问:
How to structure REGEX in C#
I currently have a regex that checks if a US State is spelled correctly

var r = new Regex(string.Format(@"\b(?:{0})\b", pattern), RegexOptions.IgnoreCase)

pattern is a pipe delimited string containing all US states.

It was working as intended today until one of the states was spelled like "Florida.." I would have liked it picked up the fact there was a fullstop character.

I found this regex that will only match letters.
    ^[a-zA-Z]+

How do I combine this with my current Regex or is it not possible?

I tried some variations of this but it didn't work

```<code>var r = new Regex(string.Format(@"\b^[a-zA-Z]+(?:{0})\b", pattern), RegexOptions.IgnoreCase);
</code>```

EDIT: Florida.. was in my input string. My pattern string hasn't changed at all. Apologies for not being clearer.

答:
Don't search for characters directly, tell regex to consume all which are not targeted specific characters such as [^\|.]+. It uses the set [ ] with the not ^ indicator says consume anything which is not a literal | or .. Hence it consumes just the text needed. Such as on

Colorado|Florida..|New Mexico

returns 3 matches of Colorado Florida and New Mexico

Title: How to structure REGEX in C#

Body:
I currently have a regex that checks if a US State is spelled correctly

var r = new Regex(string.Format(@"\b(?:{0})\b", pattern), RegexOptions.IgnoreCase)

pattern is a pipe delimited string containing all US states.

It was working as intended today until one of the states was spelled like "Florida.." I would have liked it picked up the fact there was a fullstop character.

I found this regex that will only match letters.
    ^[a-zA-Z]+

How do I combine this with my current Regex or is it not possible?

I tried some variations of this but it didn't work

var r = new Regex(string.Format(@"\b^[a-zA-Z]+(?:{0})\b", pattern), RegexOptions.IgnoreCase);

EDIT: Florida.. was in my input string. My pattern string hasn't changed at all. Apologies for not being clearer.


问:
Input string was not in a correct formatt asp.net
```<code>string query = "select * from tblUser where UEmail = '" + TextBox1.Text + "'";
DataSet ds = new DataSet();
ds = obj.fillDataset(query);

if(ds.Tables[0].Rows.Count > 0)
{
    int pwd = Convert.ToInt16(ds.Tables[0].Rows[0]["UPassword"].ToString());
    MailMessage msg = new MailMessage("somemailaddress@gmail.com", TextBox1.Text.Trim());
    msg.Subject = "Confirm Password";
    msg.Body = "Your password is" + pwd.ToString();
    msg.IsBodyHtml = true;
    SmtpClient smtp = new SmtpClient();
    smtp.Host = "smtp.gmail.com";
    smtp.EnableSsl = true;
    NetworkCredential ntwcred = new NetworkCredential();
    ntwcred.UserName = "somemailaddress@gmail.com";
    ntwcred.Password = "********";
    smtp.UseDefaultCredentials = true;
    smtp.Credentials = ntwcred;
    smtp.Port = 587;
    smtp.Send(msg);
    Response.Write("<script language=javascript>alert('Your Password is Successfully sent to your Email');</script>");
}
</code>```

I am applying functionality that when user enters his email address in a textbox and clicks a button, an email is sent to the email address, so he can get his forgotten password.

I am getting an error on the line below:

```<code>int pwd = Convert.ToInt16(ds.Tables[0].Rows[0]["UPassword"].ToString());
</code>```

(the password datatype is varchar in sqlserver)

答:
If the password can contain non-numeric characters, then don't try to convert it to an integer:</p>

```<code>string pwd = ds.Tables[0].Rows[0]["UPassword"];
</code>```

Body:
string query = "select * from tblUser where UEmail = '" + TextBox1.Text + "'";
DataSet ds = new DataSet();
ds = obj.fillDataset(query);

if(ds.Tables[0].Rows.Count > 0)
{
    int pwd = Convert.ToInt16(ds.Tables[0].Rows[0]["UPassword"].ToString());
    MailMessage msg = new MailMessage("somemailaddress@gmail.com", TextBox1.Text.Trim());
    msg.Subject = "Confirm Password";
    msg.Body = "Your password is" + pwd.ToString();
    msg.IsBodyHtml = true;
    SmtpClient smtp = new SmtpClient();
    smtp.Host = "smtp.gmail.com";
    smtp.EnableSsl = true;
    NetworkCredential ntwcred = new NetworkCredential();
    ntwcred.UserName = "somemailaddress@gmail.com";
    ntwcred.Password = "********";
    smtp.UseDefaultCredentials = true;
    smtp.Credentials = ntwcred;
    smtp.Port = 587;
    smtp.Send(msg);
    Response.Write("");
}

I am applying functionality that when user enters his email address in a textbox and clicks a button, an email is sent to the email address, so he can get his forgotten password.

I am getting an error on the line below:

int pwd = Convert.ToInt16(ds.Tables[0].Rows[0]["UPassword"].ToString());

(the password datatype is varchar in sqlserver)

Body:
If the password can contain non-numeric characters, then don't try to convert it to an integer:

string pwd = ds.Tables[0].Rows[0]["UPassword"];