问:
Why isn't this code executing the stored procedure and inserting data?
I have a controller listed here which should be calling the Dapper method, however I cannot get it to execute. It's not throwing any exceptions and it is redirecting under the try catch however the procedure doesn't seem to be running as no new users are ever created.

The connection set up works with simple inline .Query methods however as soon as I attempt to do this with a stored procedure, it fails.

Model:

    public class User
    {
        public int UserID { get; set; }
        public string Username { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Boolean ActiveB { get; set; }
    }
```

<p>View:</p>

```@model ScaleBase.Models.FullUser

@{
    ViewData["Title"] = "Create";
}

Create

User

        <form asp-action="Create">

                <input asp-for="OrganisationID" class="form-control" />

                <input asp-for="ClientID" class="form-control" />

                <input asp-for="TeamID" class="form-control" />

                <input asp-for="Email" class="form-control" />

                <input asp-for="Username" class="form-control" />

                <input asp-for="Password" type="password" class="form-control" />

                <input asp-for="FirstName" class="form-control" />

                <input asp-for="LastName" class="form-control" />

                        <input asp-for="ActiveB" /> @Html.DisplayNameFor(model => model.ActiveB)

                <input type="submit" value="Create" class="btn btn-default" />

        </form>

```

<p>Controller:</p>

```public ActionResult Create(IFormCollection collection)
{
        try
        {
            DynamicParameters parameters = new DynamicParameters();

            parameters.Add("@Organisation", collection["OrganisationID"]);
            parameters.Add("@ClientID1", collection["ClientID"]);
            parameters.Add("@Team", collection["TeamID"]);
            parameters.Add("@Email", collection["Email"]);
            parameters.Add("@UserName", collection["UserName"]);
            parameters.Add("@Password", collection["Password"]);
            parameters.Add("@FirstName", collection["FirstName"]);
            parameters.Add("@LastName", collection["LastName"]);

            var affectedRows = _dapperRepo.CreateUser(parameters);

            return RedirectToAction(nameof(Index));
        }
        catch (Exception)
        {
            throw;
        }
    }
```

<p>Dapper repo:</p>

```    public async Task<User> CreateUser(DynamicParameters parameters)
    {
        using (IDbConnection conn = Connection)
        {
            string sproc = "EXEC sproc_NewUser @Organisation, @Client1, @Team, @Email  @UserName, @Password, @FirstName, @LastName";
            conn.Open();
            var result = await conn.QueryAsync(sproc, parameters, commandType: CommandType.StoredProcedure);
            return result.FirstOrDefault();
        }
    }
```

<p>Stored procedure:</p>

```BEGIN TRY
    BEGIN TRANSACTION NewUser
        DECLARE @salt UNIQUEIDENTIFIER = NEWID()

        INSERT INTO [dbo].[User] (Username, Email, FirstName, LastName, Password, Salt, Active)
        VALUES (@UserName, @Email, @FirstName, @LastName, HASHBYTES('SHA2_512', @Password+CAST(@salt AS NVARCHAR(36))), @salt, 1)

        INSERT INTO [dbo].[UserOrganisations] (UserID, OrganisationID)
        VALUES (IDENT_CURRENT('User'), @Organisation)

        INSERT INTO [dbo].[UserClients] (UserID, ClientID)
        VALUES (IDENT_CURRENT('User'), @Client1)

        IF @Client2 IS NOT NULL
        BEGIN
            INSERT INTO [dbo].[UserClients] (UserID, ClientID)
            VALUES (IDENT_CURRENT('User'), @Client2)
        END

        IF @Client3 IS NOT NULL
        BEGIN
            INSERT INTO [dbo].[UserClients] (UserID, ClientID)
            VALUES (IDENT_CURRENT('User'), @Client3)
        END

        IF @Client4 IS NOT NULL
        BEGIN
            INSERT INTO [dbo].[UserClients] (UserID, ClientID)
            VALUES (IDENT_CURRENT('User'), @Client4)
        END

        IF @Client5 IS NOT NULL
        BEGIN
            INSERT INTO [dbo].[UserClients] (UserID, ClientID)
            VALUES (IDENT_CURRENT('User'), @Client5)
        END

        INSERT INTO [dbo].[UserTeams] (UserID, TeamID)
        VALUES (IDENT_CURRENT('User'), @Team)

        INSERT INTO [dbo].[UserPermission] (UserID, HolidayCount, HolidayUsed, TemplateID, ConfigState1, ConfigState2, ConfigState3, ConfigState4, ConfigState5)
        VALUES (IDENT_CURRENT('User'), @Holiday, 0, 1, 255, null, null, null, null)

        INSERT INTO [dbo].[UserTime] (UserID, Scale, StartTime, EndTime)
        VALUES (IDENT_CURRENT('User'), 1, @StartTime, @EndTime)

        COMMIT TRANSACTION NewUser

        PRINT 'Success'

        SELECT
            [UserID], [Username], [Email], [Firstname], [Lastname], [Active]
        FROM
            [User]
        WHERE
            [UserID] = IDENT_CURRENT('User')
END TRY
BEGIN CATCH
    IF (@@TRANCOUNT > 0)
    BEGIN
        ROLLBACK TRANSACTION NewUser
        PRINT 'Failed'
    END

    SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

        RETURN 'Error'
END CATCH
```

答:
Delclare ALL paramaters which are listed in your stored procedure. @Client2, @ClientID3 ect will cause an error of undeclared paramaters.

Changing the implementation of this to .ExecuteAsync and executing in the controller seem to resolve this issue.

public Async Task<IActionResult> Create(IFormCollection collection)
{
        try
        {
            DynamicParameters parameters = new DynamicParameters();

            parameters.Add("@Organisation", collection["OrganisationID"]);
            parameters.Add("@ClientID1", collection["ClientID"]);
            parameters.Add("@Team", collection["TeamID"]);
            parameters.Add("@Email", collection["Email"]);
            parameters.Add("@UserName", collection["UserName"]);
            parameters.Add("@Password", collection["Password"]);
            parameters.Add("@FirstName", collection["FirstName"]);
            parameters.Add("@LastName", collection["LastName"]);

            var affectedRows = _dapperRepo.CreateUser(parameters);
            using (IDbConnection conn = Connection)
            {
                string sproc = "EXEC sproc_NewUser @Organisation, @Client1, @Team, @Email  @UserName, @Password, @FirstName, @LastName";
                conn.Open();
                var result = await conn.QueryAsync(sproc, parameters, commandType: CommandType.StoredProcedure);
                var result2 = result.FirstOrDefault();
            }
            return RedirectToAction(nameof(Index));
        }
        catch (Exception)
        {
            throw;
        }
    }
```

Body:
I have a controller listed here which should be calling the Dapper method, however I cannot get it to execute. It's not throwing any exceptions and it is redirecting under the try catch however the procedure doesn't seem to be running as no new users are ever created.

The connection set up works with simple inline .Query methods however as soon as I attempt to do this with a stored procedure, it fails.

Model:

    public class User
    {
        public int UserID { get; set; }
        public string Username { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Boolean ActiveB { get; set; }
    }

View:

@model ScaleBase.Models.FullUser

@{
    ViewData["Title"] = "Create";
}

Create

User

        <form asp-action="Create">

                <input asp-for="OrganisationID" class="form-control" />

                <input asp-for="ClientID" class="form-control" />

                <input asp-for="TeamID" class="form-control" />

                <input asp-for="Email" class="form-control" />

                <input asp-for="Username" class="form-control" />

                <input asp-for="Password" type="password" class="form-control" />

                <input asp-for="FirstName" class="form-control" />

                <input asp-for="LastName" class="form-control" />

                        <input asp-for="ActiveB" /> @Html.DisplayNameFor(model => model.ActiveB)

                <input type="submit" value="Create" class="btn btn-default" />

        </form>

Controller:

public ActionResult Create(IFormCollection collection)
{
        try
        {
            DynamicParameters parameters = new DynamicParameters();

            parameters.Add("@Organisation", collection["OrganisationID"]);
            parameters.Add("@ClientID1", collection["ClientID"]);
            parameters.Add("@Team", collection["TeamID"]);
            parameters.Add("@Email", collection["Email"]);
            parameters.Add("@UserName", collection["UserName"]);
            parameters.Add("@Password", collection["Password"]);
            parameters.Add("@FirstName", collection["FirstName"]);
            parameters.Add("@LastName", collection["LastName"]);

            var affectedRows = _dapperRepo.CreateUser(parameters);

            return RedirectToAction(nameof(Index));
        }
        catch (Exception)
        {
            throw;
        }
    }

Dapper repo:

    public async Task<User> CreateUser(DynamicParameters parameters)
    {
        using (IDbConnection conn = Connection)
        {
            string sproc = "EXEC sproc_NewUser @Organisation, @Client1, @Team, @Email  @UserName, @Password, @FirstName, @LastName";
            conn.Open();
            var result = await conn.QueryAsync(sproc, parameters, commandType: CommandType.StoredProcedure);
            return result.FirstOrDefault();
        }
    }

Stored procedure:

BEGIN TRY
    BEGIN TRANSACTION NewUser
        DECLARE @salt UNIQUEIDENTIFIER = NEWID()

        INSERT INTO [dbo].[User] (Username, Email, FirstName, LastName, Password, Salt, Active)
        VALUES (@UserName, @Email, @FirstName, @LastName, HASHBYTES('SHA2_512', @Password+CAST(@salt AS NVARCHAR(36))), @salt, 1)

        INSERT INTO [dbo].[UserOrganisations] (UserID, OrganisationID)
        VALUES (IDENT_CURRENT('User'), @Organisation)

        INSERT INTO [dbo].[UserClients] (UserID, ClientID)
        VALUES (IDENT_CURRENT('User'), @Client1)

        IF @Client2 IS NOT NULL
        BEGIN
            INSERT INTO [dbo].[UserClients] (UserID, ClientID)
            VALUES (IDENT_CURRENT('User'), @Client2)
        END

        IF @Client3 IS NOT NULL
        BEGIN
            INSERT INTO [dbo].[UserClients] (UserID, ClientID)
            VALUES (IDENT_CURRENT('User'), @Client3)
        END

        IF @Client4 IS NOT NULL
        BEGIN
            INSERT INTO [dbo].[UserClients] (UserID, ClientID)
            VALUES (IDENT_CURRENT('User'), @Client4)
        END

        IF @Client5 IS NOT NULL
        BEGIN
            INSERT INTO [dbo].[UserClients] (UserID, ClientID)
            VALUES (IDENT_CURRENT('User'), @Client5)
        END

        INSERT INTO [dbo].[UserTeams] (UserID, TeamID)
        VALUES (IDENT_CURRENT('User'), @Team)

        INSERT INTO [dbo].[UserPermission] (UserID, HolidayCount, HolidayUsed, TemplateID, ConfigState1, ConfigState2, ConfigState3, ConfigState4, ConfigState5)
        VALUES (IDENT_CURRENT('User'), @Holiday, 0, 1, 255, null, null, null, null)

        INSERT INTO [dbo].[UserTime] (UserID, Scale, StartTime, EndTime)
        VALUES (IDENT_CURRENT('User'), 1, @StartTime, @EndTime)

        COMMIT TRANSACTION NewUser

        PRINT 'Success'

        SELECT
            [UserID], [Username], [Email], [Firstname], [Lastname], [Active]
        FROM
            [User]
        WHERE
            [UserID] = IDENT_CURRENT('User')
END TRY
BEGIN CATCH
    IF (@@TRANCOUNT > 0)
    BEGIN
        ROLLBACK TRANSACTION NewUser
        PRINT 'Failed'
    END

    SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

        RETURN 'Error'
END CATCH


来源: stackexchange

问:
Phonegap Firebase Push Notifications
I have a Android/ios app, and i use my browser with php to insert articles on the database, and then the app pushes the data from the database with ajax.

What i need, is that when i post a article on the php(server side), and it gets insert, it sends a notification to the phones.

I have this on my app js:

```<code>const push = PushNotification.init({
            android: {
                vibrate: "true",
                alert: "true",
                badge: "true",
                sound: "true"
            },
            browser: {
            },
            ios: {
                vibrate: "true",
                alert: "true",
                badge: "true",
                sound: "true"
            },
            windows: {}
        });
            push.on('registration', function(data) {
            //alert(data.registrationId);
            var registrationId=data.registrationId;
            var dataString ="id_usuario="+registrationId;
            if($.trim(registrationId).length>0){
                $.ajax({
                    type: "POST",
                    url: "https://pizzarte.com/app/registarid.php",
                    data: dataString,
                    crossDomain: true,
                    cache: false,
                })
            }
        });

            push.on('notification', function(data) {
            //alert(data.title+" Message: grgregregerg" +data.message);
            });

            push.on('error', function(e) {
            alert(e);
            });
</code>```

So when the user starts the app, it saves the registrationID of that device, and it gets stored on the database. This is working just fine. Now on the server side, i pull all the registeredID's, and try to send a notification:

```<code><?php

// API access key from Google API's Console - server key here https://console.developers.google.com/apis/credentials?authuser=2&project=project_name
define( 'API_ACCESS_KEY', 'this is my api access key, im using the server key');
$registrationIds = array("device_ids");

var_dump ($registrationIds);

// prep the bundle
$msg = array
(
    'message'   => 'here is a message. message',
    'title'     => 'This is a title. title',
    'subtitle'  => 'This is a subtitle. subtitle',
    'tickerText'    => 'Ticker text here...Ticker text here...Ticker text here',
    'vibrate'   => 1,
    'sound'     => 1
);

$fields = array
(
    'registration_ids'  => $registrationIds,
    'data'          => $msg
);

$headers = array
(
    'Authorization: key=' . API_ACCESS_KEY,
    'Content-Type: application/json'
);

var_dump ($headers);

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );

echo $result;
</code>```

But i always get the error "Unauthorized
Error 401"

On my config.xml i have this too:

```<code><plugin name="phonegap-plugin-push" spec="2.0.0" />
<variable name="SENDER_ID" value="xxxxxxxxxxxxx" />
</plugin>

<platform name="android">
    <preference name="android-minSdkVersion" value="14" />
    <allow-intent href="market:*" />
    <resource-file src="google-services.json" target="google-services.json" />
</platform>
</code>```

What am i doing wrong here?

答:
change this in config.xml

```<code><plugin name="phonegap-plugin-push" spec="~2.1.2" >
        <variable name="FCM_VERSION" value="11.0.1" />
  </plugin>
</code>```

and change next

```<code><platform name="android">
    <preference name="android-minSdkVersion" value="14" />
    <allow-intent href="market:*" />
    <resource-file src="google-services.json" target="google-services.json" />
</platform>
</code>```

to

```<code><platform name="android">
    <preference name="android-minSdkVersion" value="16" />
    <allow-intent href="market:*" />
    <resource-file src="google-services.json" target="app/google-services.json" />
</platform>
</code>```

    value="14"  to value="16"

target="google-services.json" need to be target="app/google-services.json"

I hope it will help you.

ContentLicense: CC BY-SA 4.0

Title: Phonegap Firebase Push Notifications

Body:
I have a Android/ios app, and i use my browser with php to insert articles on the database, and then the app pushes the data from the database with ajax.

What i need, is that when i post a article on the php(server side), and it gets insert, it sends a notification to the phones.

I have this on my app js:

const push = PushNotification.init({
            android: {
                vibrate: "true",
                alert: "true",
                badge: "true",
                sound: "true"
            },
            browser: {
            },
            ios: {
                vibrate: "true",
                alert: "true",
                badge: "true",
                sound: "true"
            },
            windows: {}
        });
            push.on('registration', function(data) {
            //alert(data.registrationId);
            var registrationId=data.registrationId;
            var dataString ="id_usuario="+registrationId;
            if($.trim(registrationId).length>0){
                $.ajax({
                    type: "POST",
                    url: "https://pizzarte.com/app/registarid.php",
                    data: dataString,
                    crossDomain: true,
                    cache: false,
                })
            }
        });

            push.on('notification', function(data) {
            //alert(data.title+" Message: grgregregerg" +data.message);
            });

            push.on('error', function(e) {
            alert(e);
            });

So when the user starts the app, it saves the registrationID of that device, and it gets stored on the database. This is working just fine. Now on the server side, i pull all the registeredID's, and try to send a notification:

<?php

// API access key from Google API's Console - server key here https://console.developers.google.com/apis/credentials?authuser=2&project=project_name
define( 'API_ACCESS_KEY', 'this is my api access key, im using the server key');
$registrationIds = array("device_ids");

var_dump ($registrationIds);

// prep the bundle
$msg = array
(
    'message'   => 'here is a message. message',
    'title'     => 'This is a title. title',
    'subtitle'  => 'This is a subtitle. subtitle',
    'tickerText'    => 'Ticker text here...Ticker text here...Ticker text here',
    'vibrate'   => 1,
    'sound'     => 1
);

$fields = array
(
    'registration_ids'  => $registrationIds,
    'data'          => $msg
);

$headers = array
(
    'Authorization: key=' . API_ACCESS_KEY,
    'Content-Type: application/json'
);

var_dump ($headers);

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );

echo $result;

But i always get the error "Unauthorized
Error 401"

On my config.xml i have this too:

<plugin name="phonegap-plugin-push" spec="2.0.0" />
<variable name="SENDER_ID" value="xxxxxxxxxxxxx" />
</plugin>

<platform name="android">
    <preference name="android-minSdkVersion" value="14" />
    <allow-intent href="market:*" />
    <resource-file src="google-services.json" target="google-services.json" />
</platform>

What am i doing wrong here?

Body:
change this in config.xml

<plugin name="phonegap-plugin-push" spec="~2.1.2" >
        <variable name="FCM_VERSION" value="11.0.1" />
  </plugin>

and change next

<platform name="android">
    <preference name="android-minSdkVersion" value="14" />
    <allow-intent href="market:*" />
    <resource-file src="google-services.json" target="google-services.json" />
</platform>

to

<platform name="android">
    <preference name="android-minSdkVersion" value="16" />
    <allow-intent href="market:*" />
    <resource-file src="google-services.json" target="app/google-services.json" />
</platform>

    value="14"  to value="16"

target="google-services.json" need to be target="app/google-services.json"

I hope it will help you.


问:
HIghcharts Scrollbar (w/ showFull false) displays after setExtremes called
After setting the extremes of a graph to dataMin and dataMax on the xAxis the xAxis scrollbar that is configured with showFull false still displays.

Background on how we get in this state:
We have a chart that gets updated data every 30 seconds, instead of redrawing we use chart.update w/ series attribute and redraw false.
this updates the dataMin dataMax attributes of the axis but not the min/max attributes (which control the window in view)

using logic to determine if we want to interrupt the users work flow we decide if it is necessary to call setExtremes w/ redraw true
-- NOTE: this is mainly required because otherwise the graph min can be bellow the dataMin for the axis (causing whitespace)
using floor and setExtremes i am able to partially resolve that problem by pushing the window in view to the updated time range and using floor to prevent them from scrolling back (tho this is sub par since the whitespace clearly still exists and can be 'seen' in the scrollbar styling)

HOWEVER even w/ setExtremes dataMin dataMax the scrollbar is still shown

Expected: graph is updated with more recent live data, window of time range in view for graph is updated IFF the min would otherwise be lower than the new dataMin, scrollbar should now see 'universe' as newDataMin - newDataMax (! oldDataMin - newDataMax which seems to be the case)

Actual: graph is updated with more recent data, window of time is not update automatically, Time that is no longer covered by query is now represented by ugly white space

EDIT:

```<code>void handleLiveUpdate(List agentSeries, int rangeStartTime) {
  // Needed to decide down the line if we should redraw graph
  var xAxisExtremesPreUpdate = chart["xAxis"][0].callMethod("getExtremes");

  // Updates the chart's data w/o forcing the graph to redraw itself
  // Updates the XAxis dataMin && dataMax attributes BUT NOT the min max attributes
  // (where the min/max attributes determine the window of time in view for the chart)
  chart.callMethod("update", [new js.JsObject.jsify({
    'series': agentSeries
  })]);

  // Decide if redrawing the graph would be disruptive or if it is required
  var xAxisExtremesPostUpdate = chart["xAxis"][0].callMethod("getExtremes");
  if (xAxisExtremesPreUpdate['max'] == xAxisExtremesPreUpdate['dataMax']
      && xAxisExtremesPreUpdate['min'] == xAxisExtremesPreUpdate['dataMin']) { /* Full View Case */
    // Keep entire TimeRange in view as window moves
    chart["xAxis"][0].callMethod("setExtremes", [xAxisExtremesPostUpdate['dataMin'], xAxisExtremesPostUpdate['dataMax'], true, true]);
//TODO scrollbar still visible.. why ?
  } else { /* Partial View Case */
    // Gather data on current extremes after updating the series.data
    var min = xAxisExtremesPostUpdate['min'];
    var max = xAxisExtremesPostUpdate['max'];
    var range = max - min;
    // Determine which partial view case we are in
    // 'Left Aligned' the min value before change was the dataMin before change
    // 'Right Aligned' the max value before change was the dataMax before change
    // 'Not Aligned' the min/max values do not correlate to the dataMin/dataMax values - indicates user had scrolled to some custom portion of time range
    if (xAxisExtremesPostUpdate['min'] < xAxisExtremesPostUpdate['dataMin']) { /* Partial View - Left Aligned (Ex looking at first hour of last 8 hours) */
      min = xAxisExtremesPostUpdate['dataMin'];
      max = min + range;
      chart["xAxis"][0].callMethod("setExtremes", [min, max, true, true]);
    } else if (xAxisExtremesPostUpdate['max'] == xAxisExtremesPreUpdate['dataMax']) { /* Partial View - Right Aligned (Ex looking at most recent week of last month) */
      max = xAxisExtremesPostUpdate['dataMax'];
      chart["xAxis"][0].callMethod("setExtremes", [max - range, max, true, true]);
    } else { /* Partial View - Not Aligned (Extremes do not touch dataMin dataMax => no need to redraw as window moves s*/
      // NO-OP: no need to redraw since moving window has no impact on window in view
    }
  }

  // Always update the floor attribute, prevents long lived charts from scrolling back to a time they no longer have data in hand for
  chart["xAxis"][0].callMethod("update", [new js.JsObject.jsify({
    'floor': rangeStartTime
  }), true]);
}
</code>```

EDIT 2: screenshots for illustration

W/ Current solution

W/ Solution Commented Out

JSFiddle Note: update there seems to update the xAxis as i would have expected.

答:
Instead of using the setExtremes method, you should update the axis with min and max properties:

```<code>chart.xAxis[0].update({
    min: chart.xAxis[0].dataMin,
    max: chart.xAxis[0].dataMax
});
</code>```

Live demo: https://jsfiddle.net/BlackLabel/y150hupz/

API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#update

Body:
After setting the extremes of a graph to dataMin and dataMax on the xAxis the xAxis scrollbar that is configured with showFull false still displays.

Background on how we get in this state:
We have a chart that gets updated data every 30 seconds, instead of redrawing we use chart.update w/ series attribute and redraw false.
this updates the dataMin dataMax attributes of the axis but not the min/max attributes (which control the window in view)

using logic to determine if we want to interrupt the users work flow we decide if it is necessary to call setExtremes w/ redraw true
-- NOTE: this is mainly required because otherwise the graph min can be bellow the dataMin for the axis (causing whitespace)
using floor and setExtremes i am able to partially resolve that problem by pushing the window in view to the updated time range and using floor to prevent them from scrolling back (tho this is sub par since the whitespace clearly still exists and can be 'seen' in the scrollbar styling)

HOWEVER even w/ setExtremes dataMin dataMax the scrollbar is still shown

Expected: graph is updated with more recent live data, window of time range in view for graph is updated IFF the min would otherwise be lower than the new dataMin, scrollbar should now see 'universe' as newDataMin - newDataMax (! oldDataMin - newDataMax which seems to be the case)

Actual: graph is updated with more recent data, window of time is not update automatically, Time that is no longer covered by query is now represented by ugly white space

EDIT:

void handleLiveUpdate(List agentSeries, int rangeStartTime) {
  // Needed to decide down the line if we should redraw graph
  var xAxisExtremesPreUpdate = chart["xAxis"][0].callMethod("getExtremes");

  // Updates the chart's data w/o forcing the graph to redraw itself
  // Updates the XAxis dataMin && dataMax attributes BUT NOT the min max attributes
  // (where the min/max attributes determine the window of time in view for the chart)
  chart.callMethod("update", [new js.JsObject.jsify({
    'series': agentSeries
  })]);

  // Decide if redrawing the graph would be disruptive or if it is required
  var xAxisExtremesPostUpdate = chart["xAxis"][0].callMethod("getExtremes");
  if (xAxisExtremesPreUpdate['max'] == xAxisExtremesPreUpdate['dataMax']
      && xAxisExtremesPreUpdate['min'] == xAxisExtremesPreUpdate['dataMin']) { /* Full View Case */
    // Keep entire TimeRange in view as window moves
    chart["xAxis"][0].callMethod("setExtremes", [xAxisExtremesPostUpdate['dataMin'], xAxisExtremesPostUpdate['dataMax'], true, true]);
//TODO scrollbar still visible.. why ?
  } else { /* Partial View Case */
    // Gather data on current extremes after updating the series.data
    var min = xAxisExtremesPostUpdate['min'];
    var max = xAxisExtremesPostUpdate['max'];
    var range = max - min;
    // Determine which partial view case we are in
    // 'Left Aligned' the min value before change was the dataMin before change
    // 'Right Aligned' the max value before change was the dataMax before change
    // 'Not Aligned' the min/max values do not correlate to the dataMin/dataMax values - indicates user had scrolled to some custom portion of time range
    if (xAxisExtremesPostUpdate['min'] < xAxisExtremesPostUpdate['dataMin']) { /* Partial View - Left Aligned (Ex looking at first hour of last 8 hours) */
      min = xAxisExtremesPostUpdate['dataMin'];
      max = min + range;
      chart["xAxis"][0].callMethod("setExtremes", [min, max, true, true]);
    } else if (xAxisExtremesPostUpdate['max'] == xAxisExtremesPreUpdate['dataMax']) { /* Partial View - Right Aligned (Ex looking at most recent week of last month) */
      max = xAxisExtremesPostUpdate['dataMax'];
      chart["xAxis"][0].callMethod("setExtremes", [max - range, max, true, true]);
    } else { /* Partial View - Not Aligned (Extremes do not touch dataMin dataMax => no need to redraw as window moves s*/
      // NO-OP: no need to redraw since moving window has no impact on window in view
    }
  }

  // Always update the floor attribute, prevents long lived charts from scrolling back to a time they no longer have data in hand for
  chart["xAxis"][0].callMethod("update", [new js.JsObject.jsify({
    'floor': rangeStartTime
  }), true]);
}

EDIT 2: screenshots for illustration

W/ Current solution

W/ Solution Commented Out

JSFiddle Note: update there seems to update the xAxis as i would have expected.

Body:
Instead of using the setExtremes method, you should update the axis with min and max properties:

chart.xAxis[0].update({
    min: chart.xAxis[0].dataMin,
    max: chart.xAxis[0].dataMax
});

Live demo: https://jsfiddle.net/BlackLabel/y150hupz/

API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#update


问:
Firebase realtime database : Does the user download the entire database every time?
I want the user to send some data to the database. But the downloaded data is a little high.
These are my rules:

```<code>{
  "rules": {
    ".read": false,
    ".write": true
  }
}
</code>```

In one day, the downloaded data has become 7.2 mb. The size of my database is around 320kb. This is my code where I'm using it.

```<code>String id = mDatabase.child(username).push().getKey();
Record r = new Record(calendar.getTimeInMillis(),sensorValue);
mDatabase.child(username).child(id).setValue(r);

</code>```

答:
A common source of unexpected bandwidth usage in the Firebase Realtime Database (and in Cloud Firestore, Firebase's other database), is the fact that any data shown in the Firebase console also counts towards your quota.

So in your case, if you've kept the database open in the Firebase console, and refreshed it 10 times over the day, or if you've opened the Firebase Database console 10 times in a day, you're already well on your way to explaining the bandwidth usage that you have.

Body:
I want the user to send some data to the database. But the downloaded data is a little high.
These are my rules:

{
  "rules": {
    ".read": false,
    ".write": true
  }
}

In one day, the downloaded data has become 7.2 mb. The size of my database is around 320kb. This is my code where I'm using it.

String id = mDatabase.child(username).push().getKey();
Record r = new Record(calendar.getTimeInMillis(),sensorValue);
mDatabase.child(username).child(id).setValue(r);


问:
RMagick: Get a list of available formats
With RMagick, is there any way to get a list of all the available image formats for writing to? I want to fill a <select> tag with all of the different writable formats.

答:
Ruby 1.9.2

```<code> Magick.formats.select {|image_format, mode_string| mode_string.include? 'w' }.keys.each do |image_format|
    puts image_format
 end
</code>```

Relevant Source for RMagick

https://github.com/rmagick/rmagick/blob/master/lib/RMagick.rb#L19

Mode String Information for RMagick

http://www.google.com/codesearch/p?hl=en#q35x35fKNI0/pub/distfiles/ruby/RMagick-1.7.0.tar.gz%7CYe7iosFBC-s/RMagick-1.7.0/ext/RMagick/rmmain.c&l=239

ContentLicense: CC BY-SA 3.0

Body:
Ruby 1.9.2

 Magick.formats.select {|image_format, mode_string| mode_string.include? 'w' }.keys.each do |image_format|
    puts image_format
 end

Relevant Source for RMagick

https://github.com/rmagick/rmagick/blob/master/lib/RMagick.rb#L19

Mode String Information for RMagick

http://www.google.com/codesearch/p?hl=en#q35x35fKNI0/pub/distfiles/ruby/RMagick-1.7.0.tar.gz%7CYe7iosFBC-s/RMagick-1.7.0/ext/RMagick/rmmain.c&l=239


问:
Prevent execution of command shell in a Makefile
The example below define a variable called GUNICORN_PID_FILE, this variable run the command cat to obtain the PID inside the file.

```<code>SHELL := /bin/sh

GUNICORN_PID_FILE := gunicorn.pid
GUNICORN_PID = "$(shell cat ${GUNICORN_PID_FILE})"
</code>```

The issue is when the file gunicorn.pid not exists.

```<code>cat: gunicorn.pid: No such file or directory
</code>```

Have a way to prevent this issue?

答:
This answer works like a charm. Simple use of a subprocess:</p>

```<code>GUNICORN_PID = "$$(cat ${GUNICORN_PID_FILE})"
</code>```

Body:
The example below define a variable called GUNICORN_PID_FILE, this variable run the command cat to obtain the PID inside the file.

SHELL := /bin/sh

GUNICORN_PID_FILE := gunicorn.pid
GUNICORN_PID = "$(shell cat ${GUNICORN_PID_FILE})"

The issue is when the file gunicorn.pid not exists.

cat: gunicorn.pid: No such file or directory

Have a way to prevent this issue?

Body:
This answer works like a charm. Simple use of a subprocess:

GUNICORN_PID = "$$(cat ${GUNICORN_PID_FILE})"


问:
How to replace emojis in html with twemoji?
In user-generated posts, I have many raw emojis like

```<code>   <p>I ❤ your post!</p>
</code>```

I'm wondering what is the best way to replace these emojis with colorful emojis like:

```<code> <p>I <i class="twa twa-heart">❤</i> your post!</p>
</code>```

I'd like to style the emojies with twemoji library.

You might ask why not let users insert the styled emojis at the first place while picking the emojis? The answer is that the interface's text editor is not WYSIWYG and the user posts are heavily stripped. So such option is ruled out and I'm looking for a solution that does this conversion at render time.

答:
Use an object, where the key is the stripped-back emoji, and the value is the full HTML content. Iterate through each character in the string and check if it's a stripped-back emoji. If so, replace it. Finally, join it all together and write to the page.

const raw = "
I ❤ your post!
";
const emojis = {
  "❤": `<i class="twa twa-heart">❤</i>`
};
const res = [...raw].map(e => emojis[e] || e).join("");
document.write(res);```

Body:
In user-generated posts, I have many raw emojis like

I ❤ your post!

I'm wondering what is the best way to replace these emojis with colorful emojis like:

I ❤ your post!

I'd like to style the emojies with twemoji library.

You might ask why not let users insert the styled emojis at the first place while picking the emojis? The answer is that the interface's text editor is not WYSIWYG and the user posts are heavily stripped. So such option is ruled out and I'm looking for a solution that does this conversion at render time.

Body:
Use an object, where the key is the stripped-back emoji, and the value is the full HTML content. Iterate through each character in the string and check if it's a stripped-back emoji. If so, replace it. Finally, join it all together and write to the page.

const raw = "<p>I ❤ your post!</p>";
const emojis = {
  "❤": `<i class="twa twa-heart">❤</i>`
};
const res = [...raw].map(e => emojis[e] || e).join("");
document.write(res);


问:
Error while testing: found multiple declaration of @BootstrapWith for test class
I would like to test my CRUD REST Controller for the first time. I have watched some videos and come up with this idea but I am getting error. I am using JPA with mySql. ITodoService is simple interface with CRUD methods. My rest Controller is working when I test it via Postman, so code there is ok.
If you could give me some feedback what might be wrong and where can I check for good imformation about testing REST app because I have spent like 3 hrs without any success :) </p>

```<code>    @SpringBootTest
    @RunWith(SpringRunner.class)
    @WebMvcTest
    public class TodoFinalApplicationTests {

        @Autowired
        private MockMvc mockMvc;

        @MockBean
        private ITodosService iTodosService;

        @Test
        public void getAllTodosTest() throws Exception {

            Mockito.when(iTodosService.findAll()).thenReturn(
                        Collections.emptyList()
                        );

                        MvcResult mvcResult = mockMvc.perform(
                        MockMvcRequestBuilders.get("/todos")
                        .accept(MediaType.APPLICATION_JSON)
                        ).andReturn();

                        System.out.println(mvcResult.getResponse());

                        Mockito.verify(iTodosService.findAll());

        }
    }

    Error message:
    java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [com.damian.todo_Final.TodoFinalApplicationTests]: [@org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper), @org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper)]

EDIT:
This is code for whole CRUD REST Test
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest(classes = TodoFinalApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
// @WebMvcTest
public class TodoFinalApplicationTests {

    @Autowired
    private TestRestTemplate restTemplate;

    @LocalServerPort
    private int port;

    private String getRootUrl() {
            return "http://localhost:" + port;
    }

    @Test
    public void contextLoads() {

    }

    @Test
    public void getAllTodos() {

        HttpHeaders headers = new HttpHeaders();
        HttpEntity<String> entity = new HttpEntity<String>(null, headers);
        ResponseEntity<String> response = restTemplate.exchange(getRootUrl() + "/employees",
                HttpMethod.GET, entity, String.class);
        assertNotNull(response.getBody());

    }

    @Test
    public void createNewTodo() {

        Todos todo = new Todos();
        todo.setId(5);
        todo.setTaskDate("15.01.1990");
        todo.setTaskStatus(true);
        todo.setTaskDescritpion("Description for testing");

        ResponseEntity<Todos> postResponse = restTemplate.postForEntity(getRootUrl() + "/todos", todo, Todos.class);
        assertNotNull(postResponse);
        assertNotNull(postResponse.getBody());

    }

    @Test
    public void testUpdateTodo() {
        int id = 1;
        Todos todo = restTemplate.getForObject(getRootUrl() + "/todos/" + id, Todos.class);
        todo.setTaskDate("15.01.1990");
        todo.setTaskStatus(true);
        todo.setTaskDescritpion("Updating");
        restTemplate.put(getRootUrl() + "/todos/" + id, todo);
        Todos updatedTodo = restTemplate.getForObject(getRootUrl() + "/todos/" + id, Todos.class);
        assertNotNull(updatedTodo);

    }

    @Test
    public void testDeletedTodo() {
        int id = 3;
        Todos todo = restTemplate.getForObject(getRootUrl() + "/todos/" + id, Todos.class);
        assertNotNull(todo);
        restTemplate.delete(getRootUrl() + "/todos/" + id);
        try {
            todo = restTemplate.getForObject(getRootUrl() + "/todos/" + id, Todos.class);
        } catch (final HttpClientErrorException e) {
            assertEquals(e.getStatusCode(), HttpStatus.NOT_FOUND);
        }
    }
</code>```

答:
You have both @SpringBootTest and @WebMvcTest on one test class. Both classes, among others, specify only what beans should be instantiated in the test context.
The definitions are conflicting, so only one is allowed.

Decide if you want to test:

entire application context - use @SpringBootTest

only controllers - use @WebMvcTest

In your case, I would:

remove @SpringBootTest

specify Controller you want to test in @WebMvcTest

Alternatively, you can

remove @WebMvTest

add AutoConfigureWebMvc

@SpringBootTest brings all beans into context, and thus @WebMvcTest will likely result in a faster test.

Body:
I would like to test my CRUD REST Controller for the first time. I have watched some videos and come up with this idea but I am getting error. I am using JPA with mySql. ITodoService is simple interface with CRUD methods. My rest Controller is working when I test it via Postman, so code there is ok.
If you could give me some feedback what might be wrong and where can I check for good imformation about testing REST app because I have spent like 3 hrs without any success :)

    @SpringBootTest
    @RunWith(SpringRunner.class)
    @WebMvcTest
    public class TodoFinalApplicationTests {

        @Autowired
        private MockMvc mockMvc;

        @MockBean
        private ITodosService iTodosService;

        @Test
        public void getAllTodosTest() throws Exception {

            Mockito.when(iTodosService.findAll()).thenReturn(
                        Collections.emptyList()
                        );

                        MvcResult mvcResult = mockMvc.perform(
                        MockMvcRequestBuilders.get("/todos")
                        .accept(MediaType.APPLICATION_JSON)
                        ).andReturn();

                        System.out.println(mvcResult.getResponse());

                        Mockito.verify(iTodosService.findAll());

        }
    }

    Error message:
    java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [com.damian.todo_Final.TodoFinalApplicationTests]: [@org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper), @org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper)]

EDIT:
This is code for whole CRUD REST Test
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest(classes = TodoFinalApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
// @WebMvcTest
public class TodoFinalApplicationTests {

    @Autowired
    private TestRestTemplate restTemplate;

    @LocalServerPort
    private int port;

    private String getRootUrl() {
            return "http://localhost:" + port;
    }

    @Test
    public void contextLoads() {

    }

    @Test
    public void getAllTodos() {

        HttpHeaders headers = new HttpHeaders();
        HttpEntity<String> entity = new HttpEntity<String>(null, headers);
        ResponseEntity<String> response = restTemplate.exchange(getRootUrl() + "/employees",
                HttpMethod.GET, entity, String.class);
        assertNotNull(response.getBody());

    }

    @Test
    public void createNewTodo() {

        Todos todo = new Todos();
        todo.setId(5);
        todo.setTaskDate("15.01.1990");
        todo.setTaskStatus(true);
        todo.setTaskDescritpion("Description for testing");

        ResponseEntity<Todos> postResponse = restTemplate.postForEntity(getRootUrl() + "/todos", todo, Todos.class);
        assertNotNull(postResponse);
        assertNotNull(postResponse.getBody());

    }

    @Test
    public void testUpdateTodo() {
        int id = 1;
        Todos todo = restTemplate.getForObject(getRootUrl() + "/todos/" + id, Todos.class);
        todo.setTaskDate("15.01.1990");
        todo.setTaskStatus(true);
        todo.setTaskDescritpion("Updating");
        restTemplate.put(getRootUrl() + "/todos/" + id, todo);
        Todos updatedTodo = restTemplate.getForObject(getRootUrl() + "/todos/" + id, Todos.class);
        assertNotNull(updatedTodo);

    }

    @Test
    public void testDeletedTodo() {
        int id = 3;
        Todos todo = restTemplate.getForObject(getRootUrl() + "/todos/" + id, Todos.class);
        assertNotNull(todo);
        restTemplate.delete(getRootUrl() + "/todos/" + id);
        try {
            todo = restTemplate.getForObject(getRootUrl() + "/todos/" + id, Todos.class);
        } catch (final HttpClientErrorException e) {
            assertEquals(e.getStatusCode(), HttpStatus.NOT_FOUND);
        }
    }


问:
Resource blocked due to MIME type?
For many years I have successfully included javscript files which are dynamically created.

Here is an example:
https://granadainfo.com/sups.php?locs=95

As you can see it loads OK.

I usually put them into the head of my html document like this.

script type="text/javascript" src="https://granadainfo.com/sups.php?locs=95"

/script

In the last few days they have stopped working.

The error message from firefox debugger console is the following.

The resource from “https://granadainfo.com/sups.php?locs=95” was blocked due to MIME type (“text/html”) mismatch (X-Content-Type-Options: nosniff).

I use a2 web hosting. They must have made some change in configuration to make it stop working.

It may be that I can get over this problem with a line in the .htaccess file.

A2 hosting suggested this line but it does not work.
Header always unset X-Frame-Options

The problem only happen when there is a get request.
ie ?locs=95

There is no problem with static files.

I tried changing the file name to .js and changed the .htaccess file to parse .js as php but it makes no difference.

答:
The advanced support of A2 hosting eventually got back to me with a good answer.
The following is based on what they said and it does solve the problem.

There is a simple solution.

For security reasons, we recently set "X-Content-Type-Options" to "nosniff" by default on all of our servers. If the option was not manually set in your ".htaccess" file, then the site just defaulted to whatever the server was using (nosniff). This is what was causing the error on the site.

Earlier in this ticket, you were told to unset the "X-Frame-Options" header mistakenly because that option is only for iframes. The actual header you needed to unset was "X-Content-Type-Options".

This is the line to add to the top of your .htaccess file.

Header always unset X-Content-Type-Options

Title: Resource blocked due to MIME type?


问:
Sharepoint c# retrieve all site and subsite
I'am trying to retrieve all site and subsite in sharepoint but i get access denied.

I read about to use GetSubwebsForCurrentUser() property, but i get the same message.

My code is the next

```<code>            foreach (SPWebApplication webApp in SPWebService.ContentService.WebApplications)
            {
                foreach (SPSite siteCollection in webApp.Sites)
                {
                    foreach(SPWeb web in siteCollection.RootWeb.GetSubwebsForCurrentUser())
                    {
                       dropDownSite.Items.Add(web.Url);
                    }

                }
            }
</code>```

please i need help! Thanks!

答:
Just to make sure, is this code running on the server that is hosting the Sharepoint portal?  What version of Sharepoint are you running?

Also, would it make sense to use the Webservices that Sharepoint exposes?
http://msdn.microsoft.com/en-us/library/aa979690(v=office.12).aspx

If you are running this code on the same server as SP, then make sure that your credentials have access to SP.  If you are calling this from a website, also make sure that you are not running as "Anonymous".

Over all, I think taking advantage of the webservices is the easiest way to get it working.  But make sure that you have the right permissions being sent and that that user has access (in the SP configurations) to that data.

Hope that helps!

Body:
I'am trying to retrieve all site and subsite in sharepoint but i get access denied.

I read about to use GetSubwebsForCurrentUser() property, but i get the same message.

My code is the next

            foreach (SPWebApplication webApp in SPWebService.ContentService.WebApplications)
            {
                foreach (SPSite siteCollection in webApp.Sites)
                {
                    foreach(SPWeb web in siteCollection.RootWeb.GetSubwebsForCurrentUser())
                    {
                       dropDownSite.Items.Add(web.Url);
                    }

                }
            }

please i need help! Thanks!


问:
How to add admin user name and password field for particular Variable of Object?
I want to add Username and Password for the particular Variable of the Object.

Like when we get to see all other variables of that object on User Interface, only that variable will be password protected.

And when user wants to see the content of that field, he has to enter User Name and Password which was entered during submission of that field.

Output could be like:

Click Show button to show field   "Show"

When clicked: Enter User Name and Password.

When User Name and Password is entered Correct: Field's content is shown.

But, field should be displayed on the same page where "Show" button was there.

答: If you are using Angular JS, why not disable the view of the field of the object for the user by default and have an option to enter the password to read it. Validate it and if successful, enable the view of the field.


问:
How to Maintain the State of CollectionView over different Segments (Tab)
I'm having a collection View flow layout added as a subview inside segmented control. The Segment is Categorised into All, New, Used.
My problem is how can I maintain the state of the collection view over different Segments.

I'm Making API Calls for Loading the Data on All, New, Used segments

Also Each time when I switch the Tab I'm calling [collectionView reloadData] Which reloads the collection view but not exactly the position where I left earlier in that particular segment

For example in All Segment I have Scrolled 10 - 15 items then i'm switching to New Segment and scrolling 3 Items and Now if I again Switch the Tab to All Segment then the Position of All Segment also goes to 3rd position

How can this be resolved. Thank you for reading patiently. Any Help would help me a lot.

Here is the sample code which I use for switching the Segment

```<code>-(IBAction)changeSeg:(id)sender{
    [collectionView reloadData];

    if(segmentedControl.selectedSegmentIndex == 0){
atScrollPosition:UICollectionViewScrollPositionNone animated:false];
        typeFlag = 0;
        if ([inventoryDetails count] == 0 && totalInventoryCountForAll != 0) {
            [self loadMore];
        } else if (totalInventoryCountForAll == 0) {
            [self setNoCarVisibility: true];
        }
    }
    else if(segmentedControl.selectedSegmentIndex == 1){
        typeFlag = 1;
        if ([newInventory count] == 0 && totalInventoryCountForNew != 0) {
            [self loadMore];
        } else if (totalInventoryCountForNew == 0) {
            [self setNoCarVisibility: true];
        }
    }
    else if(segmentedControl.selectedSegmentIndex == 2){
        typeFlag = 2;
        if([usedInventory count] == 0 && totalInventoryCountForUsed != 0){
            [self loadMore];
        } else if (totalInventoryCountForUsed == 0) {
            [self setNoCarVisibility: true];
        }
    }

}
</code>```

答:
So, Finally I got the Quick Solution as Follows:

1). I have created three Collection View for All, New, Used

2). Created the required Outlet Connection, Data Source and delegates for All three collection Views

3). The trick is to hide and show the collection view for currently selected segment.

4). But I face a minor issue here. The first Collection View (All Tab in my case) needs to be the last item on Interface builder, then only it will be shown when loading the collection view initially.

5). Whenever I switch the Tabs, I hide other two collection views and show the currently selected Tab's Collection view.

This may not be the correct solution. But for time being I did this.

Body:
I'm having a collection View flow layout added as a subview inside segmented control. The Segment is Categorised into All, New, Used.
My problem is how can I maintain the state of the collection view over different Segments.

I'm Making API Calls for Loading the Data on All, New, Used segments

Also Each time when I switch the Tab I'm calling [collectionView reloadData] Which reloads the collection view but not exactly the position where I left earlier in that particular segment

For example in All Segment I have Scrolled 10 - 15 items then i'm switching to New Segment and scrolling 3 Items and Now if I again Switch the Tab to All Segment then the Position of All Segment also goes to 3rd position

How can this be resolved. Thank you for reading patiently. Any Help would help me a lot.

Here is the sample code which I use for switching the Segment

-(IBAction)changeSeg:(id)sender{
    [collectionView reloadData];

    if(segmentedControl.selectedSegmentIndex == 0){
atScrollPosition:UICollectionViewScrollPositionNone animated:false];
        typeFlag = 0;
        if ([inventoryDetails count] == 0 && totalInventoryCountForAll != 0) {
            [self loadMore];
        } else if (totalInventoryCountForAll == 0) {
            [self setNoCarVisibility: true];
        }
    }
    else if(segmentedControl.selectedSegmentIndex == 1){
        typeFlag = 1;
        if ([newInventory count] == 0 && totalInventoryCountForNew != 0) {
            [self loadMore];
        } else if (totalInventoryCountForNew == 0) {
            [self setNoCarVisibility: true];
        }
    }
    else if(segmentedControl.selectedSegmentIndex == 2){
        typeFlag = 2;
        if([usedInventory count] == 0 && totalInventoryCountForUsed != 0){
            [self loadMore];
        } else if (totalInventoryCountForUsed == 0) {
            [self setNoCarVisibility: true];
        }
    }

}


问:
Center Conditional Icon Set Icons over Data
I the only answer I've been able to find on the web is that you can't do it. I know that is not true at least with Excel 2016 because Microsoft did it them selves in the College Move Checklist template.

The problem is I can't seem to find the settings to get it to work. I've been through all the rules and formatting but can't find it. I was able to copy and paste it to work in some of the items I needed it for but I needed to make it from scratch for others.

Does anyone know how to acheive this?

答:
Edit the conditional format and check the "Show Icon Only" checkbox.  This will remove the data from visibility and show only the icon, which will then adhere to the alignment you specify.

This answer from the comment by Axel Richter


问:
SSIS to do Insert, Update, and Deletes
I have been able to get my SSIS process to handle the Insert and Updates using Sorts, Merge Join, and conditional split.

I am not sure how I could handle the delete on my destination table because my merge join is a left join operation off the source (So I can handle inserts).  How have others handled this scnerio? I tried changing to a full outer join so I could look for a null in the source, but that didn't seem to work?

Flow (Sources: Source and Destination, Sorts: Source and Destination, Merge Join, Conditional Split: Insert and Update).

答:
Not sure if this will be what you want to do, but since the question has no responses, thought I would mention MERGE If you are running SQL Server 2008.  You could add a SQL Task to SSIS and code the query handle the inserts, updates, deletes, or any subset as needed:

Here is the MS documentation:
http://technet.microsoft.com/en-us/library/bb510625.aspx

Title: SSIS to do Insert, Update, and Deletes


问:
Pixel width of monospace character
I am wondering, is it possible to calculate the pixel width of a character in a monospace font?
I am using monospace fonts because I need every character to occupy the same width in my DIV, but I am unsure how to reliably get the actual pixel width of it. I need to fix the width in order to do calculations in JavaScript.
Here's my css:

```<code>font-family: monospace;
font-size: 15px;
</code>```

Is this possible?

答:
I've faced with the same question and decided to make a calculator))

Using test-span with 10000 symbols and it's offsetWidth;

Run the snippet below and click 'OK'.

JsFiddle

(function(){

let test = document.getElementById('test');
let font = document.getElementById('font');
let size = document.getElementById('size');

document.getElementById('le').innerText = "Test length: " + test.innerText.length + " symbols.";

document.getElementById('ok').addEventListener('click', function(){
  test.style.fontFamily = font.value;
  test.style.fontSize = parseFloat( size.value ) + 'px';
  document.getElementById('result').innerText = 'Your font-width: ' + test.offsetWidth / 10000 + 'px';
});

})();```
<pre class="snippet-code-html lang-html prettyprint-override"><code><h2>Input Font-family and font-size:</h2>

<input id="font" placeholder="font-family:" value='"Lucida Console", Monaco'>
<input id="size" placeholder="font-size:" value="18">
<button id="ok">OK</button>
<p id="result"></p>

<p id="le"></p><span id="test">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span></code>```

Title: Pixel width of monospace character

Body:
I am wondering, is it possible to calculate the pixel width of a character in a monospace font?
I am using monospace fonts because I need every character to occupy the same width in my DIV, but I am unsure how to reliably get the actual pixel width of it. I need to fix the width in order to do calculations in JavaScript.
Here's my css:

font-family: monospace;
font-size: 15px;

Is this possible?

Body:
I've faced with the same question and decided to make a calculator))

Using test-span with 10000 symbols and it's offsetWidth;

Run the snippet below and click 'OK'.

JsFiddle

(function(){

let test = document.getElementById('test');
let font = document.getElementById('font');
let size = document.getElementById('size');

document.getElementById('le').innerText = "Test length: " + test.innerText.length + " symbols.";

document.getElementById('ok').addEventListener('click', function(){
  test.style.fontFamily = font.value;
  test.style.fontSize = parseFloat( size.value ) + 'px';
  document.getElementById('result').innerText = 'Your font-width: ' + test.offsetWidth / 10000 + 'px';
});

})();

<h2>Input Font-family and font-size:</h2>

<input id="font" placeholder="font-family:" value='"Lucida Console", Monaco'>
<input id="size" placeholder="font-size:" value="18">
<button id="ok">OK</button>
<p id="result"></p>

<p id="le"></p><span id="test">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span>


问:
Creating a mysql docker container setting env variables
I am using the spotify-docker-client to create and start a mysql container for testing. It works perfect, but I am having a hard time trying to find how to set certain values to connect to the database like MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, and MYSQL_PASSWORD. This is my code:

```<code>final ContainerConfig containerConfig = ContainerConfig.builder()
        .hostConfig(hostConfig)
        .image(image)
        .env("MYSQL_ROOT_PASSWORD","testrootpwd","MYSQL_DATABASE", "test", "MYSQL_USER", "test", "MYSQL_PASSWORD", "test")
        .build();

LOG.debug("Creating container for image: {}", image);
final ContainerCreation creation = this.docker.createContainer(containerConfig);
</code>```

I am assuming that .env call is to set environment variables. And according to the mysql container documentation, setting those env variables is the way to do it:

https://hub.docker.com/_/mysql

But still, I can't connect to the container, I connected to bash and I see that those env variables are not set.

Does anyone know how to do it?

I could create a dockerfile and create my own image, but I don't want to do that, I want to do it with the spotify client.

答:
This client uses docker API, so if the client is lacking documentation you can always check the original API.
Check the CREATE A CONTAINER section in Docker Engine API.

You can see that there is a JSON request example with env field:

```<code>"Env": [
           "FOO=bar",
           "BAZ=quux"
],
</code>```

So my guess is that you can do just that in your Java code:

```<code>final ContainerConfig containerConfig = ContainerConfig.builder()
    .hostConfig(hostConfig)
    .image(image)
    .env("MYSQL_ROOT_PASSWORD=testrootpwd", "MYSQL_DATABASE=test", ...)
    .build();
</code>```

P.S. Also please note what the documentation says regarding this param:

A list of environment variables to set inside the container in the
form ["VAR=value", ...].  A variable without = is removed from the
environment, rather than to have an empty value.

Might help you avoiding bugs later.

Body:
I am using the spotify-docker-client to create and start a mysql container for testing. It works perfect, but I am having a hard time trying to find how to set certain values to connect to the database like MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, and MYSQL_PASSWORD. This is my code:

final ContainerConfig containerConfig = ContainerConfig.builder()
        .hostConfig(hostConfig)
        .image(image)
        .env("MYSQL_ROOT_PASSWORD","testrootpwd","MYSQL_DATABASE", "test", "MYSQL_USER", "test", "MYSQL_PASSWORD", "test")
        .build();

LOG.debug("Creating container for image: {}", image);
final ContainerCreation creation = this.docker.createContainer(containerConfig);

I am assuming that .env call is to set environment variables. And according to the mysql container documentation, setting those env variables is the way to do it:

https://hub.docker.com/_/mysql

But still, I can't connect to the container, I connected to bash and I see that those env variables are not set.

Does anyone know how to do it?

I could create a dockerfile and create my own image, but I don't want to do that, I want to do it with the spotify client.

Body:
This client uses docker API, so if the client is lacking documentation you can always check the original API.
Check the CREATE A CONTAINER section in Docker Engine API.

You can see that there is a JSON request example with env field:

"Env": [
           "FOO=bar",
           "BAZ=quux"
],

So my guess is that you can do just that in your Java code:

final ContainerConfig containerConfig = ContainerConfig.builder()
    .hostConfig(hostConfig)
    .image(image)
    .env("MYSQL_ROOT_PASSWORD=testrootpwd", "MYSQL_DATABASE=test", ...)
    .build();

P.S. Also please note what the documentation says regarding this param:

A list of environment variables to set inside the container in the
form ["VAR=value", ...].  A variable without = is removed from the
environment, rather than to have an empty value.

Might help you avoiding bugs later.


问:
Images are not loading after deploying angular app on github pages
I deployed a test project on github pages using these commands:

```<code>ng build --prod --base-href https://<profile_name>.github.io/<repo_name>/
ngh --dir=dist/scrabble
</code>```

Everything works fine except images (on localhost every image is loading).

outputPath in angular.json:

```<code>"outputPath": "dist/scrabble/",
</code>```

assets in angular.json:

```<code>"assets": [
  "src/favicon.ico",
  "src/assets"
],
</code>```

assets folder with images is located in <project_folder>/src/assets

one example of image tag which works perfectly on localhost but doesn't load on github pages:

```<code>  <img src="../../../assets/scaledlogo.png" routerLink="/menu" />
</code>```

答:
If all your images are in your assets folder you can just remove the ../s form the path.

```<code> <img src="assets/scaledlogo.png" routerLink="/menu" />
</code>```

So the issue is everything gets transpiled and minified and the assets folder is no longer 3 directories back. Angular knows where your assets folder is if you are running it locally or its deployed and does not need the relative path.

Body:
I deployed a test project on github pages using these commands:

ng build --prod --base-href https://<profile_name>.github.io/<repo_name>/
ngh --dir=dist/scrabble

Everything works fine except images (on localhost every image is loading).

outputPath in angular.json:

"outputPath": "dist/scrabble/",

assets in angular.json:

"assets": [
  "src/favicon.ico",
  "src/assets"
],

assets folder with images is located in <project_folder>/src/assets

one example of image tag which works perfectly on localhost but doesn't load on github pages:

Body:
If all your images are in your assets folder you can just remove the ../s form the path.

 <img src="assets/scaledlogo.png" routerLink="/menu" />

So the issue is everything gets transpiled and minified and the assets folder is no longer 3 directories back. Angular knows where your assets folder is if you are running it locally or its deployed and does not need the relative path.


问:
How can I delete multipe lines in a text by Python?
I have a similar question to delete multiple line

I want to delete the line and the next 4 lines. This is my code:

```<code>bind = open('/etc/bind/named.conf.local','r')
a = dict['name']
for line in bind:
        if a in line:
            print('line  exist')
            ''' and delete this line and 4 line after it'''
        else:
            print('line does not exist')
</code>```

I want to save modify text in /etc/bind/named.conf.local in place, without fileinput. I do not want skip 4 line I want to delete them from the file. I do not want to read it and write it again and skip 4 lines.

What should I do?

答:
```<code>bind = open('text.txt','r')
a = dict['name']
lines = bind.readlines()
i = 0
while i < len(lines):
    if a in lines[i]:
        del lines[i:i+5]
    i += 1
print(lines)
</code>```

Body:
I have a similar question to delete multiple line

I want to delete the line and the next 4 lines. This is my code:

bind = open('/etc/bind/named.conf.local','r')
a = dict['name']
for line in bind:
        if a in line:
            print('line  exist')
            ''' and delete this line and 4 line after it'''
        else:
            print('line does not exist')

I want to save modify text in /etc/bind/named.conf.local in place, without fileinput. I do not want skip 4 line I want to delete them from the file. I do not want to read it and write it again and skip 4 lines.

What should I do?


问:
Ansible : how to pass "{{ABC}}" as a string
Under my jinja file i ve this line

```<code>- mockString= "{{ABC}}"
</code>```

My mockString must have the exacte value "{{ABC}}" where the first letter is " , the second is { the third is also {  ect...

Now when converting my template file ; it seems that i sees "{{ABC}}" as a variable , where it tries to interpret and change by its value , what is not my purpose.

How may i pass it as a simple string

Suggestions ??

答:
you can try like this :</p>

```<code>  mockString= \"{{ACB}}\"
</code>```

Body:
Under my jinja file i ve this line

- mockString= "{{ABC}}"

My mockString must have the exacte value "{{ABC}}" where the first letter is " , the second is { the third is also {  ect...

Now when converting my template file ; it seems that i sees "{{ABC}}" as a variable , where it tries to interpret and change by its value , what is not my purpose.

How may i pass it as a simple string

Suggestions ??

Body:
you can try like this :

  mockString= \"{{ACB}}\"


问:
Evaluate nans slices size
I have a spark dataframe with some null values in a column. I need to count the contiguous null values preceding a non null value.

Using numpy I'd do something like this (the code is not optimized for numpy because I'm trying not to use it in my problem):

import numpy as np

x = np.array([[0, None], [1, 3.], [2, 7.], [3, None], [4, 4.], [5, 3.],
              [6, None], [7, None], [8, 5.], [9, 2.], [10, None]])

def nan_count(l, n):
    assert n <= len(l) + 1
    assert n >= 0

    if n < 1 or l[n-1] is not None:
        return 0
    return nan_count(l, n-1) + 1

y = map(lambda i: nan_count(x[:,1], i), x[:,0])
res = np.concatenate([x, np.asarray(y).reshape(-1,1)], axis = 1)
res
```

<p>So that the output looks like this:</p>

<pre class="lang-py prettyprint-override"><code>Out[31]: [0, 1, 0, 0, 1, 0, 0, 1, 2, 0, 0]
</code>```

Now, if I have a spark DataFrame like x:

```<code>x = sc.parallelize([[0, None], [1, 3.], [2, 7.], [3, None], [4, 4.],
                    [5, 3.], [6, None], [7, None], [8, 5.], [9, 2.], [10, None]])\
      .toDF()
x.show()
</code>```

```<code>+---+----+
| _1|  _2|
+---+----+
|  0|null|
|  1| 3.0|
|  2| 7.0|
|  3|null|
|  4| 4.0|
|  5| 3.0|
|  6|null|
|  7|null|
|  8| 5.0|
|  9| 2.0|
| 10|null|
+---+----+
</code>```

How do I obtain the same output?

I've altready tried some workarouds using udf, but I have problems in referencing the value before the one selected (I tried using select and filter pyspark.sql.dataframe.DataFrame methods inside the udf, but it is not allowed).

EDIT: I do not know how many consecutive nans I might find.

答:
I putted comments into code to explain each step until reach the desired output.

Of course it's unnecessary create all columns from example below and probably this code can be a lot improved, but I think it's important show you step by step and do a initial kick off to solve your question.

x = sc.parallelize([
    [0, None],
    [1, 3.],
    [2, 7.],
    [3, None],
    [4, 4.],
    [5, 3.],
    [6, None],
    [7, None],
    [8, 5.],
    [9, 2.],
    [10, None]
])
# Assigned values in columns A and B to facilitate manipulation
x = x.toDF(['A', 'B'])

# Prints initial DF
x.show()
```

<p>Output:</p>

```+---+----+
|  A|   B|
+---+----+
|  0|null|
|  1| 3.0|
|  2| 7.0|
|  3|null|
|  4| 4.0|
|  5| 3.0|
|  6|null|
|  7|null|
|  8| 5.0|
|  9| 2.0|
| 10|null|
+---+----+
```

<pre class="lang-py prettyprint-override"><code># Transform null values into "1"
x = x.withColumn('C', when(x.B.isNull(), 1))
x.show()
</code>```

Output:

```<code>+---+----+----+
|  A|   B|   C|
+---+----+----+
|  0|null|   1|
|  1| 3.0|null|
|  2| 7.0|null|
|  3|null|   1|
|  4| 4.0|null|
|  5| 3.0|null|
|  6|null|   1|
|  7|null|   1|
|  8| 5.0|null|
|  9| 2.0|null|
| 10|null|   1|
+---+----+----+
</code>```

# Creates a spec that order column A
order_spec = Window().orderBy('A')

# Doing a cumulative sum. See the explanation
# https://stackoverflow.com/questions/56384625/pyspark-cumulative-sum-with-reset-condition
x = x \
    .withColumn('tmp', sum((x.C.isNull()).cast('int')).over(order_spec)) \
    .withColumn('D', sum(x.C).over(order_spec.partitionBy("tmp"))) \
    .drop('tmp')
x.show()
```

<p>Output:</p>

```+---+----+----+----+
|  A|   B|   C|   D|
+---+----+----+----+
|  0|null|   1|   1|
|  1| 3.0|null|null|
|  2| 7.0|null|null|
|  3|null|   1|   1|
|  4| 4.0|null|null|
|  5| 3.0|null|null|
|  6|null|   1|   1|
|  7|null|   1|   2|
|  8|null|   1|   3|
|  9| 5.0|null|null|
| 10| 2.0|null|null|
| 11|null|   1|   1|
+---+----+----+----+
```

<pre class="lang-py prettyprint-override"><code># Put values from column D to one row above and select the desired output values
x = x.withColumn('E', lag(x.D, ).over(order_spec)) \
    .select(x.A, x.B, when(col('E').isNotNull(), col('E')).otherwise(0).alias('nan_count'))
x.show()
</code>```

Output:

```<code>+---+----+---------+
|  A|   B|nan_count|
+---+----+---------+
|  0|null|        0|
|  1| 3.0|        1|
|  2| 7.0|        0|
|  3|null|        0|
|  4| 4.0|        1|
|  5| 3.0|        0|
|  6|null|        0|
|  7|null|        1|
|  8|null|        2|
|  9| 5.0|        3|
| 10| 2.0|        0|
| 11|null|        0|
+---+----+---------+
</code>```

Entire code:

from pyspark.shell import sc
from pyspark.sql import Window
from pyspark.sql.functions import lag, when, sum, col

x = sc.parallelize([
    [0, None], [1, 3.], [2, 7.], [3, None], [4, 4.],
    [5, 3.], [6, None], [7, None], [8, None], [9, 5.], [10, 2.], [11, None]])
x = x.toDF(['A', 'B'])

# Transform null values into "1"
x = x.withColumn('C', when(x.B.isNull(), 1))

# Creates a spec that order column A
order_spec = Window().orderBy('A')

# Doing a cumulative sum with reset condition. See the explanation
# https://stackoverflow.com/questions/56384625/pyspark-cumulative-sum-with-reset-condition
x = x \
    .withColumn('tmp', sum((x.C.isNull()).cast('int')).over(order_spec)) \
    .withColumn('D', sum(x.C).over(order_spec.partitionBy("tmp"))) \
    .drop('tmp')

# Put values from column D to one row above and select the desired output values
x = x.withColumn('E', lag(x.D, ).over(order_spec)) \
    .select(x.A, x.B, when(col('E').isNotNull(), col('E')).otherwise(0).alias('nan_count'))
x.show()
```

Title: Evaluate nans slices size

Body:
I have a spark dataframe with some null values in a column. I need to count the contiguous null values preceding a non null value.

Using numpy I'd do something like this (the code is not optimized for numpy because I'm trying not to use it in my problem):

import numpy as np

x = np.array([[0, None], [1, 3.], [2, 7.], [3, None], [4, 4.], [5, 3.],
              [6, None], [7, None], [8, 5.], [9, 2.], [10, None]])

def nan_count(l, n):
    assert n <= len(l) + 1
    assert n >= 0

    if n < 1 or l[n-1] is not None:
        return 0
    return nan_count(l, n-1) + 1

y = map(lambda i: nan_count(x[:,1], i), x[:,0])
res = np.concatenate([x, np.asarray(y).reshape(-1,1)], axis = 1)
res

So that the output looks like this:

Out[31]: [0, 1, 0, 0, 1, 0, 0, 1, 2, 0, 0]

Now, if I have a spark DataFrame like x:

x = sc.parallelize([[0, None], [1, 3.], [2, 7.], [3, None], [4, 4.],
                    [5, 3.], [6, None], [7, None], [8, 5.], [9, 2.], [10, None]])\
      .toDF()
x.show()

+---+----+
| _1|  _2|
+---+----+
|  0|null|
|  1| 3.0|
|  2| 7.0|
|  3|null|
|  4| 4.0|
|  5| 3.0|
|  6|null|
|  7|null|
|  8| 5.0|
|  9| 2.0|
| 10|null|
+---+----+

How do I obtain the same output?

I've altready tried some workarouds using udf, but I have problems in referencing the value before the one selected (I tried using select and filter pyspark.sql.dataframe.DataFrame methods inside the udf, but it is not allowed).

EDIT: I do not know how many consecutive nans I might find.

Body:
I putted comments into code to explain each step until reach the desired output.

Of course it's unnecessary create all columns from example below and probably this code can be a lot improved, but I think it's important show you step by step and do a initial kick off to solve your question.

x = sc.parallelize([
    [0, None],
    [1, 3.],
    [2, 7.],
    [3, None],
    [4, 4.],
    [5, 3.],
    [6, None],
    [7, None],
    [8, 5.],
    [9, 2.],
    [10, None]
])
# Assigned values in columns A and B to facilitate manipulation
x = x.toDF(['A', 'B'])

# Prints initial DF
x.show()

Output:

+---+----+
|  A|   B|
+---+----+
|  0|null|
|  1| 3.0|
|  2| 7.0|
|  3|null|
|  4| 4.0|
|  5| 3.0|
|  6|null|
|  7|null|
|  8| 5.0|
|  9| 2.0|
| 10|null|
+---+----+

# Transform null values into "1"
x = x.withColumn('C', when(x.B.isNull(), 1))
x.show()

Output:

+---+----+----+
|  A|   B|   C|
+---+----+----+
|  0|null|   1|
|  1| 3.0|null|
|  2| 7.0|null|
|  3|null|   1|
|  4| 4.0|null|
|  5| 3.0|null|
|  6|null|   1|
|  7|null|   1|
|  8| 5.0|null|
|  9| 2.0|null|
| 10|null|   1|
+---+----+----+

# Creates a spec that order column A
order_spec = Window().orderBy('A')

# Doing a cumulative sum. See the explanation
# https://stackoverflow.com/questions/56384625/pyspark-cumulative-sum-with-reset-condition
x = x \
    .withColumn('tmp', sum((x.C.isNull()).cast('int')).over(order_spec)) \
    .withColumn('D', sum(x.C).over(order_spec.partitionBy("tmp"))) \
    .drop('tmp')
x.show()

Output:

+---+----+----+----+
|  A|   B|   C|   D|
+---+----+----+----+
|  0|null|   1|   1|
|  1| 3.0|null|null|
|  2| 7.0|null|null|
|  3|null|   1|   1|
|  4| 4.0|null|null|
|  5| 3.0|null|null|
|  6|null|   1|   1|
|  7|null|   1|   2|
|  8|null|   1|   3|
|  9| 5.0|null|null|
| 10| 2.0|null|null|
| 11|null|   1|   1|
+---+----+----+----+

# Put values from column D to one row above and select the desired output values
x = x.withColumn('E', lag(x.D, ).over(order_spec)) \
    .select(x.A, x.B, when(col('E').isNotNull(), col('E')).otherwise(0).alias('nan_count'))
x.show()

Output:

+---+----+---------+
|  A|   B|nan_count|
+---+----+---------+
|  0|null|        0|
|  1| 3.0|        1|
|  2| 7.0|        0|
|  3|null|        0|
|  4| 4.0|        1|
|  5| 3.0|        0|
|  6|null|        0|
|  7|null|        1|
|  8|null|        2|
|  9| 5.0|        3|
| 10| 2.0|        0|
| 11|null|        0|
+---+----+---------+

Entire code:

from pyspark.shell import sc
from pyspark.sql import Window
from pyspark.sql.functions import lag, when, sum, col

x = sc.parallelize([
    [0, None], [1, 3.], [2, 7.], [3, None], [4, 4.],
    [5, 3.], [6, None], [7, None], [8, None], [9, 5.], [10, 2.], [11, None]])
x = x.toDF(['A', 'B'])

# Transform null values into "1"
x = x.withColumn('C', when(x.B.isNull(), 1))

# Creates a spec that order column A
order_spec = Window().orderBy('A')

# Doing a cumulative sum with reset condition. See the explanation
# https://stackoverflow.com/questions/56384625/pyspark-cumulative-sum-with-reset-condition
x = x \
    .withColumn('tmp', sum((x.C.isNull()).cast('int')).over(order_spec)) \
    .withColumn('D', sum(x.C).over(order_spec.partitionBy("tmp"))) \
    .drop('tmp')

# Put values from column D to one row above and select the desired output values
x = x.withColumn('E', lag(x.D, ).over(order_spec)) \
    .select(x.A, x.B, when(col('E').isNotNull(), col('E')).otherwise(0).alias('nan_count'))
x.show()