问:
MS ACcess to SQL Server Where Clause conversion
I have a where clause in an OLD msaccess query which I am converting to SQL Server.  Just trying to get some input on this.

The where clause in this Access Query is not valid for SQL Server.

Here is the Access Where statement...

```<code>WHERE (((MyTable.MYField) <> IsNull([MYField])))
</code>```

Does anyone have a good replacement for this...  MyTable.MYField is an integer value and Isnull in MS Access returns a boolean true or false value but this syntax is incorrect for SQL Server and I have tried a few permutations of this to no avail.  Sorry can't provide data or real field names....

I understand about linking the tables and what not but with millions of rows that is not a good solution...

Any Takers on this?

答:
That is a very weird looking where clause. I was curious, so did some investigation ... the TLDR conclusion of which is that the clause is equivalent to:

where MyField <> 0

I created the following table in MS Access 2013:

```<code>TestTable
---------
ID autonumber,
MyField number
</code>```

And populated it as follows

```<code>ID | MyField
------------
1  | -1
2  | 0
3  | 1
4  | NULL
</code>```

I then wrote the following query,

```<code>SELECT
    TestTable.ID,
    TestTable.MyField,
    TestTable.MyField AS MyFieldAsTrueFalse,
    IsNull([MyField]) AS IsNullAsTrueFalse,
    IsNull([MyField]) AS IsNullAsInt
FROM
    TestTable;
</code>```

The last three fields where "formatted" as their aliases suggest using the "properties" in the design view of the query. This returns the following dataset:

```<code>ID | MyField | MyFieldAsTrueFalse | IsNullAsTrueFalse | IsNullAsInt
-------------------------------------------------------------------
1  | -1      | TRUE               | FALSE             | 0
2  | 0       | FALSE              | FALSE             | 0
3  | 1       | TRUE               | FALSE             | 0
4  | NULL    | NULL               | TRUE              | -1
</code>```

After adding the provided where clause (TestTable.MyField<>IsNull([MyField])) to the query, I then only see the rows with IDs 1 and 3.

So, I think what MS Access is doing is converting the numeric field in MyField to a boolean. The way it does that is that anything other than zero becomes TRUE. NULL, however, remains NULL. So when evaluating the where clause it's doing the following:

LHS: MyField [as TRUE/FALSE/NULL]

Pseudo code

```<code>case
    when MyField is NULL then NULL
    when MyField = 0 then FALSE
    else TRUE
end
</code>```

RHS: isnull(MyField) [as TRUE/FALSE]

Pseudo code

```<code>case
    when MyField is NULL then TRUE
    else FALSE
end
</code>```

If you follow this through, I reckon the where clause is therefore equivalent to:

```<code>where MyField <> 0
</code>```

This will filter out nulls and zeroes, gives the same results in MS Access and will obviously convert to SQL-Server without complaint.

Body:
I have a where clause in an OLD msaccess query which I am converting to SQL Server.  Just trying to get some input on this.

The where clause in this Access Query is not valid for SQL Server.

Here is the Access Where statement...

WHERE (((MyTable.MYField) <> IsNull([MYField])))

Does anyone have a good replacement for this...  MyTable.MYField is an integer value and Isnull in MS Access returns a boolean true or false value but this syntax is incorrect for SQL Server and I have tried a few permutations of this to no avail.  Sorry can't provide data or real field names....

I understand about linking the tables and what not but with millions of rows that is not a good solution...

Any Takers on this?

Body:
That is a very weird looking where clause. I was curious, so did some investigation ... the TLDR conclusion of which is that the clause is equivalent to:

where MyField <> 0

I created the following table in MS Access 2013:

TestTable
---------
ID autonumber,
MyField number

And populated it as follows

ID | MyField
------------
1  | -1
2  | 0
3  | 1
4  | NULL

I then wrote the following query,

SELECT
    TestTable.ID,
    TestTable.MyField,
    TestTable.MyField AS MyFieldAsTrueFalse,
    IsNull([MyField]) AS IsNullAsTrueFalse,
    IsNull([MyField]) AS IsNullAsInt
FROM
    TestTable;

The last three fields where "formatted" as their aliases suggest using the "properties" in the design view of the query. This returns the following dataset:

ID | MyField | MyFieldAsTrueFalse | IsNullAsTrueFalse | IsNullAsInt
-------------------------------------------------------------------
1  | -1      | TRUE               | FALSE             | 0
2  | 0       | FALSE              | FALSE             | 0
3  | 1       | TRUE               | FALSE             | 0
4  | NULL    | NULL               | TRUE              | -1

After adding the provided where clause (TestTable.MyField<>IsNull([MyField])) to the query, I then only see the rows with IDs 1 and 3.

So, I think what MS Access is doing is converting the numeric field in MyField to a boolean. The way it does that is that anything other than zero becomes TRUE. NULL, however, remains NULL. So when evaluating the where clause it's doing the following:

LHS: MyField [as TRUE/FALSE/NULL]

Pseudo code

case
    when MyField is NULL then NULL
    when MyField = 0 then FALSE
    else TRUE
end

RHS: isnull(MyField) [as TRUE/FALSE]

Pseudo code

case
    when MyField is NULL then TRUE
    else FALSE
end

If you follow this through, I reckon the where clause is therefore equivalent to:

where MyField <> 0

This will filter out nulls and zeroes, gives the same results in MS Access and will obviously convert to SQL-Server without complaint.


来源: stackexchange

问:
How can I log users activity
I'm using default ASP.NET user controls and SQL user provider.

How can I log somewhere when users login to web and when logout ?

Is there some tricks for it or just write to some .log file manually each time after user login. (Also , how can I check user IP adress ?)

Thank you.

答:
The ASP.NET Login control has a LoggedIn event that you can add a handler for that does whatever you like, such as log it somewhere.  Similarly, the LoginStatus control has a LoggedOut event.

The User IP address is available using the HttpContext: HttpContext.Current.Request.UserHostAddress; or HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

ContentLicense: CC BY-SA 2.5

Title: How can I log users activity


问:
Swift 3 CGAffineTransform on CGRect
Basically my goal is to make an atom-like movement similar to this around my logo
https://media.giphy.com/media/9oHZQ2gEez8ti/giphy.gif

```<code>let rect = CGRect(origin: CGPoint(x: Logo.position.x - (Logo.frame.width/3.6), y: Logo.position.y - (Logo.frame.height/2) - kViewSize.height/32), size: CGSize(width: Logo.frame.width/2, height: Logo.frame.height + kViewSize.height/16))
let ellipse = CGPath(ellipseIn: rect, transform: nil)
YellowMagic.run(SKAction.repeatForever(SKAction.follow(ellipse, asOffset: false, orientToPath: false, duration: 1.5)))
</code>```

With the above code I get the middle ellipse, and the sprite runs around the path as desired.

The problem is getting the other two ellipses by rotating the path. I don't think that rotating a path is possible, so I tried rotating the rect with the following code.

```<code>var rect2 = rect
rect2 = rect2.applying(CGAffineTransform(rotationAngle: CGFloat(M_PI/4)))
let ellipse2 = CGPath(ellipseIn: rect2, transform: nil)
</code>```

The above code doesn't rotate the rectangle, in fact it makes the rectangle a square. There must be a simpler solution that I am missing here. Any help is greatly appretiated. Thanks!

答:
Goal to achieve

My Xcode example project

https://github.com/junaidios/Oval-path-Animation

Animation View

https://github.com/junaidios/Oval-path-Animation/blob/master/JSAnimation/animation/JSCircleAnimtionView.swift

My try

Adding Center Circle

```<code>   let centerCirclePath = UIBezierPath(ovalIn: CGRect(x: 162, y: 188, width: 20, height: 20))
   colorCircleLayerCenter.setFill()
   centerCirclePath.fill()
</code>```

Adding Ovals

```<code>    let bezierPath1 = UIBezierPath()
    bezierPath1.move(to: CGPoint(x: 145.5, y: 213.93))
    bezierPath1.addCurve(to: CGPoint(x: 84.68, y: 131.46), controlPoint1: CGPoint(x: 83.75, y: 163.11), controlPoint2: CGPoint(x: 79.26, y: 136.87))
    bezierPath1.addCurve(to: CGPoint(x: 193.5, y: 178.49), controlPoint1: CGPoint(x: 87.4, y: 128.75), controlPoint2: CGPoint(x: 130.21, y: 128.39))
    bezierPath1.addCurve(to: CGPoint(x: 258.01, y: 269.86), controlPoint1: CGPoint(x: 256.33, y: 228.23), controlPoint2: CGPoint(x: 262.32, y: 266.63))
    bezierPath1.addCurve(to: CGPoint(x: 145.5, y: 213.93), controlPoint1: CGPoint(x: 249.34, y: 276.35), controlPoint2: CGPoint(x: 207.25, y: 264.75))
    bezierPath1.close()

    let bezierPath2 = UIBezierPath()
    bezierPath2.move(to: CGPoint(x: 145.5, y: 184.8))
    bezierPath2.addCurve(to: CGPoint(x: 254.5, y: 131.5), controlPoint1: CGPoint(x: 195.5, y: 146.16), controlPoint2: CGPoint(x: 238.27, y: 131.5))
    bezierPath2.addCurve(to: CGPoint(x: 200.5, y: 217.47), controlPoint1: CGPoint(x: 262.64, y: 131.5), controlPoint2: CGPoint(x: 261.5, y: 159.92))
    bezierPath2.addCurve(to: CGPoint(x: 84.5, y: 272.49), controlPoint1: CGPoint(x: 139.94, y: 274.6), controlPoint2: CGPoint(x: 91.01, y: 272.49))
    bezierPath2.addCurve(to: CGPoint(x: 145.5, y: 184.8), controlPoint1: CGPoint(x: 71.42, y: 272.49), controlPoint2: CGPoint(x: 95.5, y: 223.44))
    bezierPath2.close()

    let bezierPath3 = UIBezierPath()
    bezierPath3.move(to: CGPoint(x: 143.5, y: 201.45))
    bezierPath3.addCurve(to: CGPoint(x: 172, y: 89.5), controlPoint1: CGPoint(x: 143.5, y: 154.31), controlPoint2: CGPoint(x: 155.77, y: 89.5))
    bezierPath3.addCurve(to: CGPoint(x: 200.5, y: 201.45), controlPoint1: CGPoint(x: 180.14, y: 89.5), controlPoint2: CGPoint(x: 200.5, y: 124.29))
    bezierPath3.addCurve(to: CGPoint(x: 172, y: 307.5), controlPoint1: CGPoint(x: 200.5, y: 278.04), controlPoint2: CGPoint(x: 178.51, y: 307.5))
    bezierPath3.addCurve(to: CGPoint(x: 143.5, y: 201.45), controlPoint1: CGPoint(x: 158.92, y: 307.5), controlPoint2: CGPoint(x: 143.5, y: 248.58))
    bezierPath3.close()

    let linLayer1 = CAShapeLayer()
    linLayer1.path = bezierPath1.cgPath;
    linLayer1.strokeColor = colorLine.cgColor
    linLayer1.fillColor = UIColor.clear.cgColor

    self.layer.addSublayer(linLayer1);

    let lineLayer2 = CAShapeLayer()
    lineLayer2.path = bezierPath2.cgPath;
    lineLayer2.strokeColor = colorLine.cgColor
    lineLayer2.fillColor = UIColor.clear.cgColor

    self.layer.addSublayer(lineLayer2);

    let lineLayer3 = CAShapeLayer()
    lineLayer3.path = bezierPath3.cgPath;
    lineLayer3.strokeColor = colorLine.cgColor
    lineLayer3.fillColor = UIColor.clear.cgColor

    self.layer.addSublayer(lineLayer3);
</code>```

Adding Moving Circles on Ovals

```<code>    let circleLayer1 = CAShapeLayer()
    circleLayer1.path = UIBezierPath(ovalIn: CGRect(x: -10, y: -10, width: 20, height: 20)).cgPath;
    circleLayer1.fillColor = colorCircleLayer1.cgColor

    let circleLayer2 = CAShapeLayer()
    circleLayer2.path = UIBezierPath(ovalIn: CGRect(x: -10, y: -10, width: 20, height: 20)).cgPath;
    circleLayer2.fillColor = colorCircleLayer2.cgColor

    let circleLayer3 = CAShapeLayer()
    circleLayer3.path = UIBezierPath(ovalIn: CGRect(x: -10, y: -10, width: 20, height: 20)).cgPath;
    circleLayer3.fillColor = colorCircleLayer3.cgColor

    self.layer.addSublayer(circleLayer1);
    self.layer.addSublayer(circleLayer2);
    self.layer.addSublayer(circleLayer3);
</code>```

Apply animation to circles

```<code>    circleLayer1.add(self.addAnimation(ovalPath: bezierPath1), forKey: "1");
    circleLayer2.add(self.addAnimation(ovalPath: bezierPath2), forKey: "2");
    circleLayer3.add(self.addAnimation(ovalPath: bezierPath3), forKey: "3");
</code>```

Animation Funcation

```<code>func addAnimation(ovalPath : UIBezierPath) -> CAKeyframeAnimation {

    let animation = CAKeyframeAnimation()

    animation.keyPath = "position"
    animation.repeatCount = HUGE
    animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear);
    animation.fillMode = kCAFillModeForwards;
    animation.repeatCount = .infinity
    animation.beginTime = 0.0
    animation.duration = 2.5
    animation.calculationMode = kCAAnimationPaced

    animation.path = ovalPath.cgPath

    return animation;
}
</code>```

Final output

ContentLicense: CC BY-SA 3.0

Title: Swift 3 CGAffineTransform on CGRect

Body:
Basically my goal is to make an atom-like movement similar to this around my logo
https://media.giphy.com/media/9oHZQ2gEez8ti/giphy.gif

let rect = CGRect(origin: CGPoint(x: Logo.position.x - (Logo.frame.width/3.6), y: Logo.position.y - (Logo.frame.height/2) - kViewSize.height/32), size: CGSize(width: Logo.frame.width/2, height: Logo.frame.height + kViewSize.height/16))
let ellipse = CGPath(ellipseIn: rect, transform: nil)
YellowMagic.run(SKAction.repeatForever(SKAction.follow(ellipse, asOffset: false, orientToPath: false, duration: 1.5)))

With the above code I get the middle ellipse, and the sprite runs around the path as desired.

The problem is getting the other two ellipses by rotating the path. I don't think that rotating a path is possible, so I tried rotating the rect with the following code.

var rect2 = rect
rect2 = rect2.applying(CGAffineTransform(rotationAngle: CGFloat(M_PI/4)))
let ellipse2 = CGPath(ellipseIn: rect2, transform: nil)

The above code doesn't rotate the rectangle, in fact it makes the rectangle a square. There must be a simpler solution that I am missing here. Any help is greatly appretiated. Thanks!

Body:
Goal to achieve

My Xcode example project

https://github.com/junaidios/Oval-path-Animation

Animation View

https://github.com/junaidios/Oval-path-Animation/blob/master/JSAnimation/animation/JSCircleAnimtionView.swift

My try

Adding Center Circle

   let centerCirclePath = UIBezierPath(ovalIn: CGRect(x: 162, y: 188, width: 20, height: 20))
   colorCircleLayerCenter.setFill()
   centerCirclePath.fill()

Adding Ovals

    let bezierPath1 = UIBezierPath()
    bezierPath1.move(to: CGPoint(x: 145.5, y: 213.93))
    bezierPath1.addCurve(to: CGPoint(x: 84.68, y: 131.46), controlPoint1: CGPoint(x: 83.75, y: 163.11), controlPoint2: CGPoint(x: 79.26, y: 136.87))
    bezierPath1.addCurve(to: CGPoint(x: 193.5, y: 178.49), controlPoint1: CGPoint(x: 87.4, y: 128.75), controlPoint2: CGPoint(x: 130.21, y: 128.39))
    bezierPath1.addCurve(to: CGPoint(x: 258.01, y: 269.86), controlPoint1: CGPoint(x: 256.33, y: 228.23), controlPoint2: CGPoint(x: 262.32, y: 266.63))
    bezierPath1.addCurve(to: CGPoint(x: 145.5, y: 213.93), controlPoint1: CGPoint(x: 249.34, y: 276.35), controlPoint2: CGPoint(x: 207.25, y: 264.75))
    bezierPath1.close()

    let bezierPath2 = UIBezierPath()
    bezierPath2.move(to: CGPoint(x: 145.5, y: 184.8))
    bezierPath2.addCurve(to: CGPoint(x: 254.5, y: 131.5), controlPoint1: CGPoint(x: 195.5, y: 146.16), controlPoint2: CGPoint(x: 238.27, y: 131.5))
    bezierPath2.addCurve(to: CGPoint(x: 200.5, y: 217.47), controlPoint1: CGPoint(x: 262.64, y: 131.5), controlPoint2: CGPoint(x: 261.5, y: 159.92))
    bezierPath2.addCurve(to: CGPoint(x: 84.5, y: 272.49), controlPoint1: CGPoint(x: 139.94, y: 274.6), controlPoint2: CGPoint(x: 91.01, y: 272.49))
    bezierPath2.addCurve(to: CGPoint(x: 145.5, y: 184.8), controlPoint1: CGPoint(x: 71.42, y: 272.49), controlPoint2: CGPoint(x: 95.5, y: 223.44))
    bezierPath2.close()

    let bezierPath3 = UIBezierPath()
    bezierPath3.move(to: CGPoint(x: 143.5, y: 201.45))
    bezierPath3.addCurve(to: CGPoint(x: 172, y: 89.5), controlPoint1: CGPoint(x: 143.5, y: 154.31), controlPoint2: CGPoint(x: 155.77, y: 89.5))
    bezierPath3.addCurve(to: CGPoint(x: 200.5, y: 201.45), controlPoint1: CGPoint(x: 180.14, y: 89.5), controlPoint2: CGPoint(x: 200.5, y: 124.29))
    bezierPath3.addCurve(to: CGPoint(x: 172, y: 307.5), controlPoint1: CGPoint(x: 200.5, y: 278.04), controlPoint2: CGPoint(x: 178.51, y: 307.5))
    bezierPath3.addCurve(to: CGPoint(x: 143.5, y: 201.45), controlPoint1: CGPoint(x: 158.92, y: 307.5), controlPoint2: CGPoint(x: 143.5, y: 248.58))
    bezierPath3.close()

    let linLayer1 = CAShapeLayer()
    linLayer1.path = bezierPath1.cgPath;
    linLayer1.strokeColor = colorLine.cgColor
    linLayer1.fillColor = UIColor.clear.cgColor

    self.layer.addSublayer(linLayer1);

    let lineLayer2 = CAShapeLayer()
    lineLayer2.path = bezierPath2.cgPath;
    lineLayer2.strokeColor = colorLine.cgColor
    lineLayer2.fillColor = UIColor.clear.cgColor

    self.layer.addSublayer(lineLayer2);

    let lineLayer3 = CAShapeLayer()
    lineLayer3.path = bezierPath3.cgPath;
    lineLayer3.strokeColor = colorLine.cgColor
    lineLayer3.fillColor = UIColor.clear.cgColor

    self.layer.addSublayer(lineLayer3);

Adding Moving Circles on Ovals

    let circleLayer1 = CAShapeLayer()
    circleLayer1.path = UIBezierPath(ovalIn: CGRect(x: -10, y: -10, width: 20, height: 20)).cgPath;
    circleLayer1.fillColor = colorCircleLayer1.cgColor

    let circleLayer2 = CAShapeLayer()
    circleLayer2.path = UIBezierPath(ovalIn: CGRect(x: -10, y: -10, width: 20, height: 20)).cgPath;
    circleLayer2.fillColor = colorCircleLayer2.cgColor

    let circleLayer3 = CAShapeLayer()
    circleLayer3.path = UIBezierPath(ovalIn: CGRect(x: -10, y: -10, width: 20, height: 20)).cgPath;
    circleLayer3.fillColor = colorCircleLayer3.cgColor

    self.layer.addSublayer(circleLayer1);
    self.layer.addSublayer(circleLayer2);
    self.layer.addSublayer(circleLayer3);

Apply animation to circles

    circleLayer1.add(self.addAnimation(ovalPath: bezierPath1), forKey: "1");
    circleLayer2.add(self.addAnimation(ovalPath: bezierPath2), forKey: "2");
    circleLayer3.add(self.addAnimation(ovalPath: bezierPath3), forKey: "3");

Animation Funcation

func addAnimation(ovalPath : UIBezierPath) -> CAKeyframeAnimation {

    let animation = CAKeyframeAnimation()

    animation.keyPath = "position"
    animation.repeatCount = HUGE
    animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear);
    animation.fillMode = kCAFillModeForwards;
    animation.repeatCount = .infinity
    animation.beginTime = 0.0
    animation.duration = 2.5
    animation.calculationMode = kCAAnimationPaced

    animation.path = ovalPath.cgPath

    return animation;
}

Final output


问:
Laravel 5.4 - Use Controller Route in javascript function
I have a table (datatables) and I have an edit icon and I want to call a route with the parameter.

My function is currently is

```<code>function editItem(id)
    {
        //alert(id);
    }
</code>```

What I want to do is to call

```<code>UsersController@editItem
</code>```

and also pass the id to the controller.

I am a little stuck!

答:
You are confusing server-side logic with client-side logic. The controller method you want to call is a server-side component that doesn't exist in client-side logic.

You should pass the route definition to JS and call this url using AJAX (jquery or axios are your friends) and read the response from the server in an asynchronous way.

I try to explain with some example code:

```<code>//routes.php
Route::get('/edit', [
  'uses' => 'UsersController@editItem',
  'as' => 'edit-item'
]);

//blade file
<script>
window.routes = {
  editItem: "{{ route('edit-item') }}",
}
function editItem(id)
{
  $.post(window.routes.editItem, { id: id }).then(function(response) {
    console.log(response);
  });
}
</script>
</code>```

Body:
I have a table (datatables) and I have an edit icon and I want to call a route with the parameter.

My function is currently is

function editItem(id)
    {
        //alert(id);
    }

What I want to do is to call

UsersController@editItem

and also pass the id to the controller.

I am a little stuck!

Body:
You are confusing server-side logic with client-side logic. The controller method you want to call is a server-side component that doesn't exist in client-side logic.

You should pass the route definition to JS and call this url using AJAX (jquery or axios are your friends) and read the response from the server in an asynchronous way.

I try to explain with some example code:

//routes.php
Route::get('/edit', [
  'uses' => 'UsersController@editItem',
  'as' => 'edit-item'
]);

//blade file
<script>
window.routes = {
  editItem: "{{ route('edit-item') }}",
}
function editItem(id)
{
  $.post(window.routes.editItem, { id: id }).then(function(response) {
    console.log(response);
  });
}
</script>


问:
Getting the minimum or maximum of two similar columns in Scala
I just started learning Scala and I'm trying to figure out a way to get the min of two or multiple Columns of the same type in a DataFrame. I have the following code which gives me the min and max of a Column individually.

```<code>inputDF.select(min($"dropoff_longitude")).show
inputDF.select(max($"pickup_longitude")).show
</code>```

How do I get the min of both the Columns, dropoff_longitude and  pickup_longitude. I did it like this

```<code>scala.math.min(
   inputDF.select(min($"pickup_longitude")).head.getFloat(0),
   inputDF.select(min($"dropoff_longitude")).head.getFloat(0)
)
</code>```

Is there a better way to do this?

Thank you

答:
Think you can do something like this:</p>

```<code>// assume all columns are of type Int, it could be other numeric type as well
val df = Seq((1,2),(3,4)).toDF("A", "B")

df.agg(min($"A"), min($"B")).first().toSeq.map{ case x: Int => x }.min
// res14: Int = 1
</code>```

Body:
I just started learning Scala and I'm trying to figure out a way to get the min of two or multiple Columns of the same type in a DataFrame. I have the following code which gives me the min and max of a Column individually.

inputDF.select(min($"dropoff_longitude")).show
inputDF.select(max($"pickup_longitude")).show

How do I get the min of both the Columns, dropoff_longitude and  pickup_longitude. I did it like this

scala.math.min(
   inputDF.select(min($"pickup_longitude")).head.getFloat(0),
   inputDF.select(min($"dropoff_longitude")).head.getFloat(0)
)

Is there a better way to do this?

Thank you

Body:
Think you can do something like this:

// assume all columns are of type Int, it could be other numeric type as well
val df = Seq((1,2),(3,4)).toDF("A", "B")

df.agg(min($"A"), min($"B")).first().toSeq.map{ case x: Int => x }.min
// res14: Int = 1


问:
PLSQL - Creating procedure with parameter, but only allowing 2 values
First off, I'm a DBA that dabbles in PL/SQL Programming.  I have some knowledge, but some is most certainly lacking.

```<code>CREATE OR REPLACE PROCEDURE TRIGGER_PRC (P_TRGNAME IN VARCHAR2, P_STATUS IN VARCHAR2)
AS ....
</code>```

I'd like to allow the P_STATUS parameter only be allowed values of 'E' or 'D' for enabling or disabling a trigger.  I've done some searching, but can't seem to find the solution for this.  Any help is greatly appreciated!

Thanks!

Jeremy

答:
You could use an IF to check if the values is either E or D. If not, raise an error using raise_application_error:

```<code>CREATE OR REPLACE PROCEDURE TRIGGER_PRC (P_TRGNAME IN VARCHAR2, P_STATUS IN VARCHAR2)
AS
begin
    if P_STATUS not in ('E', 'D') then
        raise_application_error(-20001, 'Invalid P_STATUS value - ' || P_STATUS);
    end if;

    . . .
    . . .

end;
/
</code>```

Body:
First off, I'm a DBA that dabbles in PL/SQL Programming.  I have some knowledge, but some is most certainly lacking.

CREATE OR REPLACE PROCEDURE TRIGGER_PRC (P_TRGNAME IN VARCHAR2, P_STATUS IN VARCHAR2)
AS ....

I'd like to allow the P_STATUS parameter only be allowed values of 'E' or 'D' for enabling or disabling a trigger.  I've done some searching, but can't seem to find the solution for this.  Any help is greatly appreciated!

Thanks!

Jeremy

Body:
You could use an IF to check if the values is either E or D. If not, raise an error using raise_application_error:

CREATE OR REPLACE PROCEDURE TRIGGER_PRC (P_TRGNAME IN VARCHAR2, P_STATUS IN VARCHAR2)
AS
begin
    if P_STATUS not in ('E', 'D') then
        raise_application_error(-20001, 'Invalid P_STATUS value - ' || P_STATUS);
    end if;

    . . .
    . . .

end;
/


问:
Explanation about return object of class example
I have this example ,and i need to know if the object class (ob2) in the second method came as argument from return object in the first method??

can anyone explain this example to me?

```<code>public class C {

  public B getObject(){

   B ob2 = new B ();

   return ob2; //return type
   }

   public void f3(A ob2){

   ob2.f1 (); //local variable or argument
}}
</code>```

答:
```<code>public class C {

    public B getObject(){
         B ob2 = new B ();
        return ob2; //return type
    }

    public void f3(A ob2){
         ob2.f1 (); //local variable or argument
   }
}
</code>```

I think your question is bit confusing.
You had provided in the signature that the return type of the first function is of type ' B '.
But you are expecting the Argument of type A from type B
Here the signature of second function expects argument of type A not B

Body:
I have this example ,and i need to know if the object class (ob2) in the second method came as argument from return object in the first method??

can anyone explain this example to me?

public class C {

  public B getObject(){

   B ob2 = new B ();

   return ob2; //return type
   }

   public void f3(A ob2){

   ob2.f1 (); //local variable or argument
}}

Body:
public class C {

    public B getObject(){
         B ob2 = new B ();
        return ob2; //return type
    }

    public void f3(A ob2){
         ob2.f1 (); //local variable or argument
   }
}

I think your question is bit confusing.
You had provided in the signature that the return type of the first function is of type ' B '.
But you are expecting the Argument of type A from type B
Here the signature of second function expects argument of type A not B


问:
Is String str = new String("my string") really less efficient?
I often saw people saying String str = new String("my string") is less efficient than writing String str = "my string", because the former creates a static "my string" object and then new's a String object that gets copied from the static one.

However, given that the language here is so simple and unambiguous, I can hardly imagine that Java optimizer won't take any effort to simply convert the former to the latter. Why would it really choose to do it the more laborious way? What can any negative side effects be if Java does optimize it?

答:
However, given that the language here is so simple and unambiguous, I can hardly imagine that Java optimizer won't take any effort to simply convert the former to the latter.

First, you shouldn't write code saying to do something slow just because you think the compiler will replace it with something faster.

Second, the compiler can't generally optimize this, because new guarantees the creation of a new object. If you do

```<code>String str = new String("my string");
</code>```

then it's guaranteed that str != "my string". Java can only optimize out the new if it can prove that the String object's identity won't matter to the execution of the program.

Body:
However, given that the language here is so simple and unambiguous, I can hardly imagine that Java optimizer won't take any effort to simply convert the former to the latter.

First, you shouldn't write code saying to do something slow just because you think the compiler will replace it with something faster.

Second, the compiler can't generally optimize this, because new guarantees the creation of a new object. If you do

String str = new String("my string");

then it's guaranteed that str != "my string". Java can only optimize out the new if it can prove that the String object's identity won't matter to the execution of the program.


问:
how to have many objects or models in one form with spring mvc
i have to use one form for two modelAttributes : "groupes" which is a list of Groupe and "matieres" is a list of Matiere, i know that one form support only one modelAttribute , i tried two options but both doesn't work,one by using spring bind tag and the other one by wrapping groupes and matieres in one class,
Any ideas how to solve this ?</p>

```<code>@RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm() {
ModelAndView mv = new ModelAndView("abs");

    mv.addObject("matiere", matiereservice.findAlmatieres());
    mv.addObject("groupe", groupeservice.findAllGroupes());

    return mv;
}

@RequestMapping( method = RequestMethod.POST)
public String submitForm( @ModelAttribute("groupe") Groupe groupe, @ModelAttribute("matiere") Matiere matiere,
        ModelMap map,
        BindingResult result
         ) {
           // BindingResult treatment

    return "listeleve" ;
}
</code>```

答:
Instead of sending those attributes separately, simply make a DTO class which contains List fields of both of your Groupe and Matiere classes.

```<code>public class ListeleveDTO {
    private List<Groupe> groupe;
    private List<Matiere> matiere;

    public ListeleveDTO(List<Groupe> groupe, List<Matiere> matiere) {
        // Assign to fields
    }
    // getters and setters
}
</code>```

And set the instance of this class as a model attribute.

```<code>@RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm() {
ModelAndView mv = new ModelAndView("abs");

    mv.addObject("listeleveDTO", new ListeleveDTO(groupeservice.findAllGroupes(), matiereservice.findAlmatieres());

    return mv;
}

@RequestMapping( method = RequestMethod.POST)
public String submitForm( @ModelAttribute("listeleveDTO") ListeleveDTO,
        ModelMap map,
        BindingResult result
         ) {
           // BindingResult treatment

    return "listeleve" ;
}
</code>```

Body:
i have to use one form for two modelAttributes : "groupes" which is a list of Groupe and "matieres" is a list of Matiere, i know that one form support only one modelAttribute , i tried two options but both doesn't work,one by using spring bind tag and the other one by wrapping groupes and matieres in one class,
Any ideas how to solve this ?

@RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm() {
ModelAndView mv = new ModelAndView("abs");

    mv.addObject("matiere", matiereservice.findAlmatieres());
    mv.addObject("groupe", groupeservice.findAllGroupes());

    return mv;
}

@RequestMapping( method = RequestMethod.POST)
public String submitForm( @ModelAttribute("groupe") Groupe groupe, @ModelAttribute("matiere") Matiere matiere,
        ModelMap map,
        BindingResult result
         ) {
           // BindingResult treatment

    return "listeleve" ;
}

Body:
Instead of sending those attributes separately, simply make a DTO class which contains List fields of both of your Groupe and Matiere classes.

public class ListeleveDTO {
    private List<Groupe> groupe;
    private List<Matiere> matiere;

    public ListeleveDTO(List<Groupe> groupe, List<Matiere> matiere) {
        // Assign to fields
    }
    // getters and setters
}

And set the instance of this class as a model attribute.

@RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm() {
ModelAndView mv = new ModelAndView("abs");

    mv.addObject("listeleveDTO", new ListeleveDTO(groupeservice.findAllGroupes(), matiereservice.findAlmatieres());

    return mv;
}

@RequestMapping( method = RequestMethod.POST)
public String submitForm( @ModelAttribute("listeleveDTO") ListeleveDTO,
        ModelMap map,
        BindingResult result
         ) {
           // BindingResult treatment

    return "listeleve" ;
}


问:
Bootstrap Equal Column Heights
I am trying to make my Bootstrap column's all the same height. Right now if one column has more content than another the columns float around and things don't look "square".

Here is a fiddle example of what I mean:

https://jsfiddle.net/jjq9gygr/

I have tried the display: flex approach but since my html does not have a new .row container for every 3 col-xs-4 columns, all the columns go on the same row instead of wrapping to the next line after 3 columns. I hope that makes sense.

If there is a way to keep the HTML as is and get the result I am after that would be great. Any ideas or recommendations are helpful.

```<code><div class="container">
<div class="row">
    <div class="col-xs-4 red">
  <h3>
  Column 1
  </h3>
        <p>Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. </p>
    </div>
    <div class="col-xs-4 pink">
<h3>
  Column 2
  </h3>
        <p>Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. </p>
    </div>
    <div class="col-xs-4 yellow">
  <h3>
  Column 3
  </h3>
        <p>Differnt amount of text. Differnt amount of text. Differnt amount of text. </p>
    </div>
    <div class="col-xs-4 orange">
  <h3>
  Column 4
  </h3>
        <p>Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. </p>
    </div>
    <div class="col-xs-4 blue">
  <h3>
  Column 5
  </h3>
        <p>Differnt amount of text. Differnt amount of text. Differnt amount of text. </p>
    </div>
    <div class="col-xs-4 green">
  <h3>
  Column 6
  </h3>
        <p>Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. </p>
    </div>
    <div class="col-xs-4 navy">
  <h3>
  Column 7
  </h3>
        <p>Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. </p>
    </div>
</div>
</code>```

答:
What you're looking for is the class .row-eq-height which is attached to the row containers. It's a great addition to bootstraps base code. This page explains more and below is the CSS highlighting what you need.

http://getbootstrap.com.vn/examples/equal-height-columns/

```<code> /*
 * Row with equal height columns
 * --------------------------------------------------
 */
.row-eq-height {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display:         flex;
}

/*
 * Styles copied from the Grid example to make grid rows & columns visible.
 */
.container {
  padding-right: 15px;
  padding-left: 15px;
}

h4 {
  margin-top: 25px;
}
.row {
  margin-bottom: 20px;
}
.row .row {
  margin-top: 10px;
  margin-bottom: 0;
}
[class*="col-"] {
  padding-top: 15px;
  padding-bottom: 15px;
  background-color: #eee;
  background-color: rgba(86,61,124,.15);
  border: 1px solid #ddd;
  border: 1px solid rgba(86,61,124,.2);
}

/*
 * Callout styles copied from Bootstrap's main docs.
 */
/* Common styles for all types */
.bs-callout {
  padding: 20px;
  margin: 20px 0;
  border-left: 3px solid #eee;
}
.bs-callout h4 {
  margin-top: 0;
  margin-bottom: 5px;
}
.bs-callout p:last-child {
  margin-bottom: 0;
}
.bs-callout code {
  background-color: #fff;
  border-radius: 3px;
}
/* Variations */
.bs-callout-danger {
  background-color: #fdf7f7;
  border-color: #d9534f;
}
.bs-callout-danger h4 {
  color: #d9534f;
}
.bs-callout-warning {
  background-color: #fcf8f2;
  border-color: #f0ad4e;
}
.bs-callout-warning h4 {
  color: #f0ad4e;
}
.bs-callout-info {
  background-color: #f4f8fa;
  border-color: #5bc0de;
}
.bs-callout-info h4 {
  color: #5bc0de;
}
</code>```

Title: Bootstrap Equal Column Heights

Body:
I am trying to make my Bootstrap column's all the same height. Right now if one column has more content than another the columns float around and things don't look "square".

Here is a fiddle example of what I mean:

https://jsfiddle.net/jjq9gygr/

I have tried the display: flex approach but since my html does not have a new .row container for every 3 col-xs-4 columns, all the columns go on the same row instead of wrapping to the next line after 3 columns. I hope that makes sense.

If there is a way to keep the HTML as is and get the result I am after that would be great. Any ideas or recommendations are helpful.

  Column 1

Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text.

  Column 2

Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text.

  Column 3

Differnt amount of text. Differnt amount of text. Differnt amount of text.

  Column 4

Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text.

  Column 5

Differnt amount of text. Differnt amount of text. Differnt amount of text.

  Column 6

Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text.

  Column 7

Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text. Differnt amount of text.

Body:
What you're looking for is the class .row-eq-height which is attached to the row containers. It's a great addition to bootstraps base code. This page explains more and below is the CSS highlighting what you need.

http://getbootstrap.com.vn/examples/equal-height-columns/

 /*
 * Row with equal height columns
 * --------------------------------------------------
 */
.row-eq-height {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display:         flex;
}

/*
 * Styles copied from the Grid example to make grid rows & columns visible.
 */
.container {
  padding-right: 15px;
  padding-left: 15px;
}

h4 {
  margin-top: 25px;
}
.row {
  margin-bottom: 20px;
}
.row .row {
  margin-top: 10px;
  margin-bottom: 0;
}
[class*="col-"] {
  padding-top: 15px;
  padding-bottom: 15px;
  background-color: #eee;
  background-color: rgba(86,61,124,.15);
  border: 1px solid #ddd;
  border: 1px solid rgba(86,61,124,.2);
}

/*
 * Callout styles copied from Bootstrap's main docs.
 */
/* Common styles for all types */
.bs-callout {
  padding: 20px;
  margin: 20px 0;
  border-left: 3px solid #eee;
}
.bs-callout h4 {
  margin-top: 0;
  margin-bottom: 5px;
}
.bs-callout p:last-child {
  margin-bottom: 0;
}
.bs-callout code {
  background-color: #fff;
  border-radius: 3px;
}
/* Variations */
.bs-callout-danger {
  background-color: #fdf7f7;
  border-color: #d9534f;
}
.bs-callout-danger h4 {
  color: #d9534f;
}
.bs-callout-warning {
  background-color: #fcf8f2;
  border-color: #f0ad4e;
}
.bs-callout-warning h4 {
  color: #f0ad4e;
}
.bs-callout-info {
  background-color: #f4f8fa;
  border-color: #5bc0de;
}
.bs-callout-info h4 {
  color: #5bc0de;
}


问:
Login to Microsoft SQL Server Error: 18456
I am getting this error while trying to connect to the SQL Server.

Microsoft SQL Server Error: 18456

Can anybody tell me what the error code means?

答: I believe this can happen if you are trying to log in with a user that is defined in Active Directory, but attempt using "SQL Server Authentication" in the login screen. I do not know how to specify a different user with NTLM/Windows Authentication: When I click the Windows Authentication dropdown, the username and password is blanked out, and I can only log in as myself. </p>


问:
Client does not support authentication protocol requested by server
I need to establish PHP4 environment in conjunction with mysql5 and I am facing this problem when I try to connect to mysql.

Thank you for any trace.

答:
It's a known MySQL problem. C.5.2.4. Client does not support authentication protocol:

MySQL 5.1 uses an authentication protocol based on a password hashing algorithm that is incompatible with that used by older (pre-4.1) clients. If you upgrade the server from 4.0, attempts to connect to it with an older client may fail with the following message: "Client does not support authentication protocol requested
  by server; consider upgrading MySQL client".

To solve this problem, you should use one of the following approaches:

     1. Upgrade all client programs to use a 4.1.1 or newer client library.

     2. When connecting to the server with a pre-4.1 client program, use an account that still has a pre-4.1-style password.

     3. Reset the password to pre-4.1 style for each user that needs to use a pre-4.1 client program.

     4. Tell the server to use the older password hashing algorithm.


问:
set text to textview if an image has been selected from gallery
I have a textview: Click to add an image behind an imageview.

when user click, it will open the gallery. If user select an image it will be displayed in the imageview.

I want to set the textview text to blank if an image has been selected.

I tried inside imageview on click:

```<code>        Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE);
        ImageViewText.setText("");
</code>```

the problem here is the textview will be blank in the moment user click on the imageview. What I want is to reset it if user really selected an image.

Any ideas?

答: Since you're using startActivityForResult, you should have an onActivityResult method overridden. You can check there if the user has actually selected something which is where you can call setText("") or preferably setVisibility(View.GONE)</p>

Body:
I have a textview: Click to add an image behind an imageview.

when user click, it will open the gallery. If user select an image it will be displayed in the imageview.

I want to set the textview text to blank if an image has been selected.

I tried inside imageview on click:

        Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE);
        ImageViewText.setText("");

the problem here is the textview will be blank in the moment user click on the imageview. What I want is to reset it if user really selected an image.

Any ideas?


问:
Range of size of tensor's dimension - tf.range
I'm trying to define an operation for a NN I'm implementing, but to do so I need to iterate over the dimension of a tensor. I have a small working example below.

```<code>X = tf.placeholder(tf.float32, shape=[None, 10])
idx = [[i] for i in tf.range(X.get_shape()[0])]
</code>```

This produces an error stating

```<code>ValueError: Cannot convert an unknown Dimension to a Tensor: ?
</code>```

When using the same code but using tf.shape instead, resulting in the code being

```<code>X = tf.placeholder(tf.float32, shape=[None, 10])
idx = [[i] for i in tf.range(tf.shape(X)[0])]
</code>```

Gives the following error

```<code>TypeError: 'Tensor' object is not iterable.
</code>```

The way that I'm implementing this NN, the batch_size isn't defined until the training function, which is at the end of the code. This is just where I'm building the graph itself, so the batch_size isn't known by this point, and it can't be fixed as the training batch_size and the test set batch_sizes are different.

What is the best way to fix this? This is the last thing keeping my code from running, as I got it to run with a fixed batch_size, though those results aren't useful. I've been pouring over the TensorFlow API Documentation and stack overflow for weeks to no avail.

I've also tried to feed in a placeholder into the range, so when I'm running the test/training set the code would be the following

```<code>X = tf.placeholder(tf.float32, shape=[None, 10])
bs = tf.placeholder(tf.int32)

def My_Function(X):
    # Do some stuff to X
    idx = [[i] for i in tf.range(bs)]
    # return some tensor

A = tf.nn.relu(My_Function(X))
</code>```

However, this gives the same error as above

```<code>TypeError: 'Tensor' object is not iterable.
</code>```

答:
You can't operate on tensors that way. You need to use tf.map_fn as user1735003 mentioned.

Here is an example where I used tf.map_fn in order to pass the output of an LSTM at each timestep into a linear layer, defined by weights['out'] and biases['out'].

```<code>x = tf.placeholder("float", [features_dimension, None, n_timesteps])

weights = {'out': tf.Variable(tf.zeros([N_HIDDEN_LSTM, labels_dimension]))}
biases = {'out': tf.Variable(tf.zeros([labels_dimension]))}

def LSTM_model(x, weights, biases):
        lstm_cell = rnn.LSTMCell(N_HIDDEN_LSTM)
        # outputs is a Tensor of shape (n_timesteps, n_observations, N_HIDDEN_LSTM)
        outputs, states = tf.nn.dynamic_rnn(lstm_cell, x, dtype=tf.float32, time_major=True)
        # Linear activation
        def pred_fn(current_output):
            return tf.matmul(current_output, weights['out']) + biases['out']
        # Use tf.map_fn to apply pred_fn to each tensor in outputs, along
        # dimension 0 (timestep dimension)
        pred = tf.map_fn(pred_fn, outputs)

        return pred
</code>```

Body:
I'm trying to define an operation for a NN I'm implementing, but to do so I need to iterate over the dimension of a tensor. I have a small working example below.

X = tf.placeholder(tf.float32, shape=[None, 10])
idx = [[i] for i in tf.range(X.get_shape()[0])]

This produces an error stating

ValueError: Cannot convert an unknown Dimension to a Tensor: ?

When using the same code but using tf.shape instead, resulting in the code being

X = tf.placeholder(tf.float32, shape=[None, 10])
idx = [[i] for i in tf.range(tf.shape(X)[0])]

Gives the following error

TypeError: 'Tensor' object is not iterable.

The way that I'm implementing this NN, the batch_size isn't defined until the training function, which is at the end of the code. This is just where I'm building the graph itself, so the batch_size isn't known by this point, and it can't be fixed as the training batch_size and the test set batch_sizes are different.

What is the best way to fix this? This is the last thing keeping my code from running, as I got it to run with a fixed batch_size, though those results aren't useful. I've been pouring over the TensorFlow API Documentation and stack overflow for weeks to no avail.

I've also tried to feed in a placeholder into the range, so when I'm running the test/training set the code would be the following

X = tf.placeholder(tf.float32, shape=[None, 10])
bs = tf.placeholder(tf.int32)

def My_Function(X):
    # Do some stuff to X
    idx = [[i] for i in tf.range(bs)]
    # return some tensor

A = tf.nn.relu(My_Function(X))

However, this gives the same error as above

TypeError: 'Tensor' object is not iterable.

Body:
You can't operate on tensors that way. You need to use tf.map_fn as user1735003 mentioned.

Here is an example where I used tf.map_fn in order to pass the output of an LSTM at each timestep into a linear layer, defined by weights['out'] and biases['out'].

x = tf.placeholder("float", [features_dimension, None, n_timesteps])

weights = {'out': tf.Variable(tf.zeros([N_HIDDEN_LSTM, labels_dimension]))}
biases = {'out': tf.Variable(tf.zeros([labels_dimension]))}

def LSTM_model(x, weights, biases):
        lstm_cell = rnn.LSTMCell(N_HIDDEN_LSTM)
        # outputs is a Tensor of shape (n_timesteps, n_observations, N_HIDDEN_LSTM)
        outputs, states = tf.nn.dynamic_rnn(lstm_cell, x, dtype=tf.float32, time_major=True)
        # Linear activation
        def pred_fn(current_output):
            return tf.matmul(current_output, weights['out']) + biases['out']
        # Use tf.map_fn to apply pred_fn to each tensor in outputs, along
        # dimension 0 (timestep dimension)
        pred = tf.map_fn(pred_fn, outputs)

        return pred


问:
Using createNewLongWriteBuilder with RxAndroidBLE Correctly
I have a device that can only accept 20 bytes at a time on the virtual serial port (using BLE). If I'm not mistaken, createNewLongWriteBuilder seems to be the perfect method for this.

Here is my attempt:

```<code>String newNameMsg = "SOME STRING THAT IS LONGER THAN 20 CHARACTERS";

byte[] byteMsg = newNameMsg.getBytes(Charset.forName("UTF-8"));
byte[] endLine = hexStringToByteArray("0D"); // signifies end of line for my device
byte[] newName = new byte[byteMsg.length + endLine.length];
System.arraycopy(byteMsg, 0, newName, 0, byteMsg.length);
System.arraycopy(endLine, 0, newName, byteMsg.length, endLine.length);

connectionObservable
    .flatMap(rxBleConnection -> rxBleConnection.createNewLongWriteBuilder()
    .setCharacteristicUuid(characteristicUuid)
    .setBytes(newName)
    .setMaxBatchSize(20) // my device only accepts 20 characters at a time.
    .setWriteOperationAckStrategy(new RxBleConnection.WriteOperationAckStrategy() {
            @Override
            public Observable<Boolean> call(Observable<Boolean> booleanObservable) {
                return Observable.just(true); // this is supposed to tell the LongWriteBuilder that we should continue sending data, correct?
            }
        })
    .build()
    )
    .subscribe(
        byteArray -> {
        // Written data.
        Log.i("BLE Controller","Data has been written!");
        },
        throwable -> {
        // Handle an error here.
        }
    );
</code>```

Actual Results:
The device does not receive any data, but the logs show:

D/RxBle#Radio:   QUEUED
  RxBleRadioOperationCharacteristicLongWrite(107353908) D/RxBle#Radio:
  STARTED RxBleRadioOperationCharacteristicLongWrite(107353908)
  I/BLE Controller: Data has been written!

D/RxBle#Radio: FINISHED
  RxBleRadioOperationCharacteristicLongWrite(107353908)

UPDATE 03/30/2017:

My original understanding was incorrect and had many issues with it. I was sending a subscription instead of an Observable.

s_noopy pointed out that:

The WriteOperationAckStrategy is effectively an equavilent of ?
  Observable.repeatWhen() operator. The filtering should happen inside
  the WOAS to trigger the repeat when ready.`

Current Situation:

I need to wait for my device to clear the TX flag before I can send the next batch. To do this, I need to implement setWriteOperationAckStrategy but I need to read the TX flag to see if it is clear before sending the next batch.

My attempt:

```<code>@Override
public Observable<Boolean> call(Observable<Boolean> objectObservable) {
    return connectionObservable
                .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(serialTX.getUuid()))
                .observeOn(AndroidSchedulers.mainThread());
}
</code>```

UPDATE 07/30/2017:

Modified s_noopy's code so that I now have:

```<code>final ByteArrayBatchObservable byteArrayBatchObservable = new ByteArrayBatchObservable(newName, 19);
Log.i("BLE Controller","sending updated name");
byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
    connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(vspT, bytesBatch)
        .flatMap(writtenBytes -> { // ...and when each batch will be written...
            final Func1<byte[], Boolean> filterFunction = txBytes -> checkIfZero(txBytes);
            return rxBleConnection
                    .readCharacteristic(vspT.getUuid())
                    .repeat() // ...and repeat it...
                    .takeUntil(filterFunction)
                    .filter(filterFunction) // ...but don't emit anything until then...
                    .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
        }
    ), 1)

)
.subscribe(
    byteArray -> {
        // Written data.
        Log.i("BLE Controller","BT has been renamed! :" + byteArray.toString());
    },
    throwable -> {
        // Handle an error here.
        Log.i("BLE Controller","BT rename ERROR");

    }
);

public boolean checkIfZero(byte[] txBytes){
    Log.i("BLE Controller", "checking if tx is cleared: " +txBytes.toString());
    for (byte b : txBytes) {
        if (b != 0) {
            return false;
        }
    }
    return true;
}
</code>```

Current Situation:

I have tried to convert from using rxBleConnection to using the connectionObservable. It appears as though the first batch is written successfully, but even though the subscribe function returns a successfully written bytearray both times, the bluetooth device only sees the first batch

Logs

```<code>07-31 13:26:54.434 25060-25060/com.packet.sniffer I/BLE Controller: sending updated name
07-31 13:26:54.434 264-467/? I/ThermalEngine: Sensor:pa_therm1:33000 mC
07-31 13:26:54.440 25060-25060/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicWrite(99278425)
07-31 13:26:54.443 25060-25187/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicWrite(99278425)
07-31 13:26:54.458 25060-25060/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicWrite(56755989)
07-31 13:26:54.611 25060-25072/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicWrite characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 13:26:54.614 25060-25243/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicRead(32706505)
07-31 13:26:54.614 25060-25187/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicWrite(99278425)
07-31 13:26:54.615 25060-25187/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicWrite(56755989)
07-31 13:26:54.714 25060-25071/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicWrite characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 13:26:54.721 25060-25243/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicRead(39309874)
07-31 13:26:54.723 25060-25187/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicWrite(56755989)
07-31 13:26:54.724 25060-25187/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicRead(32706505)
07-31 13:26:54.809 1980-2244/com.android.bluetooth I/bt_btif_gatt: set_read_value unformat.len = 20
07-31 13:26:54.811 25060-25072/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 13:26:54.813 25060-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@c805018
07-31 13:26:54.813 25060-25243/com.packet.sniffer I/BLE Controller: BT has been renamed! :[B@5999a71
07-31 13:26:54.813 25060-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@c805018
07-31 13:26:54.816 25060-25187/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(32706505)
07-31 13:26:54.817 25060-25187/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicRead(39309874)
07-31 13:26:54.908 1980-2244/com.android.bluetooth I/bt_btif_gatt: set_read_value unformat.len = 20
07-31 13:26:54.910 25060-25071/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 13:26:54.911 25060-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@a1f9bcf
07-31 13:26:54.911 25060-25243/com.packet.sniffer I/BLE Controller: BT has been renamed! :[B@208995c
07-31 13:26:54.911 25060-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@a1f9bcf
07-31 13:26:54.914 25060-25187/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(39309874)
07-31 13:26:56.467 1980-2388/com.android.bluetooth D/HeadsetStateMachine: Disconnected process message: 10, size: 0
</code>```

UPDATE 07/31/2017:

Updated to make previous code synchronous

```<code>byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
    connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(vspT, bytesBatch)
                            .flatMap(writtenBytes -> { // ...and when each batch will be written...
                                    final Func1<byte[], Boolean> filterFunction = txBytes -> checkIfZero(txBytes);
                                    return rxBleConnection
                                            .readCharacteristic(vspT.getUuid())
                                            .repeat() // ...and repeat it...
                                            .takeUntil(filterFunction)
                                            .filter(filterFunction) // ...but don't emit anything until then...
                                            .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
                                }
                            ))
, 1)
</code>```

Unfortunately still not working, here are the relevant logs:

```<code>4:55:35.108 25084-25084/com.packet.sniffer I/BLE Controller: sending updated name
07-31 14:55:35.110 25084-25084/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicWrite(135224277)
07-31 14:55:35.113 25084-25209/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicWrite(135224277)
07-31 14:55:35.113 25084-25084/com.packet.sniffer I/BluetoothLEController: verify connectivity
07-31 14:55:35.219 25084-25096/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicWrite characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 14:55:35.225 25084-25243/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicRead(155469961)
07-31 14:55:35.228 25084-25209/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicWrite(135224277)
07-31 14:55:35.229 25084-25209/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicRead(155469961)
07-31 14:55:35.316 25084-25097/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 14:55:35.317 25084-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@f0396a7
07-31 14:55:35.317 25084-25243/com.packet.sniffer I/BLE Controller: BT has been renamed! :[B@8983754
07-31 14:55:35.317 25084-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@f0396a7
07-31 14:55:35.320 25084-25209/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(155469961)
</code>```

答:
From the documentation of setWriteOperationAckStrategy():

```<code>If you want to delay the next batch use provided observable and add some custom behavior (delay, waiting for a message from the device, etc.)
</code>```

Judging from your snippet here:

```<code>.setWriteOperationAckStrategy(new RxBleConnection.WriteOperationAckStrategy() {
    @Override
    public Observable<Boolean> call(Observable<Boolean> booleanObservable) {
        return Observable.just(true); // this is supposed to tell the LongWriteBuilder that we should continue sending data, correct?
    }
})
</code>```

You are not interested in delay of the next batch. In this situation you can just leave out setting the WriteOperationAckStrategy as the documentation states: If this is not specified - the next batch of bytes is written right after the previous one has finished. Which is an equavilent to:

```<code>.setWriteOperationAckStrategy(new RxBleConnection.WriteOperationAckStrategy() {
    @Override
    public Observable<Boolean> call(Observable<Boolean> objectObservable) {
        return objectObservable;
    }
})
</code>```

Edit:
To delay the next batch write there is a need to delay the ACK signal. As the Long Write operation is making sure no other operation will happen in between writes - the only possible option is to relay on characteristic notifications / indications or other side channel events.

Edit 1:
Alternative approach without using the Long Write could look like this. Consider a class that would make batches of a long byte[] that is needed to be written:

```<code>public class ByteArrayBatchObservable extends Observable<byte[]> {

    public ByteArrayBatchObservable(@NonNull final byte[] bytes, final int maxBatchSize) {
        super(SyncOnSubscribe.createSingleState(
                new Func0<ByteBuffer>() {
                    @Override
                    public ByteBuffer call() {
                        return ByteBuffer.wrap(bytes);
                    }
                },
                new Action2<ByteBuffer, Observer<? super byte[]>>() {
                    @Override
                    public void call(ByteBuffer byteBuffer, Observer<? super byte[]> observer) {
                        int nextBatchSize = Math.min(byteBuffer.remaining(), maxBatchSize);
                        if (nextBatchSize == 0) {
                            observer.onCompleted();
                            return;
                        }
                        final byte[] nextBatch = new byte[nextBatchSize];
                        byteBuffer.get(nextBatch);
                        observer.onNext(nextBatch);
                    }
                }
        ));
    }
}
</code>```

Then in your code you could use a similar code to:

```<code>final ByteArrayBatchObservable byteArrayBatchObservable = new ByteArrayBatchObservable(longByteArrayToWrite, maxBatchSize); // create an observable that will make chunks of data small enough to write at once
return byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
                rxBleConnection.writeCharacteristic(characteristicUuid, bytesBatch) // ...write them on characteristic...
                        .flatMap(writtenBytes -> { // ...and when each batch will be written...
                                    final Func1<byte[], Boolean> filterFunction = txBytes -> txBytes.length == 1 && txBytes[0] == 0;
                                    return rxBleConnection
                                            .readCharacteristic(txCharacteristicUuid) // ...start reading the TX characteristic...
                                            .repeat() // ...and repeat it...
                                            .takeUntil(filterFunction) // ...until the read value will indicate that the device is ready for the next batch...
                                            .filter(filterFunction) // ...but don't emit anything until then...
                                            .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
                                }
                        ),
        1 // ...to be sure that only one .writeCharacteristic() will be subscribed at any given time
);
</code>```

Edit 2:
Per what you wanted to achieve when writing a long name:

Write a batch of data

Perform a read of the device readiness flag

If device is not ready go back to 2.

If there is still more data to write go back to 1.

What you can see in logs:

Batch of data is written

Another batch of data is written

Read is performed

Another read is performed

And that is exactly what you have in your code as you are not synchronizing individual batches. It is probably a copy-paste error because of the place where you have put the .flatMap(Observable, 1):

```<code>final ByteArrayBatchObservable byteArrayBatchObservable = new ByteArrayBatchObservable(newName, 19);
Log.i("BLE Controller","sending updated name");
byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
    connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(vspT, bytesBatch)
        .flatMap(writtenBytes -> { // ...and when each batch will be written...
            final Func1<byte[], Boolean> filterFunction = txBytes -> checkIfZero(txBytes);
            return rxBleConnection
                    .readCharacteristic(vspT.getUuid())
                    .repeat() // ...and repeat it...
                    .takeUntil(filterFunction)
                    .filter(filterFunction) // ...but don't emit anything until then...
                    .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
        }
    ), 1)

)
</code>```

Where this code should be only a bit different to achieve synchronous behaviour:

```<code>final ByteArrayBatchObservable byteArrayBatchObservable = new ByteArrayBatchObservable(newName, 19);
Log.i("BLE Controller","sending updated name");
byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
    connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(vspT, bytesBatch)
        .flatMap(writtenBytes -> { // ...and when each batch will be written...
            final Func1<byte[], Boolean> filterFunction = txBytes -> checkIfZero(txBytes);
            return rxBleConnection
                    .readCharacteristic(vspT.getUuid())
                    .repeat() // ...and repeat it...
                    .takeUntil(filterFunction)
                    .filter(filterFunction) // ...but don't emit anything until then...
                    .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
        }
    ))
    .take(1)
, 1)
</code>```

Body:
I have a device that can only accept 20 bytes at a time on the virtual serial port (using BLE). If I'm not mistaken, createNewLongWriteBuilder seems to be the perfect method for this.

Here is my attempt:

String newNameMsg = "SOME STRING THAT IS LONGER THAN 20 CHARACTERS";

byte[] byteMsg = newNameMsg.getBytes(Charset.forName("UTF-8"));
byte[] endLine = hexStringToByteArray("0D"); // signifies end of line for my device
byte[] newName = new byte[byteMsg.length + endLine.length];
System.arraycopy(byteMsg, 0, newName, 0, byteMsg.length);
System.arraycopy(endLine, 0, newName, byteMsg.length, endLine.length);

connectionObservable
    .flatMap(rxBleConnection -> rxBleConnection.createNewLongWriteBuilder()
    .setCharacteristicUuid(characteristicUuid)
    .setBytes(newName)
    .setMaxBatchSize(20) // my device only accepts 20 characters at a time.
    .setWriteOperationAckStrategy(new RxBleConnection.WriteOperationAckStrategy() {
            @Override
            public Observable<Boolean> call(Observable<Boolean> booleanObservable) {
                return Observable.just(true); // this is supposed to tell the LongWriteBuilder that we should continue sending data, correct?
            }
        })
    .build()
    )
    .subscribe(
        byteArray -> {
        // Written data.
        Log.i("BLE Controller","Data has been written!");
        },
        throwable -> {
        // Handle an error here.
        }
    );

Actual Results:
The device does not receive any data, but the logs show:

D/RxBle#Radio:   QUEUED
  RxBleRadioOperationCharacteristicLongWrite(107353908) D/RxBle#Radio:
  STARTED RxBleRadioOperationCharacteristicLongWrite(107353908)
  I/BLE Controller: Data has been written!

D/RxBle#Radio: FINISHED
  RxBleRadioOperationCharacteristicLongWrite(107353908)

UPDATE 03/30/2017:

My original understanding was incorrect and had many issues with it. I was sending a subscription instead of an Observable.

s_noopy pointed out that:

The WriteOperationAckStrategy is effectively an equavilent of ?
  Observable.repeatWhen() operator. The filtering should happen inside
  the WOAS to trigger the repeat when ready.`

Current Situation:

I need to wait for my device to clear the TX flag before I can send the next batch. To do this, I need to implement setWriteOperationAckStrategy but I need to read the TX flag to see if it is clear before sending the next batch.

My attempt:

@Override
public Observable<Boolean> call(Observable<Boolean> objectObservable) {
    return connectionObservable
                .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(serialTX.getUuid()))
                .observeOn(AndroidSchedulers.mainThread());
}

UPDATE 07/30/2017:

Modified s_noopy's code so that I now have:

final ByteArrayBatchObservable byteArrayBatchObservable = new ByteArrayBatchObservable(newName, 19);
Log.i("BLE Controller","sending updated name");
byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
    connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(vspT, bytesBatch)
        .flatMap(writtenBytes -> { // ...and when each batch will be written...
            final Func1<byte[], Boolean> filterFunction = txBytes -> checkIfZero(txBytes);
            return rxBleConnection
                    .readCharacteristic(vspT.getUuid())
                    .repeat() // ...and repeat it...
                    .takeUntil(filterFunction)
                    .filter(filterFunction) // ...but don't emit anything until then...
                    .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
        }
    ), 1)

)
.subscribe(
    byteArray -> {
        // Written data.
        Log.i("BLE Controller","BT has been renamed! :" + byteArray.toString());
    },
    throwable -> {
        // Handle an error here.
        Log.i("BLE Controller","BT rename ERROR");

    }
);

public boolean checkIfZero(byte[] txBytes){
    Log.i("BLE Controller", "checking if tx is cleared: " +txBytes.toString());
    for (byte b : txBytes) {
        if (b != 0) {
            return false;
        }
    }
    return true;
}

Current Situation:

I have tried to convert from using rxBleConnection to using the connectionObservable. It appears as though the first batch is written successfully, but even though the subscribe function returns a successfully written bytearray both times, the bluetooth device only sees the first batch

Logs

07-31 13:26:54.434 25060-25060/com.packet.sniffer I/BLE Controller: sending updated name
07-31 13:26:54.434 264-467/? I/ThermalEngine: Sensor:pa_therm1:33000 mC
07-31 13:26:54.440 25060-25060/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicWrite(99278425)
07-31 13:26:54.443 25060-25187/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicWrite(99278425)
07-31 13:26:54.458 25060-25060/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicWrite(56755989)
07-31 13:26:54.611 25060-25072/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicWrite characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 13:26:54.614 25060-25243/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicRead(32706505)
07-31 13:26:54.614 25060-25187/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicWrite(99278425)
07-31 13:26:54.615 25060-25187/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicWrite(56755989)
07-31 13:26:54.714 25060-25071/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicWrite characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 13:26:54.721 25060-25243/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicRead(39309874)
07-31 13:26:54.723 25060-25187/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicWrite(56755989)
07-31 13:26:54.724 25060-25187/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicRead(32706505)
07-31 13:26:54.809 1980-2244/com.android.bluetooth I/bt_btif_gatt: set_read_value unformat.len = 20
07-31 13:26:54.811 25060-25072/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 13:26:54.813 25060-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@c805018
07-31 13:26:54.813 25060-25243/com.packet.sniffer I/BLE Controller: BT has been renamed! :[B@5999a71
07-31 13:26:54.813 25060-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@c805018
07-31 13:26:54.816 25060-25187/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(32706505)
07-31 13:26:54.817 25060-25187/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicRead(39309874)
07-31 13:26:54.908 1980-2244/com.android.bluetooth I/bt_btif_gatt: set_read_value unformat.len = 20
07-31 13:26:54.910 25060-25071/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 13:26:54.911 25060-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@a1f9bcf
07-31 13:26:54.911 25060-25243/com.packet.sniffer I/BLE Controller: BT has been renamed! :[B@208995c
07-31 13:26:54.911 25060-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@a1f9bcf
07-31 13:26:54.914 25060-25187/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(39309874)
07-31 13:26:56.467 1980-2388/com.android.bluetooth D/HeadsetStateMachine: Disconnected process message: 10, size: 0

UPDATE 07/31/2017:

Updated to make previous code synchronous

byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
    connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(vspT, bytesBatch)
                            .flatMap(writtenBytes -> { // ...and when each batch will be written...
                                    final Func1<byte[], Boolean> filterFunction = txBytes -> checkIfZero(txBytes);
                                    return rxBleConnection
                                            .readCharacteristic(vspT.getUuid())
                                            .repeat() // ...and repeat it...
                                            .takeUntil(filterFunction)
                                            .filter(filterFunction) // ...but don't emit anything until then...
                                            .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
                                }
                            ))
, 1)

Unfortunately still not working, here are the relevant logs:

4:55:35.108 25084-25084/com.packet.sniffer I/BLE Controller: sending updated name
07-31 14:55:35.110 25084-25084/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicWrite(135224277)
07-31 14:55:35.113 25084-25209/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicWrite(135224277)
07-31 14:55:35.113 25084-25084/com.packet.sniffer I/BluetoothLEController: verify connectivity
07-31 14:55:35.219 25084-25096/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicWrite characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 14:55:35.225 25084-25243/com.packet.sniffer D/RxBle#Radio:   QUEUED RxBleRadioOperationCharacteristicRead(155469961)
07-31 14:55:35.228 25084-25209/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicWrite(135224277)
07-31 14:55:35.229 25084-25209/com.packet.sniffer D/RxBle#Radio:  STARTED RxBleRadioOperationCharacteristicRead(155469961)
07-31 14:55:35.316 25084-25097/com.packet.sniffer D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=569a2000-b87f-490c-92cb-11ba5ea5167c status=0
07-31 14:55:35.317 25084-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@f0396a7
07-31 14:55:35.317 25084-25243/com.packet.sniffer I/BLE Controller: BT has been renamed! :[B@8983754
07-31 14:55:35.317 25084-25243/com.packet.sniffer I/BLE Controller: checking if tx is cleared: [B@f0396a7
07-31 14:55:35.320 25084-25209/com.packet.sniffer D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(155469961)

Body:
From the documentation of setWriteOperationAckStrategy():

If you want to delay the next batch use provided observable and add some custom behavior (delay, waiting for a message from the device, etc.)

Judging from your snippet here:

.setWriteOperationAckStrategy(new RxBleConnection.WriteOperationAckStrategy() {
    @Override
    public Observable<Boolean> call(Observable<Boolean> booleanObservable) {
        return Observable.just(true); // this is supposed to tell the LongWriteBuilder that we should continue sending data, correct?
    }
})

You are not interested in delay of the next batch. In this situation you can just leave out setting the WriteOperationAckStrategy as the documentation states: If this is not specified - the next batch of bytes is written right after the previous one has finished. Which is an equavilent to:

.setWriteOperationAckStrategy(new RxBleConnection.WriteOperationAckStrategy() {
    @Override
    public Observable<Boolean> call(Observable<Boolean> objectObservable) {
        return objectObservable;
    }
})

Edit:
To delay the next batch write there is a need to delay the ACK signal. As the Long Write operation is making sure no other operation will happen in between writes - the only possible option is to relay on characteristic notifications / indications or other side channel events.

Edit 1:
Alternative approach without using the Long Write could look like this. Consider a class that would make batches of a long byte[] that is needed to be written:

public class ByteArrayBatchObservable extends Observable<byte[]> {

    public ByteArrayBatchObservable(@NonNull final byte[] bytes, final int maxBatchSize) {
        super(SyncOnSubscribe.createSingleState(
                new Func0<ByteBuffer>() {
                    @Override
                    public ByteBuffer call() {
                        return ByteBuffer.wrap(bytes);
                    }
                },
                new Action2<ByteBuffer, Observer<? super byte[]>>() {
                    @Override
                    public void call(ByteBuffer byteBuffer, Observer<? super byte[]> observer) {
                        int nextBatchSize = Math.min(byteBuffer.remaining(), maxBatchSize);
                        if (nextBatchSize == 0) {
                            observer.onCompleted();
                            return;
                        }
                        final byte[] nextBatch = new byte[nextBatchSize];
                        byteBuffer.get(nextBatch);
                        observer.onNext(nextBatch);
                    }
                }
        ));
    }
}

Then in your code you could use a similar code to:

final ByteArrayBatchObservable byteArrayBatchObservable = new ByteArrayBatchObservable(longByteArrayToWrite, maxBatchSize); // create an observable that will make chunks of data small enough to write at once
return byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
                rxBleConnection.writeCharacteristic(characteristicUuid, bytesBatch) // ...write them on characteristic...
                        .flatMap(writtenBytes -> { // ...and when each batch will be written...
                                    final Func1<byte[], Boolean> filterFunction = txBytes -> txBytes.length == 1 && txBytes[0] == 0;
                                    return rxBleConnection
                                            .readCharacteristic(txCharacteristicUuid) // ...start reading the TX characteristic...
                                            .repeat() // ...and repeat it...
                                            .takeUntil(filterFunction) // ...until the read value will indicate that the device is ready for the next batch...
                                            .filter(filterFunction) // ...but don't emit anything until then...
                                            .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
                                }
                        ),
        1 // ...to be sure that only one .writeCharacteristic() will be subscribed at any given time
);

Edit 2:
Per what you wanted to achieve when writing a long name:

Write a batch of data

Perform a read of the device readiness flag

If device is not ready go back to 2.

If there is still more data to write go back to 1.

What you can see in logs:

Batch of data is written

Another batch of data is written

Read is performed

Another read is performed

And that is exactly what you have in your code as you are not synchronizing individual batches. It is probably a copy-paste error because of the place where you have put the .flatMap(Observable, 1):

final ByteArrayBatchObservable byteArrayBatchObservable = new ByteArrayBatchObservable(newName, 19);
Log.i("BLE Controller","sending updated name");
byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
    connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(vspT, bytesBatch)
        .flatMap(writtenBytes -> { // ...and when each batch will be written...
            final Func1<byte[], Boolean> filterFunction = txBytes -> checkIfZero(txBytes);
            return rxBleConnection
                    .readCharacteristic(vspT.getUuid())
                    .repeat() // ...and repeat it...
                    .takeUntil(filterFunction)
                    .filter(filterFunction) // ...but don't emit anything until then...
                    .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
        }
    ), 1)

)

Where this code should be only a bit different to achieve synchronous behaviour:

final ByteArrayBatchObservable byteArrayBatchObservable = new ByteArrayBatchObservable(newName, 19);
Log.i("BLE Controller","sending updated name");
byteArrayBatchObservable.flatMap(bytesBatch -> // using batches of data to write...
    connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(vspT, bytesBatch)
        .flatMap(writtenBytes -> { // ...and when each batch will be written...
            final Func1<byte[], Boolean> filterFunction = txBytes -> checkIfZero(txBytes);
            return rxBleConnection
                    .readCharacteristic(vspT.getUuid())
                    .repeat() // ...and repeat it...
                    .takeUntil(filterFunction)
                    .filter(filterFunction) // ...but don't emit anything until then...
                    .map(readBytes -> writtenBytes); // ...and emit the writtenBytesBatch...
        }
    ))
    .take(1)
, 1)


问:
c++ - isdigit, how to distinguish between a character and a number
I want to check if my array has only numbers how can I check it out?

i try this example but this not working and i dont Understand why.

```<code>int main() {

char* str = new char[9];
cin >> str;

cout << isdigit(str[0])<<endl;

system("pause");
return 0;
}
</code>```

input:

1234

output:
4

what i want is:

input:
1234

print: ok

input:

12fg

print: not ok (because the character in my array)

I look forward to your help and explanation

thank's.

答:
Try something like this:</p>

```<code>const char *s = "1234";

while (isdigit(*s)) s++;
const char *result = (*s) ? "not ok" : "ok";
</code>```

Body:
I want to check if my array has only numbers how can I check it out?

i try this example but this not working and i dont Understand why.

int main() {

char* str = new char[9];
cin >> str;

cout << isdigit(str[0])<<endl;

system("pause");
return 0;
}

input:

1234

output:
4

what i want is:

input:
1234

print: ok

input:

12fg

print: not ok (because the character in my array)

I look forward to your help and explanation

thank's.

Body:
Try something like this:

const char *s = "1234";

while (isdigit(*s)) s++;
const char *result = (*s) ? "not ok" : "ok";


问:
Resto is 12.7 and method getTagli return 10.0 , 2.0 , 0.5 but my result had to be 10.0, 2.0, 0.5, 0.2

Is easy, have two collections set (list) and tagli; scroll list and when resto> item in list, pickup that item and subtract that item until resto is equal 0.

```<code>public static ArrayList<Double> getTagli(Double resto) {
    Set list = Cassa.getSoldi().keySet();   // 10, 5, 2, 1, 0.5, 0.2, 0.1
    Iterator iter = list.iterator();
    Double divisore = (Double) iter.next();
    while (iter.hasNext() && resto > 0) {
        resto = Cassa.divisioniSuccessive(resto, divisore);
        if (resto<divisore)
            divisore = (Double) iter.next();
    }
    return tagli;
}

private static Double divisioniSuccessive(Double dividendo, Double divisore) {
    if (dividendo >= divisore) {
        tagli.add(divisore);
        dividendo = (Double) dividendo - (Double) divisore;
    }
    return dividendo;
}
</code>```

答:
```<code>public static double arrotonda( double numero, int nCifreDecimali ){
    return Math.round( numero * Math.pow( 10, nCifreDecimali ) )/Math.pow( 10, nCifreDecimali );
}
</code>```

Body:
Is easy, have two collections set (list) and tagli; scroll list and when resto> item in list, pickup that item and subtract that item until resto is equal 0.

public static ArrayList<Double> getTagli(Double resto) {
    Set list = Cassa.getSoldi().keySet();   // 10, 5, 2, 1, 0.5, 0.2, 0.1
    Iterator iter = list.iterator();
    Double divisore = (Double) iter.next();
    while (iter.hasNext() && resto > 0) {
        resto = Cassa.divisioniSuccessive(resto, divisore);
        if (resto<divisore)
            divisore = (Double) iter.next();
    }
    return tagli;
}

private static Double divisioniSuccessive(Double dividendo, Double divisore) {
    if (dividendo >= divisore) {
        tagli.add(divisore);
        dividendo = (Double) dividendo - (Double) divisore;
    }
    return dividendo;
}


问:
how to show progress bar moving from one activity to another activity in android
I want to show progress bar to going from one activity to another activity until another activity is loaded can anybody give example

Thanks

答: You can't have a progress to be displayed when switching to a new activity from current activity.</p>

ContentLicense: CC BY-SA 4.0


问:
User permission not routing to correct intent
I am making actions on google using API.AI and suddenly today my user permission request is not working. Just after the user gives permission, API.AI doesn't route to any intent. Next time when the user says "yes" or "no" then it handles it incorrect intent "permissionhandler". It rather shows some event "assistant_itent_action_PERMISSION" whereas it should be routing to intent "permissionHandler".

Here is how it should

答: Should be fixed now. Please check.</p>

Body: Should be fixed now. Please check.


问:
From a collection, get a new collection based on condition. - Rails
I have have this query. events = eventswhere("starts_at <= ?", 3.months.ago) which does what I want. Now with events I'm trying to call this. events.where("ticket_types.present?") but that doesn't get a new collection... What am I doing wrong? and what should my query look like?

答:
You'll want:

```<code>events.where("ticket_types <> ''")
</code>```

For ActiveRecord > 4.0, you can also use not

```<code>events.where.not(ticket_types: '')
</code>```

Body:
You'll want:

events.where("ticket_types <> ''")

For ActiveRecord > 4.0, you can also use not

events.where.not(ticket_types: '')


问:
Efficient way to replace int in list with first occurrence index
I am looking for a way to replace every int element in a list with the index of its first occurrence in a separate Distinct list. For example, take the following list:

```<code><50, 2, 4, 5, 43, 42, 44, 14, 50, 44, 23, 2, 16, 4, 5, 23, 33 ... >
</code>```

The distinct list would read like this:

```<code><50, 2, 4, 5, 43, 42, 44, 14, 50, 23, 33 ... >
</code>```

I would like for the list to read as follows:

```<code><0, 1, 2, 3, 4, 5, 6, 7, 0, 6, 8, 1, 9, 3, 4, 8, 10 ...>
</code>```

I am new to LINQ operators, but I have the following code:

```<code>//Retrieve original list:
List<int> SubFaceList = FaceList.GetRange (faceBounds [fb], faceBounds [fb + 1]);

// Get unique face list entries:
List<int> UniqueFaceList = SubFaceList.Distinct ().ToList ();

//Replace values with first ocurrence:
List<int> RestructuredList = SubFaceList.Select ((vx,ix) => UniqueFaceList.IndexOf(vx)).ToList();
</code>```

I am doing this, in order to split up a large Collada triangular 3D mesh, into smaller submeshes. The arrays are face construction order, which reference an index of vertices in a separate array, so numbers could be referenced multiple times in the face array. However, upon executing my code, some meshes take upwards of 30 minutes to process.

I also have the following code, which extracts the given vertices from the main vertex array, which does not seem to suffer from the same crippling inefficiency:

```<code>List<Vector3> subVertices = Vertices.Where ((vx, ix) => UniqueFaceList.Contains (ix)).Select (vx => vx).ToList();
</code>```

Am I going about this wrong, and is there a potential way that I could extract the index based on the current vertex being processed in this statement? I know there has to be a more efficient way to get the information that I need, but I am not quite sure how.

答:
It's possible with LINQ, but if you want maximum performance, you could use Dictionary and simple for / foreach loop (you'll find that the code is not so bigger than the most efficient LINQ solution):

```<code>var indexMap = new Dictionary<int, int>();
var RestructuredList = new List<int>(SubFaceList.Count); // final capacity
foreach (var item in SubFaceList)
{
    int index;
    if (!indexMap.TryGetValue(item, out index))
        indexMap.Add(item, index = indexMap.Count);
    RestructuredList.Add(index);
}
</code>```

Body:
I am looking for a way to replace every int element in a list with the index of its first occurrence in a separate Distinct list. For example, take the following list:

<50, 2, 4, 5, 43, 42, 44, 14, 50, 44, 23, 2, 16, 4, 5, 23, 33 ... >

The distinct list would read like this:

<50, 2, 4, 5, 43, 42, 44, 14, 50, 23, 33 ... >

I would like for the list to read as follows:

<0, 1, 2, 3, 4, 5, 6, 7, 0, 6, 8, 1, 9, 3, 4, 8, 10 ...>

I am new to LINQ operators, but I have the following code:

//Retrieve original list:
List<int> SubFaceList = FaceList.GetRange (faceBounds [fb], faceBounds [fb + 1]);

// Get unique face list entries:
List<int> UniqueFaceList = SubFaceList.Distinct ().ToList ();

//Replace values with first ocurrence:
List<int> RestructuredList = SubFaceList.Select ((vx,ix) => UniqueFaceList.IndexOf(vx)).ToList();

I am doing this, in order to split up a large Collada triangular 3D mesh, into smaller submeshes. The arrays are face construction order, which reference an index of vertices in a separate array, so numbers could be referenced multiple times in the face array. However, upon executing my code, some meshes take upwards of 30 minutes to process.

I also have the following code, which extracts the given vertices from the main vertex array, which does not seem to suffer from the same crippling inefficiency:

List<Vector3> subVertices = Vertices.Where ((vx, ix) => UniqueFaceList.Contains (ix)).Select (vx => vx).ToList();

Am I going about this wrong, and is there a potential way that I could extract the index based on the current vertex being processed in this statement? I know there has to be a more efficient way to get the information that I need, but I am not quite sure how.

Body:
It's possible with LINQ, but if you want maximum performance, you could use Dictionary and simple for / foreach loop (you'll find that the code is not so bigger than the most efficient LINQ solution):

var indexMap = new Dictionary<int, int>();
var RestructuredList = new List<int>(SubFaceList.Count); // final capacity
foreach (var item in SubFaceList)
{
    int index;
    if (!indexMap.TryGetValue(item, out index))
        indexMap.Add(item, index = indexMap.Count);
    RestructuredList.Add(index);
}


问:
Regular expression for accent mark and other characters
I need to validate if in a string exist any letter with accent mark or the Spanish letter Ñ. I tried using regular expression but, I can't find a solution.

this is my code:

```<code>var videoname = document.getElementById('url').value;
var BLIDRegExpression = /[Á\É\Í\Ó\Ú\-\Ñ\ñ]+$/(]+$/;
var matchesCount = videoname.split(BLIDRegExpression).length - 1;
alert(matchesCount);
</code>```

The alert shows 0 result.

答:
I use this to test alphanumeric in portuguese. I think it fits spanish too. Take a look:

var isAlphanumeric = (str) => /^[A-zÀ-ÿ0-9\–\-_\s\.\(\)\/]+$/.test( str );
console.log(isAlphanumeric('España'));
console.log(isAlphanumeric('España%&*'));```
</div>
</div>
</p>

<p>With a small change it does what you want:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>var hasAccent = (str) => /[À-ÿ]/.test( str );
console.log(hasAccent('España'));
console.log(hasAccent('Brasil'));</code>```

Body:
I need to validate if in a string exist any letter with accent mark or the Spanish letter Ñ. I tried using regular expression but, I can't find a solution.

this is my code:

var videoname = document.getElementById('url').value;
var BLIDRegExpression = /[Á\É\Í\Ó\Ú\-\Ñ\ñ]+$/(]+$/;
var matchesCount = videoname.split(BLIDRegExpression).length - 1;
alert(matchesCount);

The alert shows 0 result.

Body:
I use this to test alphanumeric in portuguese. I think it fits spanish too. Take a look:

var isAlphanumeric = (str) => /^[A-zÀ-ÿ0-9\–\-_\s\.\(\)\/]+$/.test( str );
console.log(isAlphanumeric('España'));
console.log(isAlphanumeric('España%&*'));

With a small change it does what you want:

var hasAccent = (str) => /[À-ÿ]/.test( str );
console.log(hasAccent('España'));
console.log(hasAccent('Brasil'));


问:
Matlab: interpolation operator for multigrid methods
I have to build the following matrix:

```<code> 1 2 1
     1 2 1
         1 2 1
</code>```

I tried the following:

```<code> N = 8;
 full( ( spdiags(repmat([1/4,1/2,1/4], N/2-1, 1), 0:2, N/2-1, N-1) ) )
</code>```

but the output is not what I want.

Body:
I have to build the following matrix:

 1 2 1
     1 2 1
         1 2 1

I tried the following:

 N = 8;
 full( ( spdiags(repmat([1/4,1/2,1/4], N/2-1, 1), 0:2, N/2-1, N-1) ) )

but the output is not what I want.

Body:
It is not clean but it should work anyway:

 N = 10;
 w(1, :) = [1, 2, 1, zeros(1, (N-1)-3)];
 for i = 1:(N/2-2)
     w(i+1, :) = [zeros(1, i*2), 1, 2, 1, zeros(1, (N-1)-(3+i*2))];
 end


问:
Interface implementation in java by comparator
I got confused while stuyding java in deep with the core concept.

what i have studied is, if you have interface

```<code>public interface interfaceconcept {

    public void heyyou(String s);
    public abstract void nono(String s);
    public void kolk(int i);

}
</code>```

and you have a class which implements the interface then you have to write the body of all the methods

```<code>  public class implementation implements interfaceconcept{

    @Override
    public void heyyou(String s) {
        // TODO Auto-generated method stub

    }

    @Override
    public void nono(String s) {
        // TODO Auto-generated method stub

    }

    @Override
    public void kolk(int i) {
        // TODO Auto-generated method stub

    }

    }
</code>```

if you dont want to write the methods you can use abstract class

Now i was studing about comparator, and while inpecting its class i found it is an interface

```<code>public interface Comparator<T> {
//
}
</code>```

now it implemented it in another class, firstly it gave me an error saying.

The type Order must implement the inherited abstract method Comparator.compare(Order, Order)

i have added all the method by clicking add unimplemented method and remove all but one.

but when i compiled it, it simply compiled why? am i not supppose to add all the unimplemented methods of comparator interface as per the rules of java?

Also one of its method in comparator class is

```<code>default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }
</code>```

what is the point if you have written the implementation of one method in interface itself? you cant write any body of the method, if i m correct.

```<code>public class Order implements Comparator<Order>{

    @Override
    public int compare(Order o1, Order o2) {
        // TODO Auto-generated method stub
        return 0;
    }

    }
</code>```

答:
If you look at the Javadocs for Comparator<T>
https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
you'll see that the only abstract method that is not default, not static, and not already implemented via inheritance from Object is compare(T, T). So it's the only method that is unimplemented in the interface, and therefore when you implement it you have implemented all the unimplemented methods in the interface.

Body:
I got confused while stuyding java in deep with the core concept.

what i have studied is, if you have interface

public interface interfaceconcept {

    public void heyyou(String s);
    public abstract void nono(String s);
    public void kolk(int i);

}

and you have a class which implements the interface then you have to write the body of all the methods

  public class implementation implements interfaceconcept{

    @Override
    public void heyyou(String s) {
        // TODO Auto-generated method stub

    }

    @Override
    public void nono(String s) {
        // TODO Auto-generated method stub

    }

    @Override
    public void kolk(int i) {
        // TODO Auto-generated method stub

    }

    }

if you dont want to write the methods you can use abstract class

Now i was studing about comparator, and while inpecting its class i found it is an interface

public interface Comparator<T> {
//
}

now it implemented it in another class, firstly it gave me an error saying.

The type Order must implement the inherited abstract method Comparator.compare(Order, Order)

i have added all the method by clicking add unimplemented method and remove all but one.

but when i compiled it, it simply compiled why? am i not supppose to add all the unimplemented methods of comparator interface as per the rules of java?

Also one of its method in comparator class is

default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }

what is the point if you have written the implementation of one method in interface itself? you cant write any body of the method, if i m correct.

public class Order implements Comparator<Order>{

    @Override
    public int compare(Order o1, Order o2) {
        // TODO Auto-generated method stub
        return 0;
    }

    }