问:
What's the fastest way to search for a value in json in SQL, if we do not know the path
I am looking for the fastest way to search in a SQL table for a value in a JSON.

I am trying to update this value. And there may be more occurrences in the same JSON.

```<code>update d
    set d.Content = replace(d.Content, rm.WrongValue , rm.NewValue)
    from dbo.Document d
    inner join RenameMatches rm d.content like '%' + rm.WrongValue + '%'
</code>```

The next line is taking to long and I am trying to make it faster

```<code> d.content like '%' + rm.WrongValue + '%'
</code>```

I thought using JSON_Modify, however, the path is not always the same.

Thanks!

答:
If there's multiple WrongValue's in that RenameMatches, then you could loop through them.

But then it needs some sequencial number without gaps.

In the example below, the values are assumed to be strings.

So they get double-quoted to match complete string values.

Demo:

```<code>--
-- Sample data
--
create table Document (
 document_id int identity primary key,
 content nvarchar(max)
);

insert into Document (content) values
  ('[{"id":1, "code":"abc123"},{"id":2, "code":"def456"}]')
, ('{"id":3, "data":{"name":"test",code1":"abc123","code2":"abc123"}}');

create table RenameMatches (
 WrongValue nvarchar(30) not null primary key,
 NewValue nvarchar(30) not null
);

insert into RenameMatches (WrongValue, NewValue) values
  ('abc123', 'abc12345')
, ('def456', 'def456789');
</code>```

```<code>-- Using a table variable with identity
DECLARE @RenameMatches table (
 id INT identity primary key,
 WrongValue NVARCHAR(30) not null,
 NewValue NVARCHAR(30) not null
);

INSERT INTO @RenameMatches (WrongValue, NewValue)
SELECT WrongValue, NewValue
FROM RenameMatches;

DECLARE @MaxRenameID INT = (SELECT MAX(id) FROM @RenameMatches);
DECLARE @RenameID INT = 1;

WHILE @RenameID <= @MaxRenameID
BEGIN
   UPDATE d
   SET d.Content = REPLACE(d.Content
                   , quotename(rm.WrongValue,'"')
                   , quotename(rm.NewValue,'"'))
   FROM Document d
   JOIN @RenameMatches rm
     ON rm.id = @RenameID
    AND d.content like '%"'+rm.WrongValue+'"%';

   SET @RenameID += 1;
END;
</code>```

```<code>select * from Document
</code>```

document_id
content

1
[{"id":1, "code":"abc12345"},{"id":2, "code":"def456789"}]

2
{"id":3, "data":{"name":"test",code1":"abc12345","code2":"abc12345"}}

Demo on db<>fiddle here

Body:
I am looking for the fastest way to search in a SQL table for a value in a JSON.

I am trying to update this value. And there may be more occurrences in the same JSON.

update d
    set d.Content = replace(d.Content, rm.WrongValue , rm.NewValue)
    from dbo.Document d
    inner join RenameMatches rm d.content like '%' + rm.WrongValue + '%'

The next line is taking to long and I am trying to make it faster

 d.content like '%' + rm.WrongValue + '%'

I thought using JSON_Modify, however, the path is not always the same.

Thanks!

Body:
If there's multiple WrongValue's in that RenameMatches, then you could loop through them.

But then it needs some sequencial number without gaps.

In the example below, the values are assumed to be strings.

So they get double-quoted to match complete string values.

Demo:

--
-- Sample data
--
create table Document (
 document_id int identity primary key,
 content nvarchar(max)
);

insert into Document (content) values
  ('[{"id":1, "code":"abc123"},{"id":2, "code":"def456"}]')
, ('{"id":3, "data":{"name":"test",code1":"abc123","code2":"abc123"}}');

create table RenameMatches (
 WrongValue nvarchar(30) not null primary key,
 NewValue nvarchar(30) not null
);

insert into RenameMatches (WrongValue, NewValue) values
  ('abc123', 'abc12345')
, ('def456', 'def456789');

-- Using a table variable with identity
DECLARE @RenameMatches table (
 id INT identity primary key,
 WrongValue NVARCHAR(30) not null,
 NewValue NVARCHAR(30) not null
);

INSERT INTO @RenameMatches (WrongValue, NewValue)
SELECT WrongValue, NewValue
FROM RenameMatches;

DECLARE @MaxRenameID INT = (SELECT MAX(id) FROM @RenameMatches);
DECLARE @RenameID INT = 1;

WHILE @RenameID <= @MaxRenameID
BEGIN
   UPDATE d
   SET d.Content = REPLACE(d.Content
                   , quotename(rm.WrongValue,'"')
                   , quotename(rm.NewValue,'"'))
   FROM Document d
   JOIN @RenameMatches rm
     ON rm.id = @RenameID
    AND d.content like '%"'+rm.WrongValue+'"%';

   SET @RenameID += 1;
END;

select * from Document

document_id
content

1
[{"id":1, "code":"abc12345"},{"id":2, "code":"def456789"}]

2
{"id":3, "data":{"name":"test",code1":"abc12345","code2":"abc12345"}}

Demo on db<>fiddle here


来源: stackexchange

问:
SVG with 'svg' element embedded
I've a problem with a complicated SVG image.

It works on Chrome and Firefox, but there is no way to convert it into a PNG image even using an online tool or GIMP and also with Inkscape.

I'm not sure where the problem is. Maybe because is it an image built with two other SVG images embedded.

Here is the SVG file.

To reproduce the problem: open the SVG file linked with a browser: it works.

Open it with GIMP and the image is empty.

An easier example with the same problem:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">

  <defs>
      <svg id="pippo" viewBox="0 0 10 10" >
      <circle id="myCircle" cx="5" cy="5" r="5" />
    </svg>

    <linearGradient id="myGradient" gradientTransform="rotate(90)">
      <stop offset="20%" stop-color="gold" />
      <stop offset="90%" stop-color="red" />
    </linearGradient>
  </defs>

  <rect height="100%" width="100%" fill="#fc0" />

  <use x="0" y="0" href="#pippo" fill="url('#myGradient')" />
</svg>```

答:
With SVG 1 you need to use the attribute xlink:href instead of href on the use element

<use x="0" y="0" xlink:href="#pippo" fill="url('#myGradient')" />
```
<p>You will also need the <code>xlink</code> namespace on the <code><svg></code> element</p>
<pre class="lang-xml prettyprint-override"><code><svg
  viewBox="0 0 10 10"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
>
</code>```

Since SVG 2, xlink: prefix is deprecated but SVG 2 is a W3C Candidate Recommendation and all its features are not yet supported by all browsers and editors.

Full SVG 1 example:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

  <defs>
    <svg id="pippo" viewBox="0 0 10 10">
      <circle id="myCircle" cx="5" cy="5" r="5" />
    </svg>

    <linearGradient id="myGradient" gradientTransform="rotate(90)">
      <stop offset="20%" stop-color="gold" />
      <stop offset="90%" stop-color="red" />
    </linearGradient>
  </defs>

  <rect height="100%" width="100%" fill="#fc0" />
  <use x="0" y="0" xlink:href="#pippo" fill="url('#myGradient')" />
</svg>```

ContentLicense: CC BY-SA 4.0

Title: SVG with 'svg' element embedded

Body:
With SVG 1 you need to use the attribute xlink:href instead of href on the use element

<use x="0" y="0" xlink:href="#pippo" fill="url('#myGradient')" />

You will also need the xlink namespace on the <svg> element

<svg
  viewBox="0 0 10 10"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
>

Since SVG 2, xlink: prefix is deprecated but SVG 2 is a W3C Candidate Recommendation and all its features are not yet supported by all browsers and editors.

Full SVG 1 example:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- Some graphical objects to use -->
  <defs>
    <svg id="pippo" viewBox="0 0 10 10">
      <circle id="myCircle" cx="5" cy="5" r="5" />
    </svg>

    <linearGradient id="myGradient" gradientTransform="rotate(90)">
      <stop offset="20%" stop-color="gold" />
      <stop offset="90%" stop-color="red" />
    </linearGradient>
  </defs>

  <!-- using my graphical objects -->
  <rect height="100%" width="100%" fill="#fc0" />
  <use x="0" y="0" xlink:href="#pippo" fill="url('#myGradient')" />
</svg>


问:
Does GRPC have a Channel that can be used for testing?
I'd like to create a simple test but with RPC within the same JVM.

What I was thinking was something like

@Test
void foo() {
    Channel channel = new SomeMagicalObject(new MySystemImpl());
    SystemStub stub =  SystemGrpc.newStub(channel);

    var ret = stub.doSomething(...)
    assertThat(ret).isTrue();
}
```
<p>I was wondering if there's something already built that implements <code>Channel</code> that takes in a GRPC server implementation.  That way I avoid having to run Netty and manage ports etc. Like this...</p>
```private static Server server;
private static Channel channel;

@BeforeAll
@SneakyThrows
static void setupServer() {
    server = ServerBuilder.forPort(0)
            .addService(new MySystemImpl())
            .build()
            .start();
    channel = ManagedChannelBuilder.forAddress("localhost", server.getPort())
            .usePlaintext()
            .build();

}

@AfterAll
@SneakyThrows
static void teardownServer() {
    server
            .shutdown()
            .awaitTermination();
}
```

答:
The InProcess transport is what you want. It is a full-fledged transport, but uses method calls and some tricks to avoid message serialization. It is ideally suited to testing, but is also production-worthy. When used with directExecutor(), tests can be deterministic. InProcess transport is used in the examples. See HelloWorldServerTest for one usage.

private static Server server;
private static Channel channel;

@BeforeAll
@SneakyThrows
static void setupServer() {
    // This code, except for the server.start(),
    // could be moved to the declarations above.
    server = InProcessServerBuilder.forName("test-name")
            .directExecutor()
            .addService(new MySystemImpl())
            .build()
            .start();
    channel = InProcessChannelBuilder.forName("test-name")
            .directExecutor()
            .build();
}

@AfterAll
@SneakyThrows
static void teardownServer() {
    server.shutdownNow();
    channel.shutdownNow();

    // Useful if you are worried about test
    // code continuing to run after the test is
    // considered complete. For a static usage,
    // probably not necessary.
    server.awaitTermination(1, SECONDS);
    channel.awaitTermination(1, SECONDS);
}
```

Body:
I'd like to create a simple test but with RPC within the same JVM.

What I was thinking was something like

@Test
void foo() {
    Channel channel = new SomeMagicalObject(new MySystemImpl());
    SystemStub stub =  SystemGrpc.newStub(channel);

    var ret = stub.doSomething(...)
    assertThat(ret).isTrue();
}

I was wondering if there's something already built that implements Channel that takes in a GRPC server implementation.  That way I avoid having to run Netty and manage ports etc. Like this...

private static Server server;
private static Channel channel;

@BeforeAll
@SneakyThrows
static void setupServer() {
    server = ServerBuilder.forPort(0)
            .addService(new MySystemImpl())
            .build()
            .start();
    channel = ManagedChannelBuilder.forAddress("localhost", server.getPort())
            .usePlaintext()
            .build();

}

@AfterAll
@SneakyThrows
static void teardownServer() {
    server
            .shutdown()
            .awaitTermination();
}


问:
allHeaderFields is not case insensitive when looking up keys
I'm using Alamofire to make my API calls.

Depending on the server I'm using the response headers could be capitalized.

But as the documentation says for allHeaderFields :

var allHeaderFields: [AnyHashable : Any] { get }

A dictionary containing all the HTTP header fields received as part of the server’s response. By examining this dictionary clients can see the “raw” header information returned by the HTTP server.

The keys in this dictionary are the header field names, as received from the server. See RFC 2616 for a list of commonly used HTTP header fields.

HTTP headers are case insensitive. To simplify your code, certain header field names are canonicalized into their standard form. For example, if the server sends a content-length header, it is automatically adjusted to be Content-Length.

The returned dictionary of headers is configured to be case-preserving during the set operation (unless the key already exists with a different case), and case-insensitive when looking up keys.

For example, if you set the header X-foo, and then later set the header X-Foo, the dictionary’s key will be X-foo, but the value will taken from the X-Foo header.

But in my code if I'm doing this :

```<code>if let headers = response.response?.allHeaderFields {
   print("Access-Token: \(response.response?.allHeaderFields["Access-Token"])")
   print("access-token: \(response.response?.allHeaderFields["access-token"])")
   print("access-token: \(response.response?.allHeaderFields["Access-token"])")
}
</code>```

In the console I have

```<code>Access-Token: nil
access-token: Optional(jdRtDzKHNs_i-jt3Lh3a3A)
access-token: nil
</code>```

Am I missing something ?

答:
Apple finally provided a way to do case-insensitive lookups for HTTP headers in Swift. We should call:

```<code>HTTPURLResponse.value(forHTTPHeaderField:)
</code>```

for that instead of using allHeaderFields. You can find this info here (that's the bug report link provided by Eduardo Vital in his answer).

ContentLicense: CC BY-SA 3.0

Body:
I'm using Alamofire to make my API calls.

Depending on the server I'm using the response headers could be capitalized.

But as the documentation says for allHeaderFields :

var allHeaderFields: [AnyHashable : Any] { get }

A dictionary containing all the HTTP header fields received as part of the server’s response. By examining this dictionary clients can see the “raw” header information returned by the HTTP server.

The keys in this dictionary are the header field names, as received from the server. See RFC 2616 for a list of commonly used HTTP header fields.

HTTP headers are case insensitive. To simplify your code, certain header field names are canonicalized into their standard form. For example, if the server sends a content-length header, it is automatically adjusted to be Content-Length.

The returned dictionary of headers is configured to be case-preserving during the set operation (unless the key already exists with a different case), and case-insensitive when looking up keys.

For example, if you set the header X-foo, and then later set the header X-Foo, the dictionary’s key will be X-foo, but the value will taken from the X-Foo header.

But in my code if I'm doing this :

if let headers = response.response?.allHeaderFields {
   print("Access-Token: \(response.response?.allHeaderFields["Access-Token"])")
   print("access-token: \(response.response?.allHeaderFields["access-token"])")
   print("access-token: \(response.response?.allHeaderFields["Access-token"])")
}

In the console I have

Access-Token: nil
access-token: Optional(jdRtDzKHNs_i-jt3Lh3a3A)
access-token: nil

Am I missing something ?

Body:
Apple finally provided a way to do case-insensitive lookups for HTTP headers in Swift. We should call:

HTTPURLResponse.value(forHTTPHeaderField:)

for that instead of using allHeaderFields. You can find this info here (that's the bug report link provided by Eduardo Vital in his answer).


问:
I cant install flask in my project i write pip install flask and when i write flask --version it doesn't recognize it?
```<code>pip install flask
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: flask in c:\users\muden\appdata\roaming\python\python310\site-packages (2.0.2)
Requirement already satisfied: click>=7.1.2 in c:\users\muden\appdata\roaming\python\python310\site-packages (from flask) (8.0.3)
Requirement already satisfied: itsdangerous>=2.0 in c:\users\muden\appdata\roaming\python\python310\site-packages (from flask) (2.0.1)
Requirement already satisfied: Jinja2>=3.0 in c:\users\muden\appdata\roaming\python\python310\site-packages (from flask) (3.0.3)
Requirement already satisfied: Werkzeug>=2.0 in c:\users\muden\appdata\roaming\python\python310\site-packages (from flask) (2.0.3)
Requirement already satisfied: colorama in c:\users\muden\appdata\roaming\python\python310\site-packages (from click>=7.1.2->flask) (0.4.4)
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\muden\appdata\roaming\python\python310\site-packages (from Jinja2>=3.0->flask) (2.0.1)
</code>```

What is the problem Pleaz?

答:
can u try that after creating a virtual environment inside your folder,

steps to create virtual env and using it are here:

step 1:

```<code>    python -m venv venv
</code>```

step 2 for linux :

```<code>    source venv/bin/activate
</code>```

step 2 for windows :

```<code>     source venv\Scripts\activate
</code>```

step 3 : now install your projects requirement here and try running using flask it will work.

```<code>    pip install flask

    flask --version
</code>```

Body:
pip install flask
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: flask in c:\users\muden\appdata\roaming\python\python310\site-packages (2.0.2)
Requirement already satisfied: click>=7.1.2 in c:\users\muden\appdata\roaming\python\python310\site-packages (from flask) (8.0.3)
Requirement already satisfied: itsdangerous>=2.0 in c:\users\muden\appdata\roaming\python\python310\site-packages (from flask) (2.0.1)
Requirement already satisfied: Jinja2>=3.0 in c:\users\muden\appdata\roaming\python\python310\site-packages (from flask) (3.0.3)
Requirement already satisfied: Werkzeug>=2.0 in c:\users\muden\appdata\roaming\python\python310\site-packages (from flask) (2.0.3)
Requirement already satisfied: colorama in c:\users\muden\appdata\roaming\python\python310\site-packages (from click>=7.1.2->flask) (0.4.4)
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\muden\appdata\roaming\python\python310\site-packages (from Jinja2>=3.0->flask) (2.0.1)

What is the problem Pleaz?

Body:
can u try that after creating a virtual environment inside your folder,

steps to create virtual env and using it are here:

step 1:

    python -m venv venv

step 2 for linux :

    source venv/bin/activate

step 2 for windows :

     source venv\Scripts\activate

step 3 : now install your projects requirement here and try running using flask it will work.

    pip install flask

    flask --version


问:
Applying a distinct operation within each rdd
I have some very large pyspark dataframes with many duplicate rows. However, in my use case, the shuffle to do a full distinct() is not worth it in time cost. Instead, I wish to just apply distinct within each partition.  I can't figure out how to do this, however. I've tried:

```<code>>>> spark = SparkSession.builder.appName('foobar').getOrCreate()
>>> data = [("Java", "20000"), ("Python", "100000"), ("Scala", "3000")]
>>> df = spark.createDataFrame(data)
>>> df.rdd.mapPartitions(lambda p: p.distinct()).collect()
</code>```

and

```<code>>>> spark = SparkSession.builder.appName('foobar').getOrCreate()
>>> data = [("Java", "20000"), ("Python", "100000"), ("Scala", "3000")]
>>> df = spark.createDataFrame(data)
>>> df.foreachPartition(lambda p: p.distinct()).collect()
</code>```

but in both cases I get

```<code>AttributeError: 'itertools.chain' object has no attribute 'distinct'
</code>```

Would you please have advice on how to achieve this?

答:
The type of p in mapPartitions is an itertools.chain, not an RDD. You can return the unique elements from a chain with a function like below and then use it in the call to mapPartitions:

def uniq(chain):
    seen = set()
    for x in chain:
        if x in seen:
            continue
        seen.add(x)
        yield x

rdd = sc.parallelize([1,2,2,3,3,4])
rdd.repartition(1).mapPartitions(uniq).foreach(print)

# outputs
# 1
# 2
# 3
# 4
```
<p>I've repartitioned into a single partition above to simulate uniqueness across the whole example data set but this will work correctly assuming you have already partitioned your data appropriately.</p>
<p>EDIT:</p>
<p><strong>Performance</strong></p>
<p>I don't know spark perf that well but in general the <code>uniq</code> function above should be faster than <code>distinct</code> because we are explicitly operating on a single partition rather than spark having to coordinate the distinctness across multiple partitions.</p>
<p>Even if there only happens to be 1 partition I suspect there is still a layer of coordination as indicated by the below results - I'm actually pretty surprised how much faster using <code>uniq</code> was over <code>distinct</code> on a single partition...</p>
<p>The below isn't concrete due to the very low sample size running locally but hopefully it gives a rough indicator.</p>
<pre class="lang-py prettyprint-override"><code># setup
rdd = sc.parallelize(["hello"] * 1000000).repartition(1)
rdd2 = rdd.repartition(2)

import timeit

# uniq 1 partition
timeit.timeit(lambda: rdd.mapPartitions(uniq).foreach(print), number=100)
# snip output...
17.04100012999993

# uniq 2 partitions
timeit.timeit(lambda: rdd2.mapPartitions(uniq).foreach(print), number=100)
# snip output...
9.535805986000014

# distinct 1 partition
timeit.timeit(lambda: rdd.distinct().foreach(print), number=100)
# snip output...
74.313582924

# distinct 2 partitions
timeit.timeit(lambda: rdd2.distinct().foreach(print), number=100)
# snip output...
38.47051327800011
</code>```

So the mapPartitions(uniq) approach seems to be a fair bit more performant (bearing in mind the above is a pretty limited test).

Body:
I have some very large pyspark dataframes with many duplicate rows. However, in my use case, the shuffle to do a full distinct() is not worth it in time cost. Instead, I wish to just apply distinct within each partition.  I can't figure out how to do this, however. I've tried:

>>> spark = SparkSession.builder.appName('foobar').getOrCreate()
>>> data = [("Java", "20000"), ("Python", "100000"), ("Scala", "3000")]
>>> df = spark.createDataFrame(data)
>>> df.rdd.mapPartitions(lambda p: p.distinct()).collect()

and

>>> spark = SparkSession.builder.appName('foobar').getOrCreate()
>>> data = [("Java", "20000"), ("Python", "100000"), ("Scala", "3000")]
>>> df = spark.createDataFrame(data)
>>> df.foreachPartition(lambda p: p.distinct()).collect()

but in both cases I get

AttributeError: 'itertools.chain' object has no attribute 'distinct'

Would you please have advice on how to achieve this?

Body:
The type of p in mapPartitions is an itertools.chain, not an RDD. You can return the unique elements from a chain with a function like below and then use it in the call to mapPartitions:

def uniq(chain):
    seen = set()
    for x in chain:
        if x in seen:
            continue
        seen.add(x)
        yield x

rdd = sc.parallelize([1,2,2,3,3,4])
rdd.repartition(1).mapPartitions(uniq).foreach(print)

# outputs
# 1
# 2
# 3
# 4

I've repartitioned into a single partition above to simulate uniqueness across the whole example data set but this will work correctly assuming you have already partitioned your data appropriately.

EDIT:

Performance

I don't know spark perf that well but in general the uniq function above should be faster than distinct because we are explicitly operating on a single partition rather than spark having to coordinate the distinctness across multiple partitions.

Even if there only happens to be 1 partition I suspect there is still a layer of coordination as indicated by the below results - I'm actually pretty surprised how much faster using uniq was over distinct on a single partition...

The below isn't concrete due to the very low sample size running locally but hopefully it gives a rough indicator.

# setup
rdd = sc.parallelize(["hello"] * 1000000).repartition(1)
rdd2 = rdd.repartition(2)

import timeit

# uniq 1 partition
timeit.timeit(lambda: rdd.mapPartitions(uniq).foreach(print), number=100)
# snip output...
17.04100012999993

# uniq 2 partitions
timeit.timeit(lambda: rdd2.mapPartitions(uniq).foreach(print), number=100)
# snip output...
9.535805986000014

# distinct 1 partition
timeit.timeit(lambda: rdd.distinct().foreach(print), number=100)
# snip output...
74.313582924

# distinct 2 partitions
timeit.timeit(lambda: rdd2.distinct().foreach(print), number=100)
# snip output...
38.47051327800011

So the mapPartitions(uniq) approach seems to be a fair bit more performant (bearing in mind the above is a pretty limited test).


问:
How to make sure a line of code is executed after another is completed?
I have a viewControl called PostViewController which has a UITableView of posts. I also have a class called PostCell which defines the UITableViewCell. I made a button function in PostCell called likeButtonClicked to favour a post similar to twitter.

```<code>@IBAction func likesButtonClicked(_ sender: Any) { NotificationCenter.default.post(name: NSNotification.Name(rawValue: "likeButtonClicked"), object: nil, userInfo: ["cell":self, "likesButton":likesButton!]) }
</code>```

This is to pass the cell indexPath and the button name to PostViewController. I need indexPath to increase the likes by 1 and the button name to change its image to pink when post is favoured.

I then subscribed to the notification in viewDidLoad of PostViewController.

```<code> NotificationCenter.default.addObserver(self, selector: #selector(postLiked), name: NSNotification.Name(rawValue: "likeButtonClicked"), object: nil)
</code>```

I then wrote this function in the same viewController

```<code>  @objc func postLiked(notification: Notification){
    if let cell = notification.userInfo?["cell"] as? UITableViewCell{
        let likesButton = notification.userInfo?["likesButton"] as? SpringButton
        if let indexPath = postsTableView.indexPath(for: cell){
            let post = posts[indexPath.row]
            postId = post.id
            PostAPI.getPostById(postId: postId) { post in
                //Check if the same post were already favoured.
                if !self.liked || self.oldPostId != self.postId{
                    self.newLikes = post.likes + 1
                    self.liked = true
                    self.oldPostId = self.postId
                }else{
                    self.newLikes = self.newLikes - 1
                    self.liked = false
                }
                PostAPI.favourPost(postId: self.postId, likes: self.newLikes) {
                    PostAPI.getPostById(postId: self.postId) { postResponse in
                        let post = postResponse
                        self.posts[indexPath.row] = post
                        let cellNumber = IndexPath(row: indexPath.row, section: indexPath.section)
                        self.reloadRowData(cellNumber: cellNumber){
                            if !self.liked{
                                likesButton?.tintColor = .systemPink
                            }else{
                                likesButton?.tintColor = .darkGray
                            }
                        }
                    }
                }
            }
        }
    }
}
func reloadRowData(cellNumber: IndexPath, completion: @escaping () -> ()) {
    self.postsTableView.reloadRows(at: [cellNumber], with: .none)
    completion()
}

</code>```

Please tell me why the last 4 lines of postLiked function is executed before reloadRowData function, which causes the button to change its color to pink then returns immediately to gray when it should stay pink.

Any help will be most appreciated.
Thank you.

答:
<s>A table view's .reloadRows(at:...) (and .reloadData()) functions are async processes.

So your reloadRowData() func is returning before the table view actually reloads the row(s).

This is a rather unusual approach - both in using NotificationCenter for your cells to communicate with the controller, and in trying to change the button's tint color by holding a reference to the button.

The tint color really should be set in cellForRowAt, based on your data source.</s>

Edit

My description of table view data reloading being asynchronous was misleading.

The point I wanted to make was this...

If I change my data, call .reloadData(), and then change my data again:

```<code>    // set myData values
    myData = ["You", "Say", "Hello"]

    // call .reloadData here
    tableView.reloadData()

    // change myData values
    myData = ["I", "Say", "Goodbye"]

</code>```

the table view will not display "You Say Hello" even though we call .reloadData() when those are the values of myData.

Here's a complete, simple example to demonstrate:

```<code>class TestTableViewController: UITableViewController {

    var myData: [String] = ["Some", "Song", "Lyrics"]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "c")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myData.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let c = tableView.dequeueReusableCell(withIdentifier: "c", for: indexPath)
        c.textLabel?.text = myData[indexPath.row]
        return c
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // call my func when a row is selected
        self.myReload()
    }

    func myReload() {

        // set myData values
        myData = ["You", "Say", "Hello"]

        // call .reloadData here
        tableView.reloadData()

        // change myData values
        myData = ["I", "Say", "Goodbye"]

        // table view doesn't reload itself we exit this func
        // so we'll get
        //  I
        //  Say
        //  Goodbye

    }

}
</code>```

So, among the other issues described by Rob Napier in his answer, your original code was trying to change the tint color of an object in a cell before the table reloaded its data.

Body:
I have a viewControl called PostViewController which has a UITableView of posts. I also have a class called PostCell which defines the UITableViewCell. I made a button function in PostCell called likeButtonClicked to favour a post similar to twitter.

@IBAction func likesButtonClicked(_ sender: Any) { NotificationCenter.default.post(name: NSNotification.Name(rawValue: "likeButtonClicked"), object: nil, userInfo: ["cell":self, "likesButton":likesButton!]) }

This is to pass the cell indexPath and the button name to PostViewController. I need indexPath to increase the likes by 1 and the button name to change its image to pink when post is favoured.

I then subscribed to the notification in viewDidLoad of PostViewController.

 NotificationCenter.default.addObserver(self, selector: #selector(postLiked), name: NSNotification.Name(rawValue: "likeButtonClicked"), object: nil)

I then wrote this function in the same viewController

  @objc func postLiked(notification: Notification){
    if let cell = notification.userInfo?["cell"] as? UITableViewCell{
        let likesButton = notification.userInfo?["likesButton"] as? SpringButton
        if let indexPath = postsTableView.indexPath(for: cell){
            let post = posts[indexPath.row]
            postId = post.id
            PostAPI.getPostById(postId: postId) { post in
                //Check if the same post were already favoured.
                if !self.liked || self.oldPostId != self.postId{
                    self.newLikes = post.likes + 1
                    self.liked = true
                    self.oldPostId = self.postId
                }else{
                    self.newLikes = self.newLikes - 1
                    self.liked = false
                }
                PostAPI.favourPost(postId: self.postId, likes: self.newLikes) {
                    PostAPI.getPostById(postId: self.postId) { postResponse in
                        let post = postResponse
                        self.posts[indexPath.row] = post
                        let cellNumber = IndexPath(row: indexPath.row, section: indexPath.section)
                        self.reloadRowData(cellNumber: cellNumber){
                            if !self.liked{
                                likesButton?.tintColor = .systemPink
                            }else{
                                likesButton?.tintColor = .darkGray
                            }
                        }
                    }
                }
            }
        }
    }
}
func reloadRowData(cellNumber: IndexPath, completion: @escaping () -> ()) {
    self.postsTableView.reloadRows(at: [cellNumber], with: .none)
    completion()
}

Please tell me why the last 4 lines of postLiked function is executed before reloadRowData function, which causes the button to change its color to pink then returns immediately to gray when it should stay pink.

Any help will be most appreciated.
Thank you.

Body:
<s>A table view's .reloadRows(at:...) (and .reloadData()) functions are async processes.

So your reloadRowData() func is returning before the table view actually reloads the row(s).

This is a rather unusual approach - both in using NotificationCenter for your cells to communicate with the controller, and in trying to change the button's tint color by holding a reference to the button.

The tint color really should be set in cellForRowAt, based on your data source.</s>

Edit

My description of table view data reloading being asynchronous was misleading.

The point I wanted to make was this...

If I change my data, call .reloadData(), and then change my data again:

    // set myData values
    myData = ["You", "Say", "Hello"]

    // call .reloadData here
    tableView.reloadData()

    // change myData values
    myData = ["I", "Say", "Goodbye"]

the table view will not display "You Say Hello" even though we call .reloadData() when those are the values of myData.

Here's a complete, simple example to demonstrate:

class TestTableViewController: UITableViewController {

    var myData: [String] = ["Some", "Song", "Lyrics"]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "c")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myData.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let c = tableView.dequeueReusableCell(withIdentifier: "c", for: indexPath)
        c.textLabel?.text = myData[indexPath.row]
        return c
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // call my func when a row is selected
        self.myReload()
    }

    func myReload() {

        // set myData values
        myData = ["You", "Say", "Hello"]

        // call .reloadData here
        tableView.reloadData()

        // change myData values
        myData = ["I", "Say", "Goodbye"]

        // table view doesn't reload itself we exit this func
        // so we'll get
        //  I
        //  Say
        //  Goodbye

    }

}

So, among the other issues described by Rob Napier in his answer, your original code was trying to change the tint color of an object in a cell before the table reloaded its data.


问:
How to send an email when item is added to Cosmos DB with Azure Functions
I want to have a Cosmos DB trigger which gives me the added document, which I can use to send an email via Sendgrid.

Now I've already added the Cosmos DB trigger, and also the Sendgrid output, but I don't really know how to get the added document from the Cosmos DB.

Can anyone help?

```<code>// function.json
{
  "bindings": [
    {
      "type": "cosmosDBTrigger",
      "name": "restaurant",
      "direction": "in",
      "leaseCollectionName": "leases",
      "connectionStringSetting": "connection-string",
      "databaseName": "database-name",
      "collectionName": "collection-name",
      "createLeaseCollectionIfNotExists": true
    },
    {
      "type": "sendGrid",
      "name": "message",
      "direction": "out",
      "apiKey": "SENDGRID_API_KEY",
      "from": "from",
      "to": "{customerEmail}",
      "subject": "",
      "text": ""
    }
  ]
}
</code>```

答:
Based on the official examples: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-cosmosdb-v2-trigger?tabs=javascript

module.exports = function (context, restaurant) {
      context.log('First document Id modified : ', restaurant[0].id);
      // the restaurant variable is an array where 1 or more modified documents can come, iterate and consume
      context.done();
    }
```

You can loop on the restaurant variable (the name maps to the name you defined in the name property in your config) and for each document, send an email.

Remember to have try/catch blocks within any loop in case one of the emails fails to send for whatever reason, the loop does continue with the rest. Log any errors, but avoid exiting the function if there is more documents to process.

Body:
I want to have a Cosmos DB trigger which gives me the added document, which I can use to send an email via Sendgrid.

Now I've already added the Cosmos DB trigger, and also the Sendgrid output, but I don't really know how to get the added document from the Cosmos DB.

Can anyone help?

// function.json
{
  "bindings": [
    {
      "type": "cosmosDBTrigger",
      "name": "restaurant",
      "direction": "in",
      "leaseCollectionName": "leases",
      "connectionStringSetting": "connection-string",
      "databaseName": "database-name",
      "collectionName": "collection-name",
      "createLeaseCollectionIfNotExists": true
    },
    {
      "type": "sendGrid",
      "name": "message",
      "direction": "out",
      "apiKey": "SENDGRID_API_KEY",
      "from": "from",
      "to": "{customerEmail}",
      "subject": "",
      "text": ""
    }
  ]
}

Body:
Based on the official examples: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-cosmosdb-v2-trigger?tabs=javascript

module.exports = function (context, restaurant) {
      context.log('First document Id modified : ', restaurant[0].id);
      // the restaurant variable is an array where 1 or more modified documents can come, iterate and consume
      context.done();
    }

You can loop on the restaurant variable (the name maps to the name you defined in the name property in your config) and for each document, send an email.

Remember to have try/catch blocks within any loop in case one of the emails fails to send for whatever reason, the loop does continue with the rest. Log any errors, but avoid exiting the function if there is more documents to process.


问:
Customize Spring boot Kafka listener metrics
We have a microservice architecture on the project and we use Prometheus and Grafana for monitoring. The services are implemented using Spring Boot and the integration with Prometheus is through spring-boot-actuator.
There are some Kafka consumers in the project, and for each @KafkaListener spring is generating some metrics. Here is a sample of the Prometheus time series for the metric spring_kafka_listener_seconds_count

```<code>spring_kafka_listener_seconds_count{exception="ListenerExecutionFailedException", instance="192.168.100.4:8001", job="spring-actuator", name="org.springframework.kafka.KafkaListenerEndpointContainer#0-0", result="failure"} 2
spring_kafka_listener_seconds_count{exception="none", instance="192.168.100.4:8001", job="spring-actuator", name="org.springframework.kafka.KafkaListenerEndpointContainer#0-0", result="success"} 2
spring_kafka_listener_seconds_count{exception="none", instance="192.168.100.4:8001", job="spring-actuator", name="org.springframework.kafka.KafkaListenerEndpointContainer#1-0", result="success"} 4
</code>```

org.springframework.kafka.KafkaListenerEndpointContainer#0-0 - doesn't give much info regarding the @KafkaListener method of interest.
Is it possible to configure more meaningful value for the name label of these metrics?

答:
Give the listener a meaningful id.

@KafkaListener(id = "someId", ...)

Note that, by default, the id will be used as the consumer group.id, unless you also specify group, or set idIsGroup to false.

Body:
We have a microservice architecture on the project and we use Prometheus and Grafana for monitoring. The services are implemented using Spring Boot and the integration with Prometheus is through spring-boot-actuator.
There are some Kafka consumers in the project, and for each @KafkaListener spring is generating some metrics. Here is a sample of the Prometheus time series for the metric spring_kafka_listener_seconds_count

spring_kafka_listener_seconds_count{exception="ListenerExecutionFailedException", instance="192.168.100.4:8001", job="spring-actuator", name="org.springframework.kafka.KafkaListenerEndpointContainer#0-0", result="failure"} 2
spring_kafka_listener_seconds_count{exception="none", instance="192.168.100.4:8001", job="spring-actuator", name="org.springframework.kafka.KafkaListenerEndpointContainer#0-0", result="success"} 2
spring_kafka_listener_seconds_count{exception="none", instance="192.168.100.4:8001", job="spring-actuator", name="org.springframework.kafka.KafkaListenerEndpointContainer#1-0", result="success"} 4

org.springframework.kafka.KafkaListenerEndpointContainer#0-0 - doesn't give much info regarding the @KafkaListener method of interest.
Is it possible to configure more meaningful value for the name label of these metrics?


问:
ClickOnce on a net6 Console + Web Project
I have a kestrel enabled web app (I need to set up a web server listening on a custom port), but this should remain a console application that must be executed on our customers' PCs.

Everything's working as expected but I cannot use ClickOnce as publish profile. It just does not appear on Visual Studio 2022 publish profiles.

In my current configuration my csproj file is:

```<code><Project Sdk="Microsoft.NET.Sdk.Web">
</code>```

Modifying that with:

```<code><Project Sdk="Microsoft.NET.Sdk">
</code>```

magically ClickOnce publish profile appears, but I cannot use kestrel and asp.net infrastructure (that I need), even adding the dependencies.

How can I force visual studio to allow ClickOnce also on Web Projects?

Or as an alternative (but the former is preferred), how can I run asp.net infrastructure without Microsoft.NET.Sdk.Web?

Thanks in advance

答:
I think you could stay with Microsoft.NET.Sdk and add a reference to the ASP.NET Core shared framework.

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/target-aspnetcore?view=aspnetcore-6.0&tabs=visual-studio#use-the-aspnet-core-shared-framework

Your .csproj file should be something similar to this

```<code><Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>
</code>```

Body:
I have a kestrel enabled web app (I need to set up a web server listening on a custom port), but this should remain a console application that must be executed on our customers' PCs.

Everything's working as expected but I cannot use ClickOnce as publish profile. It just does not appear on Visual Studio 2022 publish profiles.

In my current configuration my csproj file is:

<Project Sdk="Microsoft.NET.Sdk.Web">

Modifying that with:

<Project Sdk="Microsoft.NET.Sdk">

magically ClickOnce publish profile appears, but I cannot use kestrel and asp.net infrastructure (that I need), even adding the dependencies.

How can I force visual studio to allow ClickOnce also on Web Projects?

Or as an alternative (but the former is preferred), how can I run asp.net infrastructure without Microsoft.NET.Sdk.Web?

Thanks in advance

Body:
I think you could stay with Microsoft.NET.Sdk and add a reference to the ASP.NET Core shared framework.

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/target-aspnetcore?view=aspnetcore-6.0&tabs=visual-studio#use-the-aspnet-core-shared-framework

Your .csproj file should be something similar to this

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>


问:
Is there a way to put a pie chart into a dashboard?
Here's how my code looks like

```<code>#create figure to be used as dashboard
fig = plt.figure(figsize = (16, 10), constrained_layout = True)

# Use GridSpec to determine the dimensions of the dashboard
gs = GridSpec(nrows = 2, ncols = 2, figure = fig)

ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, 0])
ax4 = fig.add_subplot(gs[1, 1])
</code>```

And my code for creating the pie chart is here

```<code>country = df.groupby('customer_country')['orderid'].count()
country = country.sort_values(ascending = False)
plt.figure(figsize=(10,6))
plt.title('Proportion of Orders From Countries', fontsize = 15)
plt.pie(country,
    explode=(0.1,0.1,0.1,0.1,0.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
    labels = country.index,
    autopct='%1.1f%%',
    pctdistance = 0.7)
</code>```

I know that when plotting graphs into a dashboard used ax1.bar() or ax2.plot() or something but I'm unsure of pie charts.

I appreciate any and all suggestions :))

答:
Wait, I figured it out. I had to remove plt.figure(figsize=(10,6))
Thank you to anyone who took a look at my question.</p>

Body:
Here's how my code looks like

#create figure to be used as dashboard
fig = plt.figure(figsize = (16, 10), constrained_layout = True)

# Use GridSpec to determine the dimensions of the dashboard
gs = GridSpec(nrows = 2, ncols = 2, figure = fig)

ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, 0])
ax4 = fig.add_subplot(gs[1, 1])

And my code for creating the pie chart is here

country = df.groupby('customer_country')['orderid'].count()
country = country.sort_values(ascending = False)
plt.figure(figsize=(10,6))
plt.title('Proportion of Orders From Countries', fontsize = 15)
plt.pie(country,
    explode=(0.1,0.1,0.1,0.1,0.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
    labels = country.index,
    autopct='%1.1f%%',
    pctdistance = 0.7)

I know that when plotting graphs into a dashboard used ax1.bar() or ax2.plot() or something but I'm unsure of pie charts.

I appreciate any and all suggestions :))


问:
How can I return some InsettableShape Protocol in SwiftUI
I have a function which returns some InsettableShape like this:

```<code>func test(value: Int) -> some InsettableShape {

    if (value == 0) {
        return Circle()
    }
    else if (value == 1) {
        return Capsule()
    }
    else {
        return Rectangle()
    }

}
</code>```

Xcode give an error of:

Function declares an opaque return type, but the return statements in its body do not have matching underlying types

because there is a missing ShapeBuilder or InsettableShapeBuilder wrapper, I cannot make this code work, how can I solve this problem?

答:
Ok, the task is to convert all those different value-types to one single, so we need a non-generic type wrapper confirming to InsettableShape protocol.

Here is a simplified demo of possible approach. Tested with Xcode 13.2 / iOS 15.2

```<code>struct Demo_Previews: PreviewProvider {
    static var previews: some View {
        test(value: 0)
            .strokeBorder(Color.red, style: StrokeStyle(lineWidth: 50.0, lineCap: .round, lineJoin: .round))
    }
}

func test(value: Int) -> some InsettableShape {
    if (value == 0) {
        return MyInsettableShape { Circle().trim(from: 0, to: 0.5).path(in: $0) }
    }
    else if (value == 1) {
        return MyInsettableShape { Capsule().path(in: $0) }
    }
    else {
        return MyInsettableShape { Rectangle().path(in: $0) }
    }
}

// Shape independent wrapper - possible, because any shape
// can provide a path for specified region rectangle
struct MyInsettableShape: InsettableShape {

    private let base: (CGRect) -> Path
    private let inset: CGFloat

    init(base: @escaping (CGRect) -> Path, inset: CGFloat = 0) {
        self.base = base
        self.inset = inset
    }

    func inset(by amount: CGFloat) -> Self {
        .init(base: base, inset: amount)
    }

    func path(in rect: CGRect) -> Path {
        base(rect.inset(by: .init(top: inset, left: inset, bottom: inset, right: inset)))
    }
}
</code>```

Body:
I have a function which returns some InsettableShape like this:

func test(value: Int) -> some InsettableShape {

    if (value == 0) {
        return Circle()
    }
    else if (value == 1) {
        return Capsule()
    }
    else {
        return Rectangle()
    }

}

Xcode give an error of:

Function declares an opaque return type, but the return statements in its body do not have matching underlying types

because there is a missing ShapeBuilder or InsettableShapeBuilder wrapper, I cannot make this code work, how can I solve this problem?

Body:
Ok, the task is to convert all those different value-types to one single, so we need a non-generic type wrapper confirming to InsettableShape protocol.

Here is a simplified demo of possible approach. Tested with Xcode 13.2 / iOS 15.2

struct Demo_Previews: PreviewProvider {
    static var previews: some View {
        test(value: 0)
            .strokeBorder(Color.red, style: StrokeStyle(lineWidth: 50.0, lineCap: .round, lineJoin: .round))
    }
}

func test(value: Int) -> some InsettableShape {
    if (value == 0) {
        return MyInsettableShape { Circle().trim(from: 0, to: 0.5).path(in: $0) }
    }
    else if (value == 1) {
        return MyInsettableShape { Capsule().path(in: $0) }
    }
    else {
        return MyInsettableShape { Rectangle().path(in: $0) }
    }
}

// Shape independent wrapper - possible, because any shape
// can provide a path for specified region rectangle
struct MyInsettableShape: InsettableShape {

    private let base: (CGRect) -> Path
    private let inset: CGFloat

    init(base: @escaping (CGRect) -> Path, inset: CGFloat = 0) {
        self.base = base
        self.inset = inset
    }

    func inset(by amount: CGFloat) -> Self {
        .init(base: base, inset: amount)
    }

    func path(in rect: CGRect) -> Path {
        base(rect.inset(by: .init(top: inset, left: inset, bottom: inset, right: inset)))
    }
}


问:
Capture click event on the screen of vlc in tkinter
I am running a stripped down version of the python-vlc example for tkinter on Windows 7 and Python 2.7.

I am trying to register clicks onto the video screen itself, without any buttons or additional UI.
However, no matter where I try to .bind() a listener, VLC appears to swallow all input and my callback function is never called.

This is probably way too much code to post here, but at least it should run. Any help appreciated!

```<code>#! /usr/bin/python
# -*- coding: utf-8 -*-

import vlc, sys, os, time, platform
import Tkinter as Tk
import ttk

def onClick():
    print "a click was successful!"

class Player(Tk.Frame):
    """The main window has to deal with events.
    """
    def __init__(self, parent, title=None, url=""):
        Tk.Frame.__init__(self, parent)
        self.parent = parent
        self.url = url

        self.player = None
        self.videopanel = ttk.Frame(self.parent)
        self.canvas = Tk.Canvas(self.videopanel,bg="blue")

        #try to listen for clicks
        self.videopanel.bind('<Button-1>', onClick)
        self.canvas.bind('<Button-1>', onClick)

        self.canvas.pack(fill=Tk.BOTH,expand=1)
        self.videopanel.pack(fill=Tk.BOTH,expand=1)

        # VLC player controls
        self.Instance = vlc.Instance()
        self.player = self.Instance.media_player_new()

        self.parent.update()

        self.Media = self.Instance.media_new(self.url)
        self.player.set_media(self.Media)

        # set the window id where to render VLC's video output
        if platform.system() == 'Windows':
            self.player.set_hwnd(self.GetHandle())
        else:
            self.player.set_xwindow(self.GetHandle()) # this line messes up windows

        self.player.play()

    def GetHandle(self):
        return self.videopanel.winfo_id()

if __name__ == "__main__":

    root = Tk.Tk()

    player = Player(root, title="tkinter vlc", url="video.mp4")
    player.bind('<Button-1>', onClick)

    root.mainloop()
</code>```

答:
This is not the tkinter question, this is the libvlc question.

VLC will create its own HWND handle above your video widget.

So you should make the VLC widget transparent for mouse events.

See my answer at https://stackoverflow.com/a/71067838/5254103

Body:
I am running a stripped down version of the python-vlc example for tkinter on Windows 7 and Python 2.7.

I am trying to register clicks onto the video screen itself, without any buttons or additional UI.
However, no matter where I try to .bind() a listener, VLC appears to swallow all input and my callback function is never called.

This is probably way too much code to post here, but at least it should run. Any help appreciated!

#! /usr/bin/python
# -*- coding: utf-8 -*-

import vlc, sys, os, time, platform
import Tkinter as Tk
import ttk

def onClick():
    print "a click was successful!"

class Player(Tk.Frame):
    """The main window has to deal with events.
    """
    def __init__(self, parent, title=None, url=""):
        Tk.Frame.__init__(self, parent)
        self.parent = parent
        self.url = url

        self.player = None
        self.videopanel = ttk.Frame(self.parent)
        self.canvas = Tk.Canvas(self.videopanel,bg="blue")

        #try to listen for clicks
        self.videopanel.bind('<Button-1>', onClick)
        self.canvas.bind('<Button-1>', onClick)

        self.canvas.pack(fill=Tk.BOTH,expand=1)
        self.videopanel.pack(fill=Tk.BOTH,expand=1)

        # VLC player controls
        self.Instance = vlc.Instance()
        self.player = self.Instance.media_player_new()

        self.parent.update()

        self.Media = self.Instance.media_new(self.url)
        self.player.set_media(self.Media)

        # set the window id where to render VLC's video output
        if platform.system() == 'Windows':
            self.player.set_hwnd(self.GetHandle())
        else:
            self.player.set_xwindow(self.GetHandle()) # this line messes up windows

        self.player.play()

    def GetHandle(self):
        return self.videopanel.winfo_id()

if __name__ == "__main__":

    root = Tk.Tk()

    player = Player(root, title="tkinter vlc", url="video.mp4")
    player.bind('<Button-1>', onClick)

    root.mainloop()


问:
Is there a CakePHP offline manual
There used to be, but there don't seem to be any direct links. A little digging around revealed some answers which I thought it would be useful to share.

These are links to the manual in one page - useful for offline
use or creating a PDF using Dardo Sordi Bogado's build script.

1.2 Manual in one page
https://web.archive.org/web/20120730003805/http://book.cakephp.org/complete/3/The-Manual

1.3 Manual in one page
https://web.archive.org/web/20120730004040/http://book.cakephp.org/complete/876/The-Manual

答: take my work: http://sourceforge.net/projects/cakephp-doc/files/</p>

Title: Is there a CakePHP offline manual


问:
How can i replace variables inside quotation marks in parallel
I want to run on parallel a command that inputs two variables into a gnuplot file, I tried with:

```<code>parallel 'OMP_NUM_THREADS=11 gnuplot -e 'alpha={}; file="{}.txt"' graf_separation_time.gp' ::: 0 1 2 3 4 5 6 7 8 9 10
</code>```

But it doesn't work, any suggestions?

答:
You are being hit by using ' inside '. Quoting is hard to get right, so it is often easier to define a function, test it and then have GNU Parallel call that.

Untested:

```<code>gp() {
  OMP_NUM_THREADS=11 gnuplot -e 'alpha='"$1"'; file="'"$1"'.txt" graf_separation_time.gp'
}
export -f gp
parallel gp {} ::: 0 1 2 3 4 5 6 7 8 9 10
</code>```

This will probably also work:

```<code>parallel -q OMP_NUM_THREADS=11 gnuplot -e 'alpha={}; file="{}.txt" graf_separation_time.gp' ::: 0 1 2 3 4 5 6 7 8 9 10
</code>```

Read more: https://www.gnu.org/software/parallel/man.html#quoting

Body:
I want to run on parallel a command that inputs two variables into a gnuplot file, I tried with:

parallel 'OMP_NUM_THREADS=11 gnuplot -e 'alpha={}; file="{}.txt"' graf_separation_time.gp' ::: 0 1 2 3 4 5 6 7 8 9 10

But it doesn't work, any suggestions?

Body:
You are being hit by using ' inside '. Quoting is hard to get right, so it is often easier to define a function, test it and then have GNU Parallel call that.

Untested:

gp() {
  OMP_NUM_THREADS=11 gnuplot -e 'alpha='"$1"'; file="'"$1"'.txt" graf_separation_time.gp'
}
export -f gp
parallel gp {} ::: 0 1 2 3 4 5 6 7 8 9 10

This will probably also work:

parallel -q OMP_NUM_THREADS=11 gnuplot -e 'alpha={}; file="{}.txt" graf_separation_time.gp' ::: 0 1 2 3 4 5 6 7 8 9 10

Read more: https://www.gnu.org/software/parallel/man.html#quoting


问:
XPath for attribute based on predecessor's attribute value?
So I have something like this

```<code><img src="/icons/folder.gif" alt="[DIR]"> <a href="convobot-main/">convobot-main/</a>
</code>```

and I want to select the a href only when the img tag has the attribute alt = "[Dir]". How can I achieve this?

答:
This XPath,

```<code>//img[@alt='[DIR]']/following-sibling::a[1]/@href
</code>```

will select href attributes of all first a siblings of all img elements with an alt attribute value of '[DIR]'.

Body:
So I have something like this

 convobot-main/

and I want to select the a href only when the img tag has the attribute alt = "[Dir]". How can I achieve this?

Body:
This XPath,

//img[@alt='[DIR]']/following-sibling::a[1]/@href

will select href attributes of all first a siblings of all img elements with an alt attribute value of '[DIR]'.


问:
Django TypeError object of type 'ManyRelatedManager' has no len()
I am trying to customise the create method for Combination objects. The field tag_id should be limited to 2 Tag instances. I have tried something like

```<code>if len(combination.tag_id) == 2:
</code>```

and I am getting the error object of type 'ManyRelatedManager' has no len()

Is there another way to set the maximum length of this field to 2?

models.py

```<code>class Combination(models.Model):

    user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
    gameround = models.ForeignKey(Gameround, on_delete=models.CASCADE, null=True)
    resource = models.ForeignKey(Resource, on_delete=models.CASCADE, null=True)
    tag_id = models.ManyToManyField(Tag, null=True)
    created = models.DateTimeField(editable=False)
    score = models.PositiveIntegerField(default=0)

    objects = models.Manager()

    def __str__(self):
        return str(self.tag_id) or ''
</code>```

serializers.py

```<code>  def create(self, validated_data):
    user = None
    request = self.context.get("request")
    if request and hasattr(request, "user"):
      user = request.user

    score = 0
    resource_id = validated_data.get("resource")

    combination = Combination(
      user=user,
      gameround=validated_data.get("gameround"),
      resource=validated_data.get("resource"),
      created=datetime.now(),
      score=score
    )
    combination.save()

    tag_data = validated_data.pop('tag_id', None)
    for tag_item in tag_data:
      tag = Tag.objects.get_or_create(**tag_item)[0]
      combination.tag_id.add(tag)

      # if len(combination.tag_id) == 2:
    return combination
</code>```

答:
Solved by adding:</p>
```<code>      if combination.tag_id.count() == 2:
        return combination
</code>```

Body:
I am trying to customise the create method for Combination objects. The field tag_id should be limited to 2 Tag instances. I have tried something like

if len(combination.tag_id) == 2:

and I am getting the error object of type 'ManyRelatedManager' has no len()

Is there another way to set the maximum length of this field to 2?

models.py

class Combination(models.Model):

    user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
    gameround = models.ForeignKey(Gameround, on_delete=models.CASCADE, null=True)
    resource = models.ForeignKey(Resource, on_delete=models.CASCADE, null=True)
    tag_id = models.ManyToManyField(Tag, null=True)
    created = models.DateTimeField(editable=False)
    score = models.PositiveIntegerField(default=0)

    objects = models.Manager()

    def __str__(self):
        return str(self.tag_id) or ''

serializers.py

  def create(self, validated_data):
    user = None
    request = self.context.get("request")
    if request and hasattr(request, "user"):
      user = request.user

    score = 0
    resource_id = validated_data.get("resource")

    combination = Combination(
      user=user,
      gameround=validated_data.get("gameround"),
      resource=validated_data.get("resource"),
      created=datetime.now(),
      score=score
    )
    combination.save()

    tag_data = validated_data.pop('tag_id', None)
    for tag_item in tag_data:
      tag = Tag.objects.get_or_create(**tag_item)[0]
      combination.tag_id.add(tag)

      # if len(combination.tag_id) == 2:
    return combination

Body:
Solved by adding:

      if combination.tag_id.count() == 2:
        return combination


问:
Get the rank of each string extracted from split_string
I have a TABLE with STR DNA DATA the following Table [DYS]

Id
DYS385

3
10-19

4
13-16

5
13-18

6
13-19

7
13-17

8
13-18

9
13-18

10
14-19

11
13-19

12
13-18

I am USING the following script to split the values of [DYS385]

```<code>select top 10 id,[DYS385],t.Value
from dys
OUTER APPLY(select * from string_split([DYS385],'-')) t
where dys385 is not null
</code>```

Output

Id
DYS385
VALUE

3
10-19
10

3
10-19
19

4
13-16
13

4
13-16
16

5
13-18
13

5
13-18
18

6
13-19
13

6
13-19
19

7
13-17
13

7
13-17
17

I want to get for each Value, the Rank
example
10-19 => 10: Rank 1, 19: Rank 2

Desired results:

Id
DYS385
VALUE
RANK

3
10-19
10
1

3
10-19
19
2

4
13-16
13
1

4
13-16
16
2

5
13-18
13
1

5
13-18
18
2

6
13-19
13
1

6
13-19
19
2

7
13-17
13
1

7
13-17
17
2

答:
Given this data:

```<code>CREATE TABLE dbo.Something(Id int, DYS385 varchar(10));

INSERT dbo.Something(Id, DYS385) VALUES (3 , '10-19'),
(4 , '13-16'), (5 , '13-18'), (6 , '13-19'),
(7 , '13-17'), (8 , '13-18'), (9 , '13-18'),
(10, '14-19'), (11, '13-19'), (12, '13-18');
</code>```

Another way to make sure you rank the broken-up strings in the right order could be to use tricks like PARSENAME(), though this can be sensitive to strings lengths and whether a dot is valid within the data:

```<code>SELECT s.Id, s.DYS385, value = v.v, [rank] = ROW_NUMBER() OVER
  (PARTITION BY s.Id ORDER BY c.c DESC)
FROM dbo.Something AS s
CROSS APPLY (VALUES(1),(2)) AS c(c)
CROSS APPLY (VALUES(PARSENAME(REPLACE(s.DYS385,'-','.'),c.c))) AS v(v)
ORDER BY s.Id, [rank];
</code>```

Output:

Id
DYS385
value
rank

3
10-19
10
1

3
10-19
19
2

4
13-16
13
1

4
13-16
16
2

5
13-18
13
1

5
13-18
18
2

6
13-19
13
1

6
13-19
19
2

7
13-17
13
1

7
13-17
17
2

8
13-18
13
1

8
13-18
18
2

9
13-18
13
1

9
13-18
18
2

10
14-19
14
1

10
14-19
19
2

11
13-19
13
1

11
13-19
19
2

12
13-18
13
1

12
13-18
18
2

Example db<>fiddle

Body:
I have a TABLE with STR DNA DATA the following Table [DYS]

Id
DYS385

3
10-19

4
13-16

5
13-18

6
13-19

7
13-17

8
13-18

9
13-18

10
14-19

11
13-19

12
13-18

I am USING the following script to split the values of [DYS385]

select top 10 id,[DYS385],t.Value
from dys
OUTER APPLY(select * from string_split([DYS385],'-')) t
where dys385 is not null

Output

Id
DYS385
VALUE

3
10-19
10

3
10-19
19

4
13-16
13

4
13-16
16

5
13-18
13

5
13-18
18

6
13-19
13

6
13-19
19

7
13-17
13

7
13-17
17

I want to get for each Value, the Rank
example
10-19 => 10: Rank 1, 19: Rank 2

Desired results:

Id
DYS385
VALUE
RANK

3
10-19
10
1

3
10-19
19
2

4
13-16
13
1

4
13-16
16
2

5
13-18
13
1

5
13-18
18
2

6
13-19
13
1

6
13-19
19
2

7
13-17
13
1

7
13-17
17
2

Body:
Given this data:

CREATE TABLE dbo.Something(Id int, DYS385 varchar(10));

INSERT dbo.Something(Id, DYS385) VALUES (3 , '10-19'),
(4 , '13-16'), (5 , '13-18'), (6 , '13-19'),
(7 , '13-17'), (8 , '13-18'), (9 , '13-18'),
(10, '14-19'), (11, '13-19'), (12, '13-18');

Another way to make sure you rank the broken-up strings in the right order could be to use tricks like PARSENAME(), though this can be sensitive to strings lengths and whether a dot is valid within the data:

SELECT s.Id, s.DYS385, value = v.v, [rank] = ROW_NUMBER() OVER
  (PARTITION BY s.Id ORDER BY c.c DESC)
FROM dbo.Something AS s
CROSS APPLY (VALUES(1),(2)) AS c(c)
CROSS APPLY (VALUES(PARSENAME(REPLACE(s.DYS385,'-','.'),c.c))) AS v(v)
ORDER BY s.Id, [rank];

Output:

Id
DYS385
value
rank

3
10-19
10
1

3
10-19
19
2

4
13-16
13
1

4
13-16
16
2

5
13-18
13
1

5
13-18
18
2

6
13-19
13
1

6
13-19
19
2

7
13-17
13
1

7
13-17
17
2

8
13-18
13
1

8
13-18
18
2

9
13-18
13
1

9
13-18
18
2

10
14-19
14
1

10
14-19
19
2

11
13-19
13
1

11
13-19
19
2

12
13-18
13
1

12
13-18
18
2

Example db<>fiddle


问:
How to use asyncio and aioredis lock inside celery tasks?

Goal:

Possibility to run asyncio coroutines.

Correct celery behavior on exceptions and task retries.

Possibility to use aioredis lock.

So, how to run async tasks properly to achieve the goal?

What is RuntimeError: await wasn't used with future (below), how can I fix it?

I have already tried:

1. asgiref

async_to_sync (from asgiref https://pypi.org/project/asgiref/).

This option makes it possible to run asyncio coroutines, but retries functionality doesn't work.

2. celery-pool-asyncio

(https://pypi.org/project/celery-pool-asyncio/)

Same problem as in asgiref. (This option makes it possible to run asyncio coroutines, but retries functionality doesn't work.)

3. write own async to sync decorator

I have performed try to create my own decorator like async_to_sync that runs coroutines threadsafe (asyncio.run_coroutine_threadsafe), but I have behavior as I described above.

4. asyncio module

Also I have try asyncio.run() or asyncio.get_event_loop().run_until_complete() (and self.retry(...)) inside celery task. This works well, tasks runs, retries works, but there is incorrect coroutine execution - inside async function I cannot use aioredis.

Implementation notes:

start celery command: celery -A celery_test.celery_app worker -l info -n worker1 -P gevent --concurrency=10 --without-gossip --without-mingle

celery app:

transport = f"redis://localhost/9"
celery_app = Celery("worker", broker=transport, backend=transport,
                    include=['tasks'])

celery_app.conf.broker_transport_options = {
    'visibility_timeout': 60 * 60 * 24,
    'fanout_prefix': True,
    'fanout_patterns': True
}
```
<ul>
<li><strong>utils</strong>:</li>
</ul>
<pre class="lang-py prettyprint-override"><code>@contextmanager
def temp_asyncio_loop():
    # asyncio.get_event_loop() automatically creates event loop only for main thread
    try:
        prev_loop = asyncio.get_event_loop()
    except RuntimeError:
        prev_loop = None
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    try:
        yield loop
    finally:
        loop.stop()
        loop.close()
        del loop
        asyncio.set_event_loop(prev_loop)

def with_temp_asyncio_loop(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        with temp_asyncio_loop() as t_loop:
            return f(*args, loop=t_loop, **kwargs)

    return wrapper

def await_(coro):
    return asyncio.get_event_loop().run_until_complete(coro)
</code>```

tasks:

@celery_app.task(bind=True, max_retries=30, default_retry_delay=0)
@with_temp_asyncio_loop
def debug(self, **kwargs):
    try:
        await_(debug_async())
    except Exception as exc:
        self.retry(exc=exc)

async def debug_async():
    async with RedisLock(f'redis_lock_{datetime.now()}'):
        pass
```
<ul>
<li><strong>redis lock</strong></li>
</ul>
<pre class="lang-py prettyprint-override"><code>
class RedisLockException(Exception):
    pass

class RedisLock(AsyncContextManager):
    """
    Redis Lock class

    :param lock_id: string (unique key)
    :param value: dummy value
    :param expire: int (time in seconds that key will storing)
    :param expire_on_delete: int (time in seconds, set pause before deleting)

        Usage:
            try:
                with RedisLock('123_lock', 5 * 60):
                    # do something
            except RedisLockException:
    """

    def __init__(self, lock_id: str, value='1', expire: int = 4, expire_on_delete: int = None):
        self.lock_id = lock_id
        self.expire = expire
        self.value = value
        self.expire_on_delete = expire_on_delete

    async def acquire_lock(self):
        return await redis.setnx(self.lock_id, self.value)

    async def release_lock(self):
        if self.expire_on_delete is None:
            return await redis.delete(self.lock_id)
        else:
            await redis.expire(self.lock_id, self.expire_on_delete)

    async def __aenter__(self, *args, **kwargs):
        if not await self.acquire_lock():
            raise RedisLockException({
                'redis_lock': 'The process: {} still run, try again later'.format(await redis.get(self.lock_id))
            })
        await redis.expire(self.lock_id, self.expire)

    async def __aexit__(self, exc_type, exc_value, traceback):
        await self.release_lock()
</code>```

On my windows machine await redis.setnx(...) blocks celery worker and it stops producing logs and Ctrl+C doesn't work.

Inside the docker container, I receive an error. There is part of traceback:

```<code>Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 854, in read_response
    response = await self._parser.read_response()
  File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 366, in read_response
    raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
aioredis.exceptions.ConnectionError: Connection closed by server.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/celery/app/trace.py", line 451, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/celery/app/trace.py", line 734, in __protected_call__
    return self.run(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/celery/app/autoretry.py", line 54, in run
    ret = task.retry(exc=exc, **retry_kwargs)
  File "/usr/local/lib/python3.9/site-packages/celery/app/task.py", line 717, in retry
    raise_with_context(exc)
  File "/usr/local/lib/python3.9/site-packages/celery/app/autoretry.py", line 34, in run
    return task._orig_run(*args, **kwargs)
  File "/app/celery_tasks/tasks.py", line 69, in wrapper
    return f(*args, **kwargs) # <--- inside with_temp_asyncio_loop from utils
  ...
  File "/usr/local/lib/python3.9/contextlib.py", line 575, in enter_async_context
    result = await _cm_type.__aenter__(cm)
  File "/app/db/redis.py", line 50, in __aenter__
    if not await self.acquire_lock():
  File "/app/db/redis.py", line 41, in acquire_lock
    return await redis.setnx(self.lock_id, self.value)
  File "/usr/local/lib/python3.9/site-packages/aioredis/client.py", line 1064, in execute_command
    return await self.parse_response(conn, command_name, **options)
  File "/usr/local/lib/python3.9/site-packages/aioredis/client.py", line 1080, in parse_response
    response = await connection.read_response()
  File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 859, in read_response
    await self.disconnect()
  File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 762, in disconnect
    await self._writer.wait_closed()
  File "/usr/local/lib/python3.9/asyncio/streams.py", line 359, in wait_closed
    await self._protocol._get_close_waiter(self)
RuntimeError: await wasn't used with future
</code>```

library versions:

```<code>celery==5.2.1
aioredis==2.0.0
</code>```

答:
Use solo pool, then create a decorator which run task function
asyncio.get_event_loop().run_until_complete(f(*args, **kwargs)) and make your task asynchronous

```<code>def sync(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        return asyncio.get_event_loop().run_until_complete(f(*args, **kwargs))
    return wrapper

@celery_app.task()
@sync
async def task():
   ...
</code>```

Body:
Goal:

Possibility to run asyncio coroutines.

Correct celery behavior on exceptions and task retries.

Possibility to use aioredis lock.

So, how to run async tasks properly to achieve the goal?

What is RuntimeError: await wasn't used with future (below), how can I fix it?

I have already tried:

1. asgiref

async_to_sync (from asgiref https://pypi.org/project/asgiref/).

This option makes it possible to run asyncio coroutines, but retries functionality doesn't work.

2. celery-pool-asyncio

(https://pypi.org/project/celery-pool-asyncio/)

Same problem as in asgiref. (This option makes it possible to run asyncio coroutines, but retries functionality doesn't work.)

3. write own async to sync decorator

I have performed try to create my own decorator like async_to_sync that runs coroutines threadsafe (asyncio.run_coroutine_threadsafe), but I have behavior as I described above.

4. asyncio module

Also I have try asyncio.run() or asyncio.get_event_loop().run_until_complete() (and self.retry(...)) inside celery task. This works well, tasks runs, retries works, but there is incorrect coroutine execution - inside async function I cannot use aioredis.

Implementation notes:

start celery command: celery -A celery_test.celery_app worker -l info -n worker1 -P gevent --concurrency=10 --without-gossip --without-mingle

celery app:

transport = f"redis://localhost/9"
celery_app = Celery("worker", broker=transport, backend=transport,
                    include=['tasks'])

celery_app.conf.broker_transport_options = {
    'visibility_timeout': 60 * 60 * 24,
    'fanout_prefix': True,
    'fanout_patterns': True
}

utils:

@contextmanager
def temp_asyncio_loop():
    # asyncio.get_event_loop() automatically creates event loop only for main thread
    try:
        prev_loop = asyncio.get_event_loop()
    except RuntimeError:
        prev_loop = None
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    try:
        yield loop
    finally:
        loop.stop()
        loop.close()
        del loop
        asyncio.set_event_loop(prev_loop)

def with_temp_asyncio_loop(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        with temp_asyncio_loop() as t_loop:
            return f(*args, loop=t_loop, **kwargs)

    return wrapper

def await_(coro):
    return asyncio.get_event_loop().run_until_complete(coro)

tasks:

@celery_app.task(bind=True, max_retries=30, default_retry_delay=0)
@with_temp_asyncio_loop
def debug(self, **kwargs):
    try:
        await_(debug_async())
    except Exception as exc:
        self.retry(exc=exc)

async def debug_async():
    async with RedisLock(f'redis_lock_{datetime.now()}'):
        pass

redis lock

class RedisLockException(Exception):
    pass

class RedisLock(AsyncContextManager):
    """
    Redis Lock class

    :param lock_id: string (unique key)
    :param value: dummy value
    :param expire: int (time in seconds that key will storing)
    :param expire_on_delete: int (time in seconds, set pause before deleting)

        Usage:
            try:
                with RedisLock('123_lock', 5 * 60):
                    # do something
            except RedisLockException:
    """

    def __init__(self, lock_id: str, value='1', expire: int = 4, expire_on_delete: int = None):
        self.lock_id = lock_id
        self.expire = expire
        self.value = value
        self.expire_on_delete = expire_on_delete

    async def acquire_lock(self):
        return await redis.setnx(self.lock_id, self.value)

    async def release_lock(self):
        if self.expire_on_delete is None:
            return await redis.delete(self.lock_id)
        else:
            await redis.expire(self.lock_id, self.expire_on_delete)

    async def __aenter__(self, *args, **kwargs):
        if not await self.acquire_lock():
            raise RedisLockException({
                'redis_lock': 'The process: {} still run, try again later'.format(await redis.get(self.lock_id))
            })
        await redis.expire(self.lock_id, self.expire)

    async def __aexit__(self, exc_type, exc_value, traceback):
        await self.release_lock()

On my windows machine await redis.setnx(...) blocks celery worker and it stops producing logs and Ctrl+C doesn't work.

Inside the docker container, I receive an error. There is part of traceback:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 854, in read_response
    response = await self._parser.read_response()
  File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 366, in read_response
    raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
aioredis.exceptions.ConnectionError: Connection closed by server.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/celery/app/trace.py", line 451, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/celery/app/trace.py", line 734, in __protected_call__
    return self.run(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/celery/app/autoretry.py", line 54, in run
    ret = task.retry(exc=exc, **retry_kwargs)
  File "/usr/local/lib/python3.9/site-packages/celery/app/task.py", line 717, in retry
    raise_with_context(exc)
  File "/usr/local/lib/python3.9/site-packages/celery/app/autoretry.py", line 34, in run
    return task._orig_run(*args, **kwargs)
  File "/app/celery_tasks/tasks.py", line 69, in wrapper
    return f(*args, **kwargs) # <--- inside with_temp_asyncio_loop from utils
  ...
  File "/usr/local/lib/python3.9/contextlib.py", line 575, in enter_async_context
    result = await _cm_type.__aenter__(cm)
  File "/app/db/redis.py", line 50, in __aenter__
    if not await self.acquire_lock():
  File "/app/db/redis.py", line 41, in acquire_lock
    return await redis.setnx(self.lock_id, self.value)
  File "/usr/local/lib/python3.9/site-packages/aioredis/client.py", line 1064, in execute_command
    return await self.parse_response(conn, command_name, **options)
  File "/usr/local/lib/python3.9/site-packages/aioredis/client.py", line 1080, in parse_response
    response = await connection.read_response()
  File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 859, in read_response
    await self.disconnect()
  File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 762, in disconnect
    await self._writer.wait_closed()
  File "/usr/local/lib/python3.9/asyncio/streams.py", line 359, in wait_closed
    await self._protocol._get_close_waiter(self)
RuntimeError: await wasn't used with future

library versions:

celery==5.2.1
aioredis==2.0.0

Body:
Use solo pool, then create a decorator which run task function
asyncio.get_event_loop().run_until_complete(f(*args, **kwargs)) and make your task asynchronous

def sync(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        return asyncio.get_event_loop().run_until_complete(f(*args, **kwargs))
    return wrapper

@celery_app.task()
@sync
async def task():
   ...


问:
Why will there be no native properties in Java 7?
Is there any rational reason, why native properties will not be part of Java 7?</p>

答:
Doing properties "right" in Java will not be easy. Rémi Forax's work especially has been valuable in figuring out what this might look like, and uncovering a lot of the "gotchas" that will have to be dealt with.

Meanwhile, Java 7 has already taken too long. The closures debate was a huge, controversial distraction that wasted a lot of mind-power that could have been used to develop features (like properties) that have broad consensus of support. Eventually, the decision was made to limit major changes to modularization (Project Jigsaw). Only "small change" is being considered for the language (under Project Coin).

JavaFX has beautiful property support, so Sun clearly understands the value of properties and knows how to implement them. But having been spoiled by JavaFX properties, developers are less likely to settle for a half-baked implementation in Java. If they are worth doing, they are worth doing right.

OwnerDisplayName: bwalliser

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: erickson

LastEditorDisplayName: erickson


问:
Difference between object reference declaration and object construction?
Consider a class named Calculator with the following code:

```<code>class Calc extends Calculator {

    Calculator calculator;                    // [Style 1]

    Calculator calculator = new Calculator(); // [Style 2]
}
</code>```

To my knowledge, no memory has been allocated in [1], but in statement [2] a new Calculator object is created.

Are there any other differences beyond that?

答:
When you write

```<code>Calculator calculator;
</code>```

It only means that you're declaring a reference to the object of type Calculator. Reference is not an object, so memory is not allocated.

When you write

```<code>new Calculator();
</code>```

It constructs the object of type Calculator and returns a reference to this object.

So, when you write

```<code>Calculator calculator = new Calculator();
</code>```

It means that you construct the object and store a reference to it in calculator.

'calculator' is not an object, it's only a reference to this object. You can have more than 1 reference to the same object.

Update:
Regarding the title of this topic, creating the instance of class and creating the object are absolutely the same. What you mean is, I believe, declaring a reference to object vs declaring it with inplace assignment (though I'm not exactly sure about terms) :-)

Body:
Consider a class named Calculator with the following code:

class Calc extends Calculator {

    Calculator calculator;                    // [Style 1]

    Calculator calculator = new Calculator(); // [Style 2]
}

To my knowledge, no memory has been allocated in [1], but in statement [2] a new Calculator object is created.

Are there any other differences beyond that?

Body:
When you write

Calculator calculator;

It only means that you're declaring a reference to the object of type Calculator. Reference is not an object, so memory is not allocated.

When you write

new Calculator();

It constructs the object of type Calculator and returns a reference to this object.

So, when you write

Calculator calculator = new Calculator();

It means that you construct the object and store a reference to it in calculator.

'calculator' is not an object, it's only a reference to this object. You can have more than 1 reference to the same object.

Update:
Regarding the title of this topic, creating the instance of class and creating the object are absolutely the same. What you mean is, I believe, declaring a reference to object vs declaring it with inplace assignment (though I'm not exactly sure about terms) :-)


问:
AES CBC encryption with PKCS7 padding in Dart (Flutter): pkcs7.dart throws an error when the encrypted text does not require padding
I am trying to encrypt some text with AES CBC encryption with PKCS7 padding in Python and then decrypt it in Dart (Flutter). It turns out package:pointycastle/paddings/pkcs7.dart throws an error when the encrypted text does not require padding.

Here is the example. Here we encode some text that requires padding in Python.

```<code>import base64
import hashlib
from Crypto.Cipher import AES
from pkcs7 import PKCS7Encoder

secret_text = 'Text that requires padding'

key_text = "some_key"
key = hashlib.sha256(key_text.encode()).digest()
print('key: ', list(key))

iv = hashlib.md5("some_iv_text".encode('utf-8')).digest()
print('iv: ', list(iv))

encoder = PKCS7Encoder()
padded_text = encoder.encode(secret_text)
print('Padded text: ', padded_text.encode('utf-8'))

e = AES.new(key, AES.MODE_CBC, iv)
cipher_text = e.encrypt(padded_text.encode('utf-8'))

print(base64.b64encode(cipher_text).decode('utf-8'))
</code>```

Output:

```<code>key:  [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
iv:  [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]
Padded text:  b'Text that requires padding\x06\x06\x06\x06\x06\x06'
PygLEjc1Kkjm5qtt5N9vHC0E7TAYVj4xLpsfa4cLiRs=

Process finished with exit code 0
</code>```

Next, we decrypt it in Dart.

```<code>import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';

void main() {
  String encryptedText = 'PygLEjc1Kkjm5qtt5N9vHC0E7TAYVj4xLpsfa4cLiRs=';

  List<int> key_text = utf8.encode("some_key"); // data being hashed
  List<int> key_bytes = sha256.convert(key_text).bytes;

  final key = Key(Uint8List.fromList(key_bytes));

  print('key: $key_bytes');

  Encrypter encrypter =
      Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));

  String iv_text = 'some_iv_text';

  Uint8List encrypted = Uint8List.fromList(base64.decode(encryptedText));

  final iv_bytes = md5.convert(utf8.encode(iv_text)).bytes;
  IV iv = IV(Uint8List.fromList(iv_bytes));

  print('iv: $iv_bytes');

  String decrypted = encrypter.decrypt(Encrypted(encrypted), iv: iv);
  print(decrypted);
}
</code>```

Output:

```<code>key: [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
iv: [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]
Text that requires padding

Process finished with exit code 0
</code>```

So, everything works well.

Let us do the same with the text that does not require padding.

```<code>import base64
import hashlib
from Crypto.Cipher import AES
from pkcs7 import PKCS7Encoder

secret_text = 'Text that does not require padding..............'

key_text = "some_key"
key = hashlib.sha256(key_text.encode()).digest()
print('key: ', list(key))

iv = hashlib.md5("some_iv_text".encode('utf-8')).digest()
print('iv: ', list(iv))

encoder = PKCS7Encoder()
padded_text = encoder.encode(secret_text)
print('Padded text: ', padded_text.encode('utf-8'))

e = AES.new(key, AES.MODE_CBC, iv)
cipher_text = e.encrypt(padded_text.encode('utf-8'))

print(base64.b64encode(cipher_text).decode('utf-8'))
</code>```

Output:

```<code>key:  [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
iv:  [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]
Padded text:  b'Text that does not require padding..............'
W2Drr/UfPBTNG4fVPG0Lb/Ax3GAyvjNNx9BlrJcxc2RTNcf2BxT2lyIx1l2ktOYl

Process finished with exit code 0
</code>```

Decrypting in Dart with the same code:

```<code>import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';

void main() {
  String encryptedText = 'W2Drr/UfPBTNG4fVPG0Lb/Ax3GAyvjNNx9BlrJcxc2RTNcf2BxT2lyIx1l2ktOYl';

  List<int> key_text = utf8.encode("some_key"); // data being hashed
  List<int> key_bytes = sha256.convert(key_text).bytes;

  final key = Key(Uint8List.fromList(key_bytes));

  print('key: $key_bytes');

  Encrypter encrypter =
      Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));

  String iv_text = 'some_iv_text';

  Uint8List encrypted = Uint8List.fromList(base64.decode(encryptedText));

  final iv_bytes = md5.convert(utf8.encode(iv_text)).bytes;
  IV iv = IV(Uint8List.fromList(iv_bytes));

  print('iv: $iv_bytes');

  String decrypted = encrypter.decrypt(Encrypted(encrypted), iv: iv);
  print(decrypted);
}
</code>```

Output:

```<code>key: [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
Unhandled exception:
Invalid argument(s): Invalid or corrupted pad block
#0      PKCS7Padding.padCount (package:pointycastle/paddings/pkcs7.dart:42:7)
#1      PaddedBlockCipherImpl.doFinal (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:112:30)
#2      PaddedBlockCipherImpl.process (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:74:25)
#3      AES.decrypt (package:encrypt/src/algorithms/aes.dart:63:22)
#4      Encrypter.decryptBytes (package:encrypt/src/encrypter.dart:25:17)
#5      Encrypter.decrypt (package:encrypt/src/encrypter.dart:31:17)
#6      main (package:zno_ua_mova/decypher_bug_reproduce.dart:28:32)
#7      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#8      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
iv: [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]

Process finished with exit code 255
</code>```

It turns out the exception is thrown by this code block in package:pointycastle/paddings/pkcs7.dart:42:7

```<code>if (count > data.length || count == 0) {
  throw ArgumentError('Invalid or corrupted pad block');
}
</code>```

When decryption works (first scenario), the variables are:

```<code>count: 6
data.length: 16
</code>```

When decryption does not work (second scenario), the variables are:

```<code>key:  [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
iv:  [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]
Padded text:  b'Text that requires padding\x06\x06\x06\x06\x06\x06'
PygLEjc1Kkjm5qtt5N9vHC0E7TAYVj4xLpsfa4cLiRs=

Process finished with exit code 0
</code>```0

Is there anything wrong with the pointycastle pkcs7 lib, or am I using it in the wrong way?

答: Ok, the problem turned out to be in the Python pkcs7 library. Its implementation does not follow the PKCS7 RFC and does not add the padding byte to the strings when its length mod blocksize equals zero. The Github issue is already there.</p>

Body:
I am trying to encrypt some text with AES CBC encryption with PKCS7 padding in Python and then decrypt it in Dart (Flutter). It turns out package:pointycastle/paddings/pkcs7.dart throws an error when the encrypted text does not require padding.

Here is the example. Here we encode some text that requires padding in Python.

import base64
import hashlib
from Crypto.Cipher import AES
from pkcs7 import PKCS7Encoder

secret_text = 'Text that requires padding'

key_text = "some_key"
key = hashlib.sha256(key_text.encode()).digest()
print('key: ', list(key))

iv = hashlib.md5("some_iv_text".encode('utf-8')).digest()
print('iv: ', list(iv))

encoder = PKCS7Encoder()
padded_text = encoder.encode(secret_text)
print('Padded text: ', padded_text.encode('utf-8'))

e = AES.new(key, AES.MODE_CBC, iv)
cipher_text = e.encrypt(padded_text.encode('utf-8'))

print(base64.b64encode(cipher_text).decode('utf-8'))

Output:

key:  [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
iv:  [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]
Padded text:  b'Text that requires padding\x06\x06\x06\x06\x06\x06'
PygLEjc1Kkjm5qtt5N9vHC0E7TAYVj4xLpsfa4cLiRs=

Process finished with exit code 0

Next, we decrypt it in Dart.

import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';

void main() {
  String encryptedText = 'PygLEjc1Kkjm5qtt5N9vHC0E7TAYVj4xLpsfa4cLiRs=';

  List<int> key_text = utf8.encode("some_key"); // data being hashed
  List<int> key_bytes = sha256.convert(key_text).bytes;

  final key = Key(Uint8List.fromList(key_bytes));

  print('key: $key_bytes');

  Encrypter encrypter =
      Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));

  String iv_text = 'some_iv_text';

  Uint8List encrypted = Uint8List.fromList(base64.decode(encryptedText));

  final iv_bytes = md5.convert(utf8.encode(iv_text)).bytes;
  IV iv = IV(Uint8List.fromList(iv_bytes));

  print('iv: $iv_bytes');

  String decrypted = encrypter.decrypt(Encrypted(encrypted), iv: iv);
  print(decrypted);
}

Output:

key: [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
iv: [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]
Text that requires padding

Process finished with exit code 0

So, everything works well.

Let us do the same with the text that does not require padding.

import base64
import hashlib
from Crypto.Cipher import AES
from pkcs7 import PKCS7Encoder

secret_text = 'Text that does not require padding..............'

key_text = "some_key"
key = hashlib.sha256(key_text.encode()).digest()
print('key: ', list(key))

iv = hashlib.md5("some_iv_text".encode('utf-8')).digest()
print('iv: ', list(iv))

encoder = PKCS7Encoder()
padded_text = encoder.encode(secret_text)
print('Padded text: ', padded_text.encode('utf-8'))

e = AES.new(key, AES.MODE_CBC, iv)
cipher_text = e.encrypt(padded_text.encode('utf-8'))

print(base64.b64encode(cipher_text).decode('utf-8'))

Output:

key:  [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
iv:  [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]
Padded text:  b'Text that does not require padding..............'
W2Drr/UfPBTNG4fVPG0Lb/Ax3GAyvjNNx9BlrJcxc2RTNcf2BxT2lyIx1l2ktOYl

Process finished with exit code 0

Decrypting in Dart with the same code:

import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';

void main() {
  String encryptedText = 'W2Drr/UfPBTNG4fVPG0Lb/Ax3GAyvjNNx9BlrJcxc2RTNcf2BxT2lyIx1l2ktOYl';

  List<int> key_text = utf8.encode("some_key"); // data being hashed
  List<int> key_bytes = sha256.convert(key_text).bytes;

  final key = Key(Uint8List.fromList(key_bytes));

  print('key: $key_bytes');

  Encrypter encrypter =
      Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));

  String iv_text = 'some_iv_text';

  Uint8List encrypted = Uint8List.fromList(base64.decode(encryptedText));

  final iv_bytes = md5.convert(utf8.encode(iv_text)).bytes;
  IV iv = IV(Uint8List.fromList(iv_bytes));

  print('iv: $iv_bytes');

  String decrypted = encrypter.decrypt(Encrypted(encrypted), iv: iv);
  print(decrypted);
}

Output:

key: [149, 37, 31, 220, 159, 221, 63, 146, 231, 174, 209, 65, 254, 127, 208, 107, 42, 235, 157, 237, 182, 247, 172, 8, 231, 217, 186, 188, 126, 137, 139, 73]
Unhandled exception:
Invalid argument(s): Invalid or corrupted pad block
#0      PKCS7Padding.padCount (package:pointycastle/paddings/pkcs7.dart:42:7)
#1      PaddedBlockCipherImpl.doFinal (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:112:30)
#2      PaddedBlockCipherImpl.process (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:74:25)
#3      AES.decrypt (package:encrypt/src/algorithms/aes.dart:63:22)
#4      Encrypter.decryptBytes (package:encrypt/src/encrypter.dart:25:17)
#5      Encrypter.decrypt (package:encrypt/src/encrypter.dart:31:17)
#6      main (package:zno_ua_mova/decypher_bug_reproduce.dart:28:32)
#7      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#8      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
iv: [205, 35, 149, 118, 23, 255, 66, 222, 206, 81, 138, 188, 169, 122, 96, 164]

Process finished with exit code 255

It turns out the exception is thrown by this code block in package:pointycastle/paddings/pkcs7.dart:42:7

if (count > data.length || count == 0) {
  throw ArgumentError('Invalid or corrupted pad block');
}

When decryption works (first scenario), the variables are:

count: 6
data.length: 16

When decryption does not work (second scenario), the variables are:

count: 46
data.length: 16

Is there anything wrong with the pointycastle pkcs7 lib, or am I using it in the wrong way?


问:
Jooq batch insert/delete returning number of rows affected?
I am trying to batch insert and batch delete a large list of objects using JOOQ and Postgres, and get the number of rows inserted/deleted. I see there are insert(Collection
 objects) and delete(Collection
 objects) provided in JOOQ, however they don't return anything. From searching online I see there's also batchStore that might return the number of inserted rows, which I am going to try. But what about delete?

Thanks!

答:
I'm assuming that you meant these methods that don't return anything?

DAO.insert(Collection
 objects)

DAO.delete(Collection
 objects)

And by batchStore you mean DSLContext.batchStore(). So, would your answer just be to use DSLContext.batchDelete()?

Body:
I'm assuming that you meant these methods that don't return anything?

DAO.insert(Collection<P> objects)

DAO.delete(Collection<P> objects)

And by batchStore you mean DSLContext.batchStore(). So, would your answer just be to use DSLContext.batchDelete()?


问:
how we can make a word refer to something like a section or a picture in latex?
how we can make a word refer to something like a section or a picture in latex?
I know how to refer to something by \ref{} but when we use this we see the number of the section or table or picture or ... but I wanna something like \href{}{} to make a word refer to some element like section, table, picture.</p>

答:
You can use an \hyperlink:

```<code>\documentclass{article}

\usepackage{hyperref}

\begin{document}

\section{title}
\label{test}

\newpage

\hyperlink{test}{link text}

\end{document}
</code>```

Body:
You can use an \hyperlink:

\documentclass{article}

\usepackage{hyperref}

\begin{document}

\section{title}
\label{test}

\newpage

\hyperlink{test}{link text}

\end{document}