问:
Scrapy custom DownloadMiddleware does not respect DOWNLOAD_DELAY
I am currently working on my CustomDownloadMiddleware. This is mainly due to a certain need for control over downloading the webpage. My CustomDownloadMiddleware looks something as below

class MySeleniumDownloadMiddleware:
    """Scrapy middleware handling the requests using selenium"""

    def __init__(self, driver):
        self.driver = driver
        self.cookies = self.driver.get_cookies()

    @classmethod
    def from_crawler(cls, crawler):
        """Initialize the middleware with the crawler settings"""

        driver = init_chromium(crawler.settings.get('SELENIUM_HOSTNAME'))
        login(driver, crawler.settings.get('MY_CREDENTIAL'))

        middleware = cls(driver=driver)

        crawler.signals.connect(middleware.spider_closed, signals.spider_closed)

        return middleware

    def process_request(self, request, spider):
        """Process a request using the selenium driver if applicable"""

        try:
            self.driver.get(request.url)
        except WebDriverException:
            self.driver = init_chromium(spider.settings.get('SELENIUM_HOSTNAME'))
            recover_cookie_to_driver(self.driver, self.cookies)
            self.driver.get(request.url)

        body = str.encode(self.driver.page_source)

        # Expose the driver via the "meta" attribute
        request.meta.update({'driver': self.driver})

        return HtmlResponse(
            self.driver.current_url,
            body=body,
            encoding='utf-8',
            request=request
        )

    def spider_closed(self):
        """Shutdown the driver when spider is closed"""
        try:
            self.driver.quit()
        except WebDriverException:
            pass
```

After opening an issue in github, I had found that the issue is that custom download middleware are required to handle the download delay by itself, and the recommendation are by using slot that can be found in this file. However, I had fail to find any relevant example of the slot being used in the download middleware.

Also, it is worth to mention that my code are heavily inspired by scrapy-selenium, and had found an issue which provide a potential solution for download delay, however when I use time.sleep(second) solution, the pipeline and spider's parse function are not being processed concurrently, which I deem the solution not viable.

Is there a proper way of implementing slot into download middleware so it respect download delay, as well as it will not hinder the ability of both pipeline and scraping being processed concurrently? If yes, what is it?

答:
I think I found reason of this behaviour.

It looks like your request don't reach downloader methods where downloader related settings used (including DOWNLOAD_DELAY).

In general case (according to scrapy achitecture) this things happens:

Downloader middlewares process_request modify request and - send request to Downloader.

Downloader:
 assign request to downloader slot
executing request from step 4. (counting downloader related settings).
Received response - > sending to process_response methods  (step 5 of scrapy achitecture scheme)

Downloader middlewares process_request - modify response and - send response to engine.

Your in your case behaviour will be different:

Downloader middlewares process_request send Httpresponse object to Downloader (not request)
 as result of process_request method of your middleware.

Downloader:
 will not execute request - because it already received response from previous step.
It will immediately send response to process_response methdos.

5.(the same as above) Downloader middlewares process_request - modify response and - send response to engine.

This behaviour coded in:

DownloaderMiddlewareManager download method.

Downloader fetch method (where DownloaderMiddlewareManager.download called)

On current implementation of scrapy downloader - DOWNLOAD_DELAY and some other downloader related settings will work only for non selenium requests.

Body:
I am currently working on my CustomDownloadMiddleware. This is mainly due to a certain need for control over downloading the webpage. My CustomDownloadMiddleware looks something as below

class MySeleniumDownloadMiddleware:
    """Scrapy middleware handling the requests using selenium"""

    def __init__(self, driver):
        self.driver = driver
        self.cookies = self.driver.get_cookies()

    @classmethod
    def from_crawler(cls, crawler):
        """Initialize the middleware with the crawler settings"""

        driver = init_chromium(crawler.settings.get('SELENIUM_HOSTNAME'))
        login(driver, crawler.settings.get('MY_CREDENTIAL'))

        middleware = cls(driver=driver)

        crawler.signals.connect(middleware.spider_closed, signals.spider_closed)

        return middleware

    def process_request(self, request, spider):
        """Process a request using the selenium driver if applicable"""

        try:
            self.driver.get(request.url)
        except WebDriverException:
            self.driver = init_chromium(spider.settings.get('SELENIUM_HOSTNAME'))
            recover_cookie_to_driver(self.driver, self.cookies)
            self.driver.get(request.url)

        body = str.encode(self.driver.page_source)

        # Expose the driver via the "meta" attribute
        request.meta.update({'driver': self.driver})

        return HtmlResponse(
            self.driver.current_url,
            body=body,
            encoding='utf-8',
            request=request
        )

    def spider_closed(self):
        """Shutdown the driver when spider is closed"""
        try:
            self.driver.quit()
        except WebDriverException:
            pass

After opening an issue in github, I had found that the issue is that custom download middleware are required to handle the download delay by itself, and the recommendation are by using slot that can be found in this file. However, I had fail to find any relevant example of the slot being used in the download middleware.

Also, it is worth to mention that my code are heavily inspired by scrapy-selenium, and had found an issue which provide a potential solution for download delay, however when I use time.sleep(second) solution, the pipeline and spider's parse function are not being processed concurrently, which I deem the solution not viable.

Is there a proper way of implementing slot into download middleware so it respect download delay, as well as it will not hinder the ability of both pipeline and scraping being processed concurrently? If yes, what is it?


来源: stackexchange

问:
Sorting a vector with pointer at object C++
If anyone can help I would be very grateful.
How do i sort this vector:

vector<Person*>person

by this criterium:

Surname

I have already tried it using set but it removes object if there is more than 2 objects with same Surname

there are lot of string variables, and I need to sort it by

Surname

and then if surnames are the same, then I need to sort them by

Name

and also it sorts by hexadecimal value of that pointer...
EDIT:
More code as you ask:

```<code>for (pChild = pRoot->FirstChildElement("Member"); pChild != NULL; pChild = pChild->NextSiblingElement())
    {
        string Surname = pChild->Attribute("surname");
        string Name = pChild->Attribute("name");
        string DateOfBirth = pChild->Attribute("dateofbirth");
        person.push_back(new Person(Surname, Name, DateOfBirth));
    }
</code>```

答:
You can use a comparator like this:</p>

```<code>// Simple class
class Person {
    public:
     string name;
    Person(string name) {
      this->name = name;
    }
};

// create a comparator like this with two objects as parameters.
bool comparator(Person* a, Person *b) {
  return a->name > b->name;
}

int main() {
  vector<Person* > v;
  v.push_back(new Person("ajay"));
  v.push_back(new Person("tanya"));

  // pass the comparator created into sort function.
  sort(v.begin(), v.end(),comparator);

  // printing output to check
  for(int i=0;i<v.size();i++) {
    cout<<v[i]->name<<endl;
  }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
If anyone can help I would be very grateful.
How do i sort this vector:

vector<Person*>person

by this criterium:

Surname

I have already tried it using set but it removes object if there is more than 2 objects with same Surname

there are lot of string variables, and I need to sort it by

Surname

and then if surnames are the same, then I need to sort them by

Name

and also it sorts by hexadecimal value of that pointer...
EDIT:
More code as you ask:

for (pChild = pRoot->FirstChildElement("Member"); pChild != NULL; pChild = pChild->NextSiblingElement())
    {
        string Surname = pChild->Attribute("surname");
        string Name = pChild->Attribute("name");
        string DateOfBirth = pChild->Attribute("dateofbirth");
        person.push_back(new Person(Surname, Name, DateOfBirth));
    }

Body:
You can use a comparator like this:

// Simple class
class Person {
    public:
     string name;
    Person(string name) {
      this->name = name;
    }
};

// create a comparator like this with two objects as parameters.
bool comparator(Person* a, Person *b) {
  return a->name > b->name;
}

int main() {
  vector<Person* > v;
  v.push_back(new Person("ajay"));
  v.push_back(new Person("tanya"));

  // pass the comparator created into sort function.
  sort(v.begin(), v.end(),comparator);

  // printing output to check
  for(int i=0;i<v.size();i++) {
    cout<<v[i]->name<<endl;
  }
}


问:
How do I add a button on right side of the toolbar in a UISplitViewController?
Trying to add a button to the right side of the toolbar of the detailviewcontroller in a split-view based app. I used flexible space to get it to the right side. In portrait it works fine, but in landscape (when the menu button disappears), the button gets moved so that half of it is off the screen.

Here's the relevant code (in DetailViewController.m):

```<code>- (void) viewDidLoad
{
    // initialize toolbar
    toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake( 0, 0, 768, 44 )];
    titleLabel = [[UILabel alloc] initWithFrame: CGRectMake( 284, 3, 200, 35 )];
    titleLabel.text = @"Title & Location";
    titleLabel.textAlignment = UITextAlignmentCenter;
    [toolbar addSubview: titleLabel];
    UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target: nil action: nil];
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle: @"Add Event" style: UIBarButtonItemStyleDone target: rootController action: @selector(parseDone)];
    NSArray *buttonArray = [NSArray arrayWithObjects: flexibleSpace, doneButton, nil];
    [toolbar setItems: buttonArray];
    [doneButton release];
    [flexibleSpace release];
    [self.view addSubview: toolbar];
}
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem
{
    NSMutableArray *itemsArray = [toolbar.items mutableCopy];
    [itemsArray insertObject: barButtonItem atIndex: 0];
    [toolbar setItems:itemsArray animated:NO];
}
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem
{
    NSMutableArray *itemsArray = [toolbar.items mutableCopy];
    [itemsArray removeObject:barButtonItem];
    [toolbar setItems:itemsArray animated:NO];
    [itemsArray release];
}
</code>```

答: In fact, if you put your view controller in a UINavigationController you get the UINavigationBar and all the functionality of the navigation controller, if you choose to use it.</p>

ContentLicense: CC BY-SA 3.0

Body:
Trying to add a button to the right side of the toolbar of the detailviewcontroller in a split-view based app. I used flexible space to get it to the right side. In portrait it works fine, but in landscape (when the menu button disappears), the button gets moved so that half of it is off the screen.

Here's the relevant code (in DetailViewController.m):

- (void) viewDidLoad
{
    // initialize toolbar
    toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake( 0, 0, 768, 44 )];
    titleLabel = [[UILabel alloc] initWithFrame: CGRectMake( 284, 3, 200, 35 )];
    titleLabel.text = @"Title & Location";
    titleLabel.textAlignment = UITextAlignmentCenter;
    [toolbar addSubview: titleLabel];
    UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target: nil action: nil];
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle: @"Add Event" style: UIBarButtonItemStyleDone target: rootController action: @selector(parseDone)];
    NSArray *buttonArray = [NSArray arrayWithObjects: flexibleSpace, doneButton, nil];
    [toolbar setItems: buttonArray];
    [doneButton release];
    [flexibleSpace release];
    [self.view addSubview: toolbar];
}
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem
{
    NSMutableArray *itemsArray = [toolbar.items mutableCopy];
    [itemsArray insertObject: barButtonItem atIndex: 0];
    [toolbar setItems:itemsArray animated:NO];
}
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem
{
    NSMutableArray *itemsArray = [toolbar.items mutableCopy];
    [itemsArray removeObject:barButtonItem];
    [toolbar setItems:itemsArray animated:NO];
    [itemsArray release];
}


问:
Python generic with union
I have a Document and Page types, both containing data and metadata parts. They are looking the same:

```<code>class Document:
    __data: DocumentData
    __meta: DocumentMeta

    def __init__(self, part: Union[DocumentData, DocumentMeta, None] = None, data: Optional[DocumentData] = None,
             meta: Optional[DocumentMeta] = None):
        super().__init__()
        self.data: Optional[DocumentData] = data
        self.meta: Optional[DocumentMeta] = meta

        if part is not None:
            if type(part) == DocumentData:
                data = part
                meta = DocumentMeta()
            elif type(part) == DocumentMeta:
                meta = part
                data = DocumentData()

class Page:
    __data: PageData
    __meta: PageMeta

    def __init__(self, part: Union[PageData, PageMeta, None] = None, data: Optional[PageData] = None,
             meta: Optional[PageMeta] = None):
        super().__init__()
        self.data: Optional[PageData] = data
        self.meta: Optional[PageMeta] = meta

        if part is not None:
            if type(part) == PageData:
                data = part
                meta = PageMeta()
            elif type(part) == PageMeta:
                meta = part
                data = PageData()
</code>```

I would like now to refactor these 2 types to use a generic type. I did it that way:

```<code>from typing import Generic, Optional, TypeVar, Union

DataStruct = TypeVar('DataStruct')
MetaStruct = TypeVar('MetaStruct')

class MetaDataStruct(Generic[DataStruct, MetaStruct]):
    __data: DataStruct
    __meta: MetaStruct

    def __init__(
        self,
        part: Union[DataStruct, MetaStruct, None] = None,
        data: Optional[DataStruct] = None,
        meta: Optional[MetaStruct] = None
    ):
        super().__init__()
        self.data: Optional[DataStruct] = data
        self.meta: Optional[MetaStruct] = meta

        if part is not None:
            if type(part) == DataStruct:
                data = part
                meta = MetaStruct()
            elif type(part) == MetaStruct:
                meta = part
                data = DataStruct()

class DocumentData:
    pass

class DocumentMeta:
    pass

class PageData:
    pass

class PageMeta:
    pass

class Document(MetaDataStruct[DocumentData, DocumentMeta]):
    pass

class Page(MetaDataStruct[PageData, PageMeta]):
    pass
</code>```

Now there's few problems with type checking.

if type(part) == DataStruct: returns False all the time. In runtime a type(part) is one of: DocumentData, DocumentMeta, PageData, PageMeta. I understand that I have to compare type(part) with actual type of DataStruct. What is the right way to resolve the runtime type of DataStruct?

In python hints manual it's written: At runtime, isinstance(x, T) will raise TypeError. In general, isinstance() and issubclass() should not be used with types. I believe the same issue is here.

I can use type(self).orig_bases[0].args[0] to infer DataStruct, but it is conceptually incorrect. It will retrieve the first generic argument instead DataStruct. So, if a MetaDataStruct base class signature will change to class MergedStruct(Struct, Generic[MetaStruct, DataStruct]) (swapped TypeVar arguments), MetaStruct will be retrieved instead DataStruct.

For some reason, when I tried to intialize Document(part=1), it passed. In practice I expected the code to raise TypeError.

答:
Temporarily, I used this solution:</p>

```<code>actual_data_struct = getattr(type(self), '__orig_bases__')[0].__args__[0]
actual_meta_struct = getattr(type(self), '__orig_bases__')[0].__args__[1]

if part is not None:
    if type(part) == actual_data_struct:
        data = part
        meta = actual_meta_struct()
    elif type(part) == actual_meta_struct:
        meta = part
        data = actual_data_struct()
</code>```

Title: Python generic with union

Body:
I have a Document and Page types, both containing data and metadata parts. They are looking the same:

class Document:
    __data: DocumentData
    __meta: DocumentMeta

    def __init__(self, part: Union[DocumentData, DocumentMeta, None] = None, data: Optional[DocumentData] = None,
             meta: Optional[DocumentMeta] = None):
        super().__init__()
        self.data: Optional[DocumentData] = data
        self.meta: Optional[DocumentMeta] = meta

        if part is not None:
            if type(part) == DocumentData:
                data = part
                meta = DocumentMeta()
            elif type(part) == DocumentMeta:
                meta = part
                data = DocumentData()

class Page:
    __data: PageData
    __meta: PageMeta

    def __init__(self, part: Union[PageData, PageMeta, None] = None, data: Optional[PageData] = None,
             meta: Optional[PageMeta] = None):
        super().__init__()
        self.data: Optional[PageData] = data
        self.meta: Optional[PageMeta] = meta

        if part is not None:
            if type(part) == PageData:
                data = part
                meta = PageMeta()
            elif type(part) == PageMeta:
                meta = part
                data = PageData()

I would like now to refactor these 2 types to use a generic type. I did it that way:

from typing import Generic, Optional, TypeVar, Union

DataStruct = TypeVar('DataStruct')
MetaStruct = TypeVar('MetaStruct')

class MetaDataStruct(Generic[DataStruct, MetaStruct]):
    __data: DataStruct
    __meta: MetaStruct

    def __init__(
        self,
        part: Union[DataStruct, MetaStruct, None] = None,
        data: Optional[DataStruct] = None,
        meta: Optional[MetaStruct] = None
    ):
        super().__init__()
        self.data: Optional[DataStruct] = data
        self.meta: Optional[MetaStruct] = meta

        if part is not None:
            if type(part) == DataStruct:
                data = part
                meta = MetaStruct()
            elif type(part) == MetaStruct:
                meta = part
                data = DataStruct()

class DocumentData:
    pass

class DocumentMeta:
    pass

class PageData:
    pass

class PageMeta:
    pass

class Document(MetaDataStruct[DocumentData, DocumentMeta]):
    pass

class Page(MetaDataStruct[PageData, PageMeta]):
    pass

Now there's few problems with type checking.

if type(part) == DataStruct: returns False all the time. In runtime a type(part) is one of: DocumentData, DocumentMeta, PageData, PageMeta. I understand that I have to compare type(part) with actual type of DataStruct. What is the right way to resolve the runtime type of DataStruct?

In python hints manual it's written: At runtime, isinstance(x, T) will raise TypeError. In general, isinstance() and issubclass() should not be used with types. I believe the same issue is here.

I can use type(self).orig_bases[0].args[0] to infer DataStruct, but it is conceptually incorrect. It will retrieve the first generic argument instead DataStruct. So, if a MetaDataStruct base class signature will change to class MergedStruct(Struct, Generic[MetaStruct, DataStruct]) (swapped TypeVar arguments), MetaStruct will be retrieved instead DataStruct.

For some reason, when I tried to intialize Document(part=1), it passed. In practice I expected the code to raise TypeError.

Body:
Temporarily, I used this solution:

actual_data_struct = getattr(type(self), '__orig_bases__')[0].__args__[0]
actual_meta_struct = getattr(type(self), '__orig_bases__')[0].__args__[1]

if part is not None:
    if type(part) == actual_data_struct:
        data = part
        meta = actual_meta_struct()
    elif type(part) == actual_meta_struct:
        meta = part
        data = actual_data_struct()


问:
Why does pandas value_counts() show a count of zero for some values?
I have a dataframe where one column is a categorical variable with the following labels: ['Short', 'Medium', 'Long', 'Very Long', 'Extremely Long'].  I am trying to create a new dataframe that drops all the rows that are Extremely Long.

I have tried doing this in the following ways:

```<code>df2 = df.query('ride_type != "Extremely Long"')
df2 = df[df['ride_type'] != 'Extremely Long']
</code>```

However, when I run .value_counts() I get the following:

```<code>df2.ride_type.value_counts()
>>> Short             130474
Long              129701
Medium            129607
Very Long         110988
Extremely Long         0
Name: ride_type, dtype: int64
</code>```

In other words, Extremely Long is still there, so I can't plot charts with just the four categories I want.

答:
This is a feature of categorical data. You may have something that looks like this:

```<code>df = pd.DataFrame({'ride_type': pd.Categorical(
    ['Long', 'Long'], categories=['Long', 'Short'])})

df
  ride_type
0      Long
1      Long
</code>```

Calling value_counts on a categorical column will record counts for all categories, not just the ones present.

```<code>df['ride_type'].value_counts()

Long     2
Short    0
Name: ride_type, dtype: int64
</code>```

The solution is to either remove unused categories, or convert to string:

```<code>df['ride_type'].cat.remove_unused_categories().value_counts()

Long    2
Name: ride_type, dtype: int64

# or,
df['ride_type'].astype(str).value_counts()

Long    2
Name: ride_type, dtype: int64
</code>```

Body:
I have a dataframe where one column is a categorical variable with the following labels: ['Short', 'Medium', 'Long', 'Very Long', 'Extremely Long'].  I am trying to create a new dataframe that drops all the rows that are Extremely Long.

I have tried doing this in the following ways:

df2 = df.query('ride_type != "Extremely Long"')
df2 = df[df['ride_type'] != 'Extremely Long']

However, when I run .value_counts() I get the following:

df2.ride_type.value_counts()
>>> Short             130474
Long              129701
Medium            129607
Very Long         110988
Extremely Long         0
Name: ride_type, dtype: int64

In other words, Extremely Long is still there, so I can't plot charts with just the four categories I want.

Body:
This is a feature of categorical data. You may have something that looks like this:

df = pd.DataFrame({'ride_type': pd.Categorical(
    ['Long', 'Long'], categories=['Long', 'Short'])})

df
  ride_type
0      Long
1      Long

Calling value_counts on a categorical column will record counts for all categories, not just the ones present.

df['ride_type'].value_counts()

Long     2
Short    0
Name: ride_type, dtype: int64

The solution is to either remove unused categories, or convert to string:

df['ride_type'].cat.remove_unused_categories().value_counts()

Long    2
Name: ride_type, dtype: int64

# or,
df['ride_type'].astype(str).value_counts()

Long    2
Name: ride_type, dtype: int64


问:
how to make a gradient border of UIView?
I want to make a gradient border of view like the following picture:

but I don't know how do it exactly , i.e. what the gradient color I should use to do it? how to set my view to show a border like the image?

I'm using the following code to get a border:

```<code> self.view.layer.borderColor = [UIColor orangeColor].CGColor;
 self.view.layer.borderWidth = 2.0f;
</code>```

答:
Thanx Tiago Mendes for answer.

I improved functionality:

added corner radius.

And fixed some issues to ensure correct masking and given border width:

improved gradient layer frame;

improved mask path rounding rect.

Swift 5

```<code>public extension UIView {
    private static let kLayerNameGradientBorder = "GradientBorderLayer"

    func gradientBorder(
        width: CGFloat,
        colors: [UIColor],
        startPoint: CGPoint = .init(x: 0.5, y: 0),
        endPoint: CGPoint = .init(x: 0.5, y: 1),
        andRoundCornersWithRadius cornerRadius: CGFloat = 0
    ) {
        let existingBorder = gradientBorderLayer()
        let border = existingBorder ?? .init()
        border.frame = CGRect(
            x: bounds.origin.x,
            y: bounds.origin.y,
            width: bounds.size.width + width,
            height: bounds.size.height + width
        )
        border.colors = colors.map { $0.cgColor }
        border.startPoint = startPoint
        border.endPoint = endPoint

        let mask = CAShapeLayer()
        let maskRect = CGRect(
            x: bounds.origin.x + width/2,
            y: bounds.origin.y + width/2,
            width: bounds.size.width - width,
            height: bounds.size.height - width
        )
        mask.path = UIBezierPath(
            roundedRect: maskRect,
            cornerRadius: cornerRadius
        ).cgPath
        mask.fillColor = UIColor.clear.cgColor
        mask.strokeColor = UIColor.white.cgColor
        mask.lineWidth = width

        border.mask = mask

        let isAlreadyAdded = (existingBorder != nil)
        if !isAlreadyAdded {
            layer.addSublayer(border)
        }
    }

    private func gradientBorderLayer() -> CAGradientLayer? {
        let borderLayers = layer.sublayers?.filter {
            $0.name == UIView.kLayerNameGradientBorder
        }
        if borderLayers?.count ?? 0 > 1 {
            fatalError()
        }
        return borderLayers?.first as? CAGradientLayer
    }
}
</code>```

And for more readable declaration of startPoint and endPoint of gradient layer I use this code:

```<code>public extension CGPoint {

    enum CoordinateSide {
        case topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left
    }

    static func unitCoordinate(_ side: CoordinateSide) -> CGPoint {
        let x: CGFloat
        let y: CGFloat

        switch side {
        case .topLeft:      x = 0.0; y = 0.0
        case .top:          x = 0.5; y = 0.0
        case .topRight:     x = 1.0; y = 0.0
        case .right:        x = 0.0; y = 0.5
        case .bottomRight:  x = 1.0; y = 1.0
        case .bottom:       x = 0.5; y = 1.0
        case .bottomLeft:   x = 0.0; y = 1.0
        case .left:         x = 1.0; y = 0.5
        }
        return .init(x: x, y: y)
    }
}
</code>```

So final usage is:

```<code>view.gradientBorder(
    width: 3,
    colors: [.red, .orange],
    startPoint: .unitCoordinate(.top),
    endPoint: .unitCoordinate(.bottom),
    andRoundCornersWithRadius: 12
)
</code>```

Body:
I want to make a gradient border of view like the following picture:

but I don't know how do it exactly , i.e. what the gradient color I should use to do it? how to set my view to show a border like the image?

I'm using the following code to get a border:

 self.view.layer.borderColor = [UIColor orangeColor].CGColor;
 self.view.layer.borderWidth = 2.0f;

Body:
Thanx Tiago Mendes for answer.

I improved functionality:

added corner radius.

And fixed some issues to ensure correct masking and given border width:

improved gradient layer frame;

improved mask path rounding rect.

Swift 5

public extension UIView {
    private static let kLayerNameGradientBorder = "GradientBorderLayer"

    func gradientBorder(
        width: CGFloat,
        colors: [UIColor],
        startPoint: CGPoint = .init(x: 0.5, y: 0),
        endPoint: CGPoint = .init(x: 0.5, y: 1),
        andRoundCornersWithRadius cornerRadius: CGFloat = 0
    ) {
        let existingBorder = gradientBorderLayer()
        let border = existingBorder ?? .init()
        border.frame = CGRect(
            x: bounds.origin.x,
            y: bounds.origin.y,
            width: bounds.size.width + width,
            height: bounds.size.height + width
        )
        border.colors = colors.map { $0.cgColor }
        border.startPoint = startPoint
        border.endPoint = endPoint

        let mask = CAShapeLayer()
        let maskRect = CGRect(
            x: bounds.origin.x + width/2,
            y: bounds.origin.y + width/2,
            width: bounds.size.width - width,
            height: bounds.size.height - width
        )
        mask.path = UIBezierPath(
            roundedRect: maskRect,
            cornerRadius: cornerRadius
        ).cgPath
        mask.fillColor = UIColor.clear.cgColor
        mask.strokeColor = UIColor.white.cgColor
        mask.lineWidth = width

        border.mask = mask

        let isAlreadyAdded = (existingBorder != nil)
        if !isAlreadyAdded {
            layer.addSublayer(border)
        }
    }

    private func gradientBorderLayer() -> CAGradientLayer? {
        let borderLayers = layer.sublayers?.filter {
            $0.name == UIView.kLayerNameGradientBorder
        }
        if borderLayers?.count ?? 0 > 1 {
            fatalError()
        }
        return borderLayers?.first as? CAGradientLayer
    }
}

And for more readable declaration of startPoint and endPoint of gradient layer I use this code:

public extension CGPoint {

    enum CoordinateSide {
        case topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left
    }

    static func unitCoordinate(_ side: CoordinateSide) -> CGPoint {
        let x: CGFloat
        let y: CGFloat

        switch side {
        case .topLeft:      x = 0.0; y = 0.0
        case .top:          x = 0.5; y = 0.0
        case .topRight:     x = 1.0; y = 0.0
        case .right:        x = 0.0; y = 0.5
        case .bottomRight:  x = 1.0; y = 1.0
        case .bottom:       x = 0.5; y = 1.0
        case .bottomLeft:   x = 0.0; y = 1.0
        case .left:         x = 1.0; y = 0.5
        }
        return .init(x: x, y: y)
    }
}

So final usage is:

view.gradientBorder(
    width: 3,
    colors: [.red, .orange],
    startPoint: .unitCoordinate(.top),
    endPoint: .unitCoordinate(.bottom),
    andRoundCornersWithRadius: 12
)


问:
PHP/MYSQL Query to be grouped by another array
My today's need, and I hope you will find the great solution, is the following.
I have a DB table with tasks, each of them with a status "open" or "closed". In my case I have only records with open tasks.

I need to build an array showing all status options (open, closed) and inside of each of them the tasks which are open or closed, if they exists.
Output should be:

```<code>Array (
  [open] => Attay(task1), Array(task2),..
  [closed] => Array()
)
</code>```

If I make the sql query:

```<code>select task_id,status from tasks group by status
</code>```

I get only the tasks inside "open". Which is the best way to build the status Array and "append" inside of each of them the tasks with that status?

thanks in advance!

答:
Thanks everybody for contributions.

I solved in this way.

```<code>  $statusArray = ['opened', 'wait_others', 'wait_us', 'closed'];
  foreach ($statusArray as $status) {
    $ticketsArray[$status]= array();
  }
  foreach ($row as $key => $value) {
    $ticketsArray[$value->status_title][$value->ticket_id]= $row[$key];
  }
  print"```";print_r($ticketsArray);
```

Body:
My today's need, and I hope you will find the great solution, is the following.
I have a DB table with tasks, each of them with a status "open" or "closed". In my case I have only records with open tasks.

I need to build an array showing all status options (open, closed) and inside of each of them the tasks which are open or closed, if they exists.
Output should be:

Array (
  [open] => Attay(task1), Array(task2),..
  [closed] => Array()
)

If I make the sql query:

select task_id,status from tasks group by status

I get only the tasks inside "open". Which is the best way to build the status Array and "append" inside of each of them the tasks with that status?

thanks in advance!

Body:
Thanks everybody for contributions.

I solved in this way.

  $statusArray = ['opened', 'wait_others', 'wait_us', 'closed'];
  foreach ($statusArray as $status) {
    $ticketsArray[$status]= array();
  }
  foreach ($row as $key => $value) {
    $ticketsArray[$value->status_title][$value->ticket_id]= $row[$key];
  }
  print"<pre>";print_r($ticketsArray);


问:
EditText settext on addTextChangedListener(TextWatcher) infite loop in Kotlin
I am using Kotlin. I need check EditText value &  add some logic to the value & set the value to same EditText every character. But unfortunately it is going infinite loop. I have use bellow code.

```<code>    EditText amount_txtAmount = findViewById(R.id.amount_txtAmount)

    amount_txtAmount.addTextChangedListener(object : TextWatcher {
        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {

        }

        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {

        }

        override fun afterTextChanged(s: Editable) {
            if (amount_txtAmount.text.toString().length > 0) {

                    var amount1 =   ValidationUtil.commaSeparateAmount(amount_txtAmount.text.toString())
                    Log.e("formatAmount-->", amount1)
                    amount_txtAmount.setText(amount1)

           }
        }
    })
</code>```

Please help how to overcome infinite loop.

答:
I'm not certain manipulating the text in the callback is the best solution, but if you want to do it, a possible way to fix the infinite loop is to remove and add the listener</p>

```<code>    override fun afterTextChanged(s: Editable) {
        if (amount_txtAmount.text.toString().length > 0) {

            amount_txtAmount.removeTextChangedListener(this)
            var amount1 =   ValidationUtil.commaSeparateAmount(amount_txtAmount.text.toString())
            Log.e("formatAmount-->", amount1)
            amount_txtAmount.setText(amount1)
            amount_txtAmount.addTextChangedListener(this)
        }
    }
</code>```

Body:
I am using Kotlin. I need check EditText value &  add some logic to the value & set the value to same EditText every character. But unfortunately it is going infinite loop. I have use bellow code.

    EditText amount_txtAmount = findViewById(R.id.amount_txtAmount)

    amount_txtAmount.addTextChangedListener(object : TextWatcher {
        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {

        }

        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {

        }

        override fun afterTextChanged(s: Editable) {
            if (amount_txtAmount.text.toString().length > 0) {

                    var amount1 =   ValidationUtil.commaSeparateAmount(amount_txtAmount.text.toString())
                    Log.e("formatAmount-->", amount1)
                    amount_txtAmount.setText(amount1)

           }
        }
    })

Please help how to overcome infinite loop.

Body:
I'm not certain manipulating the text in the callback is the best solution, but if you want to do it, a possible way to fix the infinite loop is to remove and add the listener

    override fun afterTextChanged(s: Editable) {
        if (amount_txtAmount.text.toString().length > 0) {

            amount_txtAmount.removeTextChangedListener(this)
            var amount1 =   ValidationUtil.commaSeparateAmount(amount_txtAmount.text.toString())
            Log.e("formatAmount-->", amount1)
            amount_txtAmount.setText(amount1)
            amount_txtAmount.addTextChangedListener(this)
        }
    }


问:
Venn diagram in R label mismatch
I was generating a venn diagram with label using the code as below:

```<code>v <- venn.diagram(list(ISG15=d1, USP18=d2),
                  fill = c("orange", "blue"),
                  alpha = c(0.5, 0.5), cat.cex = 3, cex=1.5,
                  filename=NULL)
# have a look at the default plot
grid.newpage()
grid.draw(v)

# have a look at the names in the plot object v
lapply(v,  names)
# We are interested in the labels
lapply(v, function(i) i$label)

# Over-write labels (5 to 7 chosen by manual check of labels)
# in foo only
v[[5]]$label  <- paste(setdiff(d1, d2), collapse="\n")
# in baa only
v[[6]]$label <- paste(setdiff(d2, d1)  , collapse="\n")
# intesection
v[[7]]$label <- paste(intersect(d1, d2), collapse="\n")
</code>```

Ideally I assume d1 (ISG15 in my dataset) will be on the left side, and d2 (UPS18) on the right. But actually d2 is on the left side, which cause my label mismatched. I don't understand the reason (probably because d1 has 25 element and d2 has 21 element? I don't know). Did I miss sth there?

But

答:
I had a look at the source code and saw that the sets are indeed sorted by size:

```<code>if (!inverted) {
    tmp1 <- max(area1, area2);
    tmp2 <- min(area1, area2);
    if (tmp1 != area1) { list.switch <- TRUE; }
    area1 <- tmp1;
    area2 <- tmp2;
    r1 <- sqrt(area1 / pi);
    r2 <- sqrt(area2 / pi);
    if (r2 == 0) {r2 <- 0.5*r1 }
    shrink.factor <- max.circle.size / r1;
    }
else {
    tmp1 <- max(area1, area2);
    tmp2 <- min(area1, area2);
    if (tmp1 != area1) { list.switch <- TRUE; }
    area1 <- tmp1;
    area2 <- tmp2;
    r1 <- sqrt(area1 / pi);
    r2 <- sqrt(area2 / pi);
    if (r1 == 0) {r1 <- 0.5*r2 }
    shrink.factor <- max.circle.size / r2;
    }
</code>```

In a very convoluted way, this sets a list.switch variable to true if area1 is not the largest. You can pass inverted=true to the function, but that means you have to keep track of which set is larger and apply the flag only when appropriate.
However, you may also want to consider other options, as detailed in this thread.

Title: Venn diagram in R label mismatch

Body:
I was generating a venn diagram with label using the code as below:

v <- venn.diagram(list(ISG15=d1, USP18=d2),
                  fill = c("orange", "blue"),
                  alpha = c(0.5, 0.5), cat.cex = 3, cex=1.5,
                  filename=NULL)
# have a look at the default plot
grid.newpage()
grid.draw(v)

# have a look at the names in the plot object v
lapply(v,  names)
# We are interested in the labels
lapply(v, function(i) i$label)

# Over-write labels (5 to 7 chosen by manual check of labels)
# in foo only
v[[5]]$label  <- paste(setdiff(d1, d2), collapse="\n")
# in baa only
v[[6]]$label <- paste(setdiff(d2, d1)  , collapse="\n")
# intesection
v[[7]]$label <- paste(intersect(d1, d2), collapse="\n")

Ideally I assume d1 (ISG15 in my dataset) will be on the left side, and d2 (UPS18) on the right. But actually d2 is on the left side, which cause my label mismatched. I don't understand the reason (probably because d1 has 25 element and d2 has 21 element? I don't know). Did I miss sth there?

But

Body:
I had a look at the source code and saw that the sets are indeed sorted by size:

if (!inverted) {
    tmp1 <- max(area1, area2);
    tmp2 <- min(area1, area2);
    if (tmp1 != area1) { list.switch <- TRUE; }
    area1 <- tmp1;
    area2 <- tmp2;
    r1 <- sqrt(area1 / pi);
    r2 <- sqrt(area2 / pi);
    if (r2 == 0) {r2 <- 0.5*r1 }
    shrink.factor <- max.circle.size / r1;
    }
else {
    tmp1 <- max(area1, area2);
    tmp2 <- min(area1, area2);
    if (tmp1 != area1) { list.switch <- TRUE; }
    area1 <- tmp1;
    area2 <- tmp2;
    r1 <- sqrt(area1 / pi);
    r2 <- sqrt(area2 / pi);
    if (r1 == 0) {r1 <- 0.5*r2 }
    shrink.factor <- max.circle.size / r2;
    }

In a very convoluted way, this sets a list.switch variable to true if area1 is not the largest. You can pass inverted=true to the function, but that means you have to keep track of which set is larger and apply the flag only when appropriate.
However, you may also want to consider other options, as detailed in this thread.


问:
How to plot multiple time intervals in pandas overlapped?
I have 3 sets of measurements from benchmarking an application with different parameters. Each test ran for the same amount of time but at different timestamps. I want to plot the results overlapping eachother.

The results are stored in a csv file with the following format: timestamp,duration.
I read the results in a pandas dataframe, convert timestamp to date time and make an aggregation to calculate the p90rt which I want to display (code below)

```<code>df["timestamp"] = pd.to_datetime(df["timestamp"], unit='ms')
df.set_index("timestamp", inplace=True)
gdf = df.groupby(pd.Grouper(freq=freq)).agg({"duration": q90})
</code>```

I do this for my 3 datasets, then I plot them using matplotlib:

```<code>ax = gdf_n.plot()
ax = gdf_r.plot(ax=ax)
gdf_p.plot(ax=ax)
plt.axhline(y=3500, color='r', linestyle='-')
</code>```

However, since they were done at different times they are plotted quite far apart. I would like them to overlap (they were all span the same amount of time - 4minutes). I'm looking for some way to normalize the date time index so the 3 plots are overlapped.

df.head()

```<code>       timestamp  duration  respCode
0  1589464106981       397       200
1  1589464107015       363       200
2  1589464107046       371       200
3  1589464107123       365       200
4  1589464107024       467       200
</code>```

答:
I found a solution albeit a bit hacky. I need the timestamp index in order to use the aggregator. So after the aggregation I wrote each dataframe to file and read again to drop the index. Afterwards index was reset and I could plot all of them.

```<code>gdf.to_csv('data.csv')
tdfn = pd.read_csv('data.csv')
tdfn = tdfn["duration"]
</code>```

Body:
I have 3 sets of measurements from benchmarking an application with different parameters. Each test ran for the same amount of time but at different timestamps. I want to plot the results overlapping eachother.

The results are stored in a csv file with the following format: timestamp,duration.
I read the results in a pandas dataframe, convert timestamp to date time and make an aggregation to calculate the p90rt which I want to display (code below)

df["timestamp"] = pd.to_datetime(df["timestamp"], unit='ms')
df.set_index("timestamp", inplace=True)
gdf = df.groupby(pd.Grouper(freq=freq)).agg({"duration": q90})

I do this for my 3 datasets, then I plot them using matplotlib:

ax = gdf_n.plot()
ax = gdf_r.plot(ax=ax)
gdf_p.plot(ax=ax)
plt.axhline(y=3500, color='r', linestyle='-')

However, since they were done at different times they are plotted quite far apart. I would like them to overlap (they were all span the same amount of time - 4minutes). I'm looking for some way to normalize the date time index so the 3 plots are overlapped.

df.head()

       timestamp  duration  respCode
0  1589464106981       397       200
1  1589464107015       363       200
2  1589464107046       371       200
3  1589464107123       365       200
4  1589464107024       467       200

Body:
I found a solution albeit a bit hacky. I need the timestamp index in order to use the aggregator. So after the aggregation I wrote each dataframe to file and read again to drop the index. Afterwards index was reset and I could plot all of them.

gdf.to_csv('data.csv')
tdfn = pd.read_csv('data.csv')
tdfn = tdfn["duration"]


问:
I have two git commits that appear the same after a pushed amend
I have a git branch that I am working on locally.  After editing some code and doing a commit and a push to a remote repo, I noticed that I had an error in my commit message.  I used amend to correct this.  First I tried to push, but this was not allowed,  So I did a pull and then a push.  Everything appeared to work.  When I look at the repo, I can see two commits, one for each message (both correct and incorrect, so I guess my correction was useless lol.)  Then I noticed that both commits contained the same code changes.  This seems strange, because I don't think that both should contain code changes.  Does this mean that the changes are applied twice?  Is this a problem that could cause issues later?  Does this need to be fixed?  If so, how do I fix this?

=====

commands

(IDE) Changes made, added and committed

git push -u origin BRANCH_NAME

(IDE) Amend performed

git push (error: failed to push some refs)

git pull

git push

答:
There is no such thing in git as an edited commit. A commit can never be changed once it exists.

What "amend" does is to start with an existing original commit and create a new commit containing the same files (what you incorrectly call "code changes") as the original commit and pointing to the same parent as the original commit.

The original commit is neither changed nor destroyed by this process, though if no ref ultimately points to it, it may go out of existence after a while as being unreachable.


问:
Cannot Import OrbitControls using Node 12 ES6 Import
I'm Using Node 12 (experimental-modules) and three (npm) and i cant get Imports to work for OrbitControls.js. I have index.js as "script: module".

Neither of these ES6 imports work

I tried copying the OrbitControls.js file out of the js folder (from the root folder of three) and placing it adjacent to index.js then adding

```<code>import {OrbitControls} from "./OrbitControls.js"
</code>```

It did not work i receive the error

Uncaught SyntaxError: The requested module './OrbitControls.js' does
  not provide an export named 'OrbitControls'

So I also tried to use the three library

```<code>import {OrbitControls} from "/three/examples/jsm/controls/OrbitControls";
</code>```

returns 404 error, so i tried relative imports

```<code>import {OrbitControls} from "../../node_modules/three/examples/jsm/controls/OrbitControls.js";
</code>```

got the 404 error again.

Ive also tried (something another user reccommended) const OrbitControls = new THREE.OrbitControls but the error seems happen from the ES6 import alone.

答:
I haven't used experimental-modules, but your second example should read

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

without the / before three;

If that doesn't work, you could try copy-pasting the OrbitControls.js source code from here to your own folder.

import { OrbitControls } from "./myFolder/OrbitControls";

If this works, then it might be a problem with your node_modules installation.

Body:
I'm Using Node 12 (experimental-modules) and three (npm) and i cant get Imports to work for OrbitControls.js. I have index.js as "script: module".

Neither of these ES6 imports work

I tried copying the OrbitControls.js file out of the js folder (from the root folder of three) and placing it adjacent to index.js then adding

import {OrbitControls} from "./OrbitControls.js"

It did not work i receive the error

Uncaught SyntaxError: The requested module './OrbitControls.js' does
  not provide an export named 'OrbitControls'

So I also tried to use the three library

import {OrbitControls} from "/three/examples/jsm/controls/OrbitControls";

returns 404 error, so i tried relative imports

import {OrbitControls} from "../../node_modules/three/examples/jsm/controls/OrbitControls.js";

got the 404 error again.

Ive also tried (something another user reccommended) const OrbitControls = new THREE.OrbitControls but the error seems happen from the ES6 import alone.


问:
Using the right Perl array references with IPC::Run
I'm trying to get this Perl code to work correctly and I believe I just need to get my references right. I would appreciate any feedback on how to use references, but if this code can't be made to work without API changes I would also appreciate feedback on how to change the surrounding APIs to support the data types I need.

I'm trying to add a new test to the PostgreSQL test suite. The code in question runs a subprocess and stores the process arguments in an array literal in a hash. for example:

```<code>my %pgdump_runs = (
    defaults => {
        dump_cmd => [
            'pg_dump', '--no-sync',
            '-f',      "$tempdir/defaults.sql",
            'postgres',
        ],
    },
    # and others
)
</code>```

That array gets passed to a helper library like so:

```<code>    $node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} },
        "$run: pg_dump runs");
</code>```

The helper library keeps passing the array down:

```<code>sub command_ok
{
    my ($cmd, $test_name) = @_;
    my $result = run_log($cmd);
</code>```

and then finally calling IPC::Run:

```<code>sub run_log
{
    return IPC::Run::run(@_);
}
</code>```

To write my test case I have to pipe the output of a command to a file descriptor that does not support seeking. It looks like the IPC::Run module supports piping for you. Here's the example for the docs:

```<code>run \@cmd1, '|', \@cmd2;
</code>```

But I tried a bunch of different ways to try and structure my array literal and none of them worked. For example, I tried this and I believe it gave me an ARRAY(0xFFFFFFFF) error:

```<code>        dump_cmd => [
            ['pg_dump', 'db'],
            '|',
            ['pg_restore', 'db2'],
        ],
</code>```

How can I get this code to set up multiple sub-processes with piping?

UPDATE: I tried out ikegami's suggestion: the command_ok function can only have two arguments passed to it, so that doesn't work (you have to pass an array reference for the first argument).

UPDATE: turning on IPC:Run's debug functionality I can see how it's trying to interpret my command line. Instead of dereferencing the array it's trying to stringify (?) it and exec that string as an executable:

```<code>1070 IPC::Run 0002 01234567890- [#11(59856)]: parsing [ 'ARRAY(0x7ff3016f1090)', '|', 'ARRAY(0x7ff3016f1510)', '>/Users/david/src/pg_bug/postgres/foo' ]
</code>```

答:
You are effectively doing the following:[1]

my %pgdump_runs = (
    foo => {
        dump_cmd => [
            ['pg_dump', 'db'],
            '|',
            ['pg_restore', 'db2'],
        ],
    },
);

IPC::Run::run( $pgdump_runs{foo}{dump_cmd} )
```
<p>This passes a single argument to <code>run</code>, but you indicated you wanted to achieve something analogous to</p>
<pre class="lang-perl prettyprint-override"><code>run \@cmd1, '|', \@cmd2;
</code>```

That would require

IPC::Run::run( @{ $pgdump_runs{foo}{dump_cmd} } )
```
<hr />
<p>A few ways you can fix this:</p>
<ol>
<li><p>Replace</p>
<pre class="lang-perl prettyprint-override"><code>return IPC::Run::run(@_);
</code>```

with

return IPC::Run::run(@{ $_[0] });
```
</li>
<li><p>Replace</p>
<pre class="lang-perl prettyprint-override"><code>run_log($cmd);
</code>```

with

run_log(@$cmd);
```
</li>
<li><p>Replace</p>
<pre class="lang-perl prettyprint-override"><code>sub command_ok {
    my ($cmd, $test_name) = @_;
    my $result = run_log($cmd);
}

$node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} }, "$run: pg_dump runs");
</code>```

with

sub command_ok {
    my $test_name = shift;
    my $result = run_log(@_);
}

$node->command_ok("$run: pg_dump runs", @{ $pgdump_runs{$run}{dump_cmd} });
```
</li>
<li><p>Replace</p>
<pre class="lang-perl prettyprint-override"><code>dump_cmd => [
    ['pg_dump', 'db'],
    '|',
    ['pg_restore', 'db2'],
],
</code>```

with

use String::ShellQuote qw( shell_quote );

dump_cmd => join(' ',
    shell_quote('pg_dump', 'db'),
    '|',
    shell_quote('pg_restore', 'db2'),
),
```
</li>
</ol>
<hr />
<p>Footnotes:</p>
<ol>
<li><p>Unless you are trying to autovivify (which you're not),</p>
<pre class="lang-perl prettyprint-override"><code>\@{ $pgdump_runs{$run}->{dump_cmd} }
</code>```

can also be written as

$pgdump_runs{$run}->{dump_cmd}
```

And in both cases, the -> can be omitted because it's between two indexes.

Body:
I'm trying to get this Perl code to work correctly and I believe I just need to get my references right. I would appreciate any feedback on how to use references, but if this code can't be made to work without API changes I would also appreciate feedback on how to change the surrounding APIs to support the data types I need.

I'm trying to add a new test to the PostgreSQL test suite. The code in question runs a subprocess and stores the process arguments in an array literal in a hash. for example:

my %pgdump_runs = (
    defaults => {
        dump_cmd => [
            'pg_dump', '--no-sync',
            '-f',      "$tempdir/defaults.sql",
            'postgres',
        ],
    },
    # and others
)

That array gets passed to a helper library like so:

    $node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} },
        "$run: pg_dump runs");

The helper library keeps passing the array down:

sub command_ok
{
    my ($cmd, $test_name) = @_;
    my $result = run_log($cmd);

and then finally calling IPC::Run:

sub run_log
{
    return IPC::Run::run(@_);
}

To write my test case I have to pipe the output of a command to a file descriptor that does not support seeking. It looks like the IPC::Run module supports piping for you. Here's the example for the docs:

run \@cmd1, '|', \@cmd2;

But I tried a bunch of different ways to try and structure my array literal and none of them worked. For example, I tried this and I believe it gave me an ARRAY(0xFFFFFFFF) error:

        dump_cmd => [
            ['pg_dump', 'db'],
            '|',
            ['pg_restore', 'db2'],
        ],

How can I get this code to set up multiple sub-processes with piping?

UPDATE: I tried out ikegami's suggestion: the command_ok function can only have two arguments passed to it, so that doesn't work (you have to pass an array reference for the first argument).

UPDATE: turning on IPC:Run's debug functionality I can see how it's trying to interpret my command line. Instead of dereferencing the array it's trying to stringify (?) it and exec that string as an executable:

1070 IPC::Run 0002 01234567890- [#11(59856)]: parsing [ 'ARRAY(0x7ff3016f1090)', '|', 'ARRAY(0x7ff3016f1510)', '>/Users/david/src/pg_bug/postgres/foo' ]

Body:
You are effectively doing the following:[1]

my %pgdump_runs = (
    foo => {
        dump_cmd => [
            ['pg_dump', 'db'],
            '|',
            ['pg_restore', 'db2'],
        ],
    },
);

IPC::Run::run( $pgdump_runs{foo}{dump_cmd} )

This passes a single argument to run, but you indicated you wanted to achieve something analogous to

run \@cmd1, '|', \@cmd2;

That would require

IPC::Run::run( @{ $pgdump_runs{foo}{dump_cmd} } )

A few ways you can fix this:

Replace

return IPC::Run::run(@_);

with

return IPC::Run::run(@{ $_[0] });

Replace

run_log($cmd);

with

run_log(@$cmd);

Replace

sub command_ok {
    my ($cmd, $test_name) = @_;
    my $result = run_log($cmd);
}

$node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} }, "$run: pg_dump runs");

with

sub command_ok {
    my $test_name = shift;
    my $result = run_log(@_);
}

$node->command_ok("$run: pg_dump runs", @{ $pgdump_runs{$run}{dump_cmd} });

Replace

dump_cmd => [
    ['pg_dump', 'db'],
    '|',
    ['pg_restore', 'db2'],
],

with

use String::ShellQuote qw( shell_quote );

dump_cmd => join(' ',
    shell_quote('pg_dump', 'db'),
    '|',
    shell_quote('pg_restore', 'db2'),
),

Footnotes:

Unless you are trying to autovivify (which you're not),

\@{ $pgdump_runs{$run}->{dump_cmd} }

can also be written as

$pgdump_runs{$run}->{dump_cmd}

And in both cases, the -> can be omitted because it's between two indexes.


问:
How to create union of two different django-models?
I have two django-models

```<code>class ModelA(models.Model):
    title = models.CharField(..., db_column='title')
    text_a = models.CharField(..., db_column='text_a')
    other_column = models.CharField(/*...*/ db_column='other_column_a')

class ModelB(models.Model):
    title = models.CharField(..., db_column='title')
    text_a = models.CharField(..., db_column='text_b')
    other_column = None
</code>```

Then I want to merge the two querysets of this models using union

```<code>ModelA.objects.all().union(ModelB.objects.all())
</code>```

But in query I see

```<code>(SELECT
`model_a`.`title`,
`model_a`.`text_a`,
`model_a`.`other_column`
FROM `model_a`)

UNION
(SELECT
`model_b`.`title`,
`model_b`.`text_b`
FROM `model_b`)
</code>```

Of course I got the exception The used SELECT statements have a different number of columns.

How to create the aliases and fake columns to use union-query?

答:
You can annotate your last column to make up for column number mismatch.</p>
```<code>a = ModelA.objects.values_list('text_a', 'title', 'other_column')
b = ModelB.objects.values_list('text_a', 'title')
        .annotate(other_column=Value("Placeholder", CharField()))

# for a list of tuples
a.union(b)

# or if you want list of dict
# (this has to be the values of the base query, in this case a)

a.union(b).values('text_a', 'title', 'other_column')

</code>```

Body:
I have two django-models

class ModelA(models.Model):
    title = models.CharField(..., db_column='title')
    text_a = models.CharField(..., db_column='text_a')
    other_column = models.CharField(/*...*/ db_column='other_column_a')

class ModelB(models.Model):
    title = models.CharField(..., db_column='title')
    text_a = models.CharField(..., db_column='text_b')
    other_column = None

Then I want to merge the two querysets of this models using union

ModelA.objects.all().union(ModelB.objects.all())

But in query I see

(SELECT
`model_a`.`title`,
`model_a`.`text_a`,
`model_a`.`other_column`
FROM `model_a`)

UNION
(SELECT
`model_b`.`title`,
`model_b`.`text_b`
FROM `model_b`)

Of course I got the exception The used SELECT statements have a different number of columns.

How to create the aliases and fake columns to use union-query?

Body:
You can annotate your last column to make up for column number mismatch.

a = ModelA.objects.values_list('text_a', 'title', 'other_column')
b = ModelB.objects.values_list('text_a', 'title')
        .annotate(other_column=Value("Placeholder", CharField()))

# for a list of tuples
a.union(b)

# or if you want list of dict
# (this has to be the values of the base query, in this case a)

a.union(b).values('text_a', 'title', 'other_column')


答:
Here's a complete example</p>

```<code>#include <vector>
#include <iostream>
#include <algorithm>

class Person
{
public:
    std::string s1, s2, s3;

    Person(std::string S1, std::string S2, std::string S3) : s1(S1), s2(S2), s3(S3) {}
};

struct less_than_key
{
    inline bool operator() (const Person* const p1, const Person* const p2)
    {
        if (p1->s1 < p2->s1)
            return true;
        else if (p1->s1 == p2->s1 && p1->s2 < p2->s2)
            return true;

        return false;
    }
};

int main()
{
    std::vector<Person*> persons{ new Person("C", "D", "E"), new Person("C", "C", "D"),
                                  new Person("B", "C", "D"), new Person("B", "C", "E")};

    std::sort(persons.begin(), persons.end(), less_than_key());

    for (auto person : persons)
    {
        std::cout << person->s1 << ' ' << person->s2 << std::endl;
    }

    return 0;
}
</code>```

Title: Sorting a vector with pointer at object C++

Body:
If anyone can help I would be very grateful.
How do i sort this vector:

vector<Person*>person

by this criterium:

Surname

I have already tried it using set but it removes object if there is more than 2 objects with same Surname

there are lot of string variables, and I need to sort it by

Surname

and then if surnames are the same, then I need to sort them by

Name

and also it sorts by hexadecimal value of that pointer...
EDIT:
More code as you ask:

for (pChild = pRoot->FirstChildElement("Member"); pChild != NULL; pChild = pChild->NextSiblingElement())
    {
        string Surname = pChild->Attribute("surname");
        string Name = pChild->Attribute("name");
        string DateOfBirth = pChild->Attribute("dateofbirth");
        person.push_back(new Person(Surname, Name, DateOfBirth));
    }

Body:
Here's a complete example

#include <vector>
#include <iostream>
#include <algorithm>

class Person
{
public:
    std::string s1, s2, s3;

    Person(std::string S1, std::string S2, std::string S3) : s1(S1), s2(S2), s3(S3) {}
};

struct less_than_key
{
    inline bool operator() (const Person* const p1, const Person* const p2)
    {
        if (p1->s1 < p2->s1)
            return true;
        else if (p1->s1 == p2->s1 && p1->s2 < p2->s2)
            return true;

        return false;
    }
};

int main()
{
    std::vector<Person*> persons{ new Person("C", "D", "E"), new Person("C", "C", "D"),
                                  new Person("B", "C", "D"), new Person("B", "C", "E")};

    std::sort(persons.begin(), persons.end(), less_than_key());

    for (auto person : persons)
    {
        std::cout << person->s1 << ' ' << person->s2 << std::endl;
    }

    return 0;
}


问:
NGINX server works normally in LAN, but doesn't work outside of it
I am running a Django project on NGINX + UWSGI. It's working properly in LAN, but from outside it shows just the NGINX default page. What can be a problem here?</p>

答: You should check if your router is redirecting the traffic to your nginx server, also check if your ISP is giving you an public IP, there is several scenarios that won't let you access to you nginx server please check if the you have a public IP and then we you can check your router in order to check if the http traffic is being redirected to your local server </p>


问:
How to get return value from call to perl sub from bash script?
I am calling a perl script from a bash script. I want to obtain the return value that the perl script returns in the bash script in order to act on it. When I have the following, the output is a blank line to the console when I expect it to be "good".

bashThing.sh

```<code>#!/bin/bash

ARG="valid"
VAL=$(perl -I. -MperlThing -e "perlThing::isValid ${ARG}")
echo $VAL
</code>```

perlThing.pm

```<code>#! /usr/bin/perl -w
use strict;

package perlThing;

sub isValid
{
  my $arg = shift;
  if($arg == "valid")
  {
    return "good";
  }
  else
  {
    return "bad";
  }
}

1;
</code>```

答:
If you expect the value good or bad in $VAR, then you should print them not return them.

Other than printed stuff, the perl process can pass only integer return values to calling program. And you can check that using $? in bash script, this variable stores the return value of last run process.

Body:
I am calling a perl script from a bash script. I want to obtain the return value that the perl script returns in the bash script in order to act on it. When I have the following, the output is a blank line to the console when I expect it to be "good".

bashThing.sh

#!/bin/bash

ARG="valid"
VAL=$(perl -I. -MperlThing -e "perlThing::isValid ${ARG}")
echo $VAL

perlThing.pm

#! /usr/bin/perl -w
use strict;

package perlThing;

sub isValid
{
  my $arg = shift;
  if($arg == "valid")
  {
    return "good";
  }
  else
  {
    return "bad";
  }
}

1;


问:
flutter has a problem with redux dependencies
i have a problem to run my flutter app, it seems flutter doesn't recognize it. i tried to connect to internet while running the project but the problem remains the same, here is the error message:

and here is the code where i inserted the dependency :

```<code>   dependencies:
    redux: ^4.0.0
    flutter_redux: ^0.6.0
</code>```

答: Your package name is likely also redux according to this Github issue. You'll have to change your package name to something other than redux and you should be able to flutter pub get.

Body:
i have a problem to run my flutter app, it seems flutter doesn't recognize it. i tried to connect to internet while running the project but the problem remains the same, here is the error message:

and here is the code where i inserted the dependency :

   dependencies:
    redux: ^4.0.0
    flutter_redux: ^0.6.0


问:
How to sum the value from dynamic nested array field and create a object for per input field
I am trying to develop a number grading system for a course using Angular 8. The real scenario is quite complex, so I separated the part and created a new project to explain where I have the problem. If you look at the image you will get an idea, what I am trying to accomplish. Assume this is the grade form of one course. For a course, there can have different exams. Students who are enrolled in this course, they will attend those specific exams for this course and then teacher will submit the number using this form. Suppose, for the first row first column (Mid Exam), the form should not allow you to provide more than 25 marks or less than zero. If you put 20 on the Mid Exam field then Total will show 20, GP will show 0.00, Grade will show F. Then if you put 30 on the Final exam field, Total value will be updated to 50, GP will be updated to 0.00 and will be updated to F. Again if you put 40 on the Assessment field,  Total value will be updated to 90, GP will be updated to 4.00 and will be updated to A. Same thing will be happened to for all the row. If you click on the Save button, numbers will be submitted.

Now I am describing the code that I tried and my problem, here studentList,  examList and gradePointList array will populate the data for a course from backend service. I created populateSomeDemoData method to generate this data. studentList is an array of the Student object which contains students' id and name. examList is an array of the Exam object which contains exam id, exam name and total marks of this exam. gradePointList contains the range of the number of letter grade and grade point. Suppose if the total mark is between 90 (minimumNumber) and 100 (maximumNumber) the grade point will be 4.00 and letter grade will be A. I tried to create a form gradeForm and applied a loop on examList for per row to create input field. But for this, I couldn't able to access the specific field using form control that's why I failed to calculate total marks and grade point for a row. Also for the same reason, I failed to create the list of Grade object which will be sent to the backend. Grade is the object of every field which will contain student, exam and number. If a field is updated, this grade object will also be updated. If Save button triggers, this number list will be passed to the backend.

HTML part is:

```<code><form [formGroup]="gradeForm" (ngSubmit)="saveGrade()">
  <table>
    <thead>
    <tr>
      <th> #</th>
      <th>Student</th>
      <th *ngFor="let exam of examList">{{exam.name}} ({{exam.marks}}%)</th>
      <th>Total</th>
      <th>GP</th>
      <th>Grade</th>
    </tr>
    </thead>

    <tbody>
    <tr *ngFor="let student of studentList; let i = index">
      <th> {{ i + 1 }} </th>
      <th> {{ student.id }} <br/> {{student.name}} </th>
      <th *ngFor="let grade of gradeFields.controls; let j = index" formArrayName="gradeFields">
        <input type="number" [formControlName]="j">
      </th>
      <th>??</th>
      <th>??</th>
      <th>??</th>
    </tr>
    </tbody>
  </table>

  <div class="wrapper">
    <button class="button">Save Grade</button>
  </div>
</form>
</code>```

TypeScript Part is:

```<code>export class AppComponent {

  public gradeForm: FormGroup;

  // This arrays will populate dynamically from the database
  public examList: Exam[] = [];
  public studentList: Student[] = [];
  public gradePointList: GradePoint[] = [];
  public gradeList: Grade[] = [];

  constructor(private formBuilder: FormBuilder) {

    this.populateSomeDemoData();

    this.createGradeForm();
  }

  createGradeForm(): void {
    this.gradeForm = this.formBuilder.group({
      gradeFields: this.formBuilder.array([
        this.formBuilder.control('')
      ])
    });

    for (let i = 0; i < this.examList.length - 1; i++) {
      this.gradeFields.push(this.formBuilder.control(''));
    }
  }

  get gradeFields() {
    return this.gradeForm.get('gradeFields') as FormArray;
  }

  saveGrade(): void {
    console.log(this.gradeForm.get('gradeFields').value);
    console.log(this.gradeList);
    console.log('Grade List Saved');
  }

  populateSomeDemoData(): void {
    // Static value for populating arrays for easy explanation
    const midTerm = new Exam();
    midTerm.id = '1';
    midTerm.name = 'Mid Exam';
    midTerm.marks = 25;

    const finalExam = new Exam();
    finalExam.id = '2';
    finalExam.name = 'Final Exam';
    finalExam.marks = 30;

    const assessmentExam = new Exam();
    assessmentExam.id = '3';
    assessmentExam.name = 'Assessment';
    assessmentExam.marks = 40;

    const attendance = new Exam();
    attendance.id = '4';
    attendance.name = 'Attendance';
    attendance.marks = 5;

    this.examList.push(midTerm);
    this.examList.push(finalExam);
    this.examList.push(assessmentExam);
    this.examList.push(attendance);

    // Static value for populating arrays for easy explanation
    const student1 = new Student();
    student1.id = '14101561';
    student1.name = 'Petey Cruiser';

    const student2 = new Student();
    student2.id = '14112201';
    student2.name = 'Bob Frapples';

    const student3 = new Student();
    student3.id = '14112202';
    student3.name = 'Paul Molive';

    const student4 = new Student();
    student4.id = '16113004';
    student4.name = 'Anna Mull';

    const student5 = new Student();
    student5.id = '16113005';
    student5.name = 'Gail Forcewind';

    this.studentList.push(student1);
    this.studentList.push(student2);
    this.studentList.push(student3);
    this.studentList.push(student4);
    this.studentList.push(student5);

    // Static value for populating arrays for easy explanation
    const aGradePoint = new GradePoint();
    aGradePoint.minimumNumber = 90;
    aGradePoint.maximumNumber = 100;
    aGradePoint.gradePoint = 4;
    aGradePoint.letterGrade = 'A';

    const bGradePoint = new GradePoint();
    bGradePoint.minimumNumber = 80;
    bGradePoint.maximumNumber = 89;
    bGradePoint.gradePoint = 3.5;
    bGradePoint.letterGrade = 'B';

    const cGradePoint = new GradePoint();
    cGradePoint.minimumNumber = 70;
    cGradePoint.maximumNumber = 79;
    cGradePoint.gradePoint = 3;
    cGradePoint.letterGrade = 'C';

    const dGradePoint = new GradePoint();
    dGradePoint.minimumNumber = 60;
    dGradePoint.maximumNumber = 69;
    dGradePoint.gradePoint = 2.5;
    dGradePoint.letterGrade = 'D';

    const fGradePoint = new GradePoint();
    fGradePoint.minimumNumber = 0;
    fGradePoint.maximumNumber = 59;
    fGradePoint.gradePoint = 0;
    fGradePoint.letterGrade = 'F';
    this.gradePointList.push(aGradePoint);
    this.gradePointList.push(bGradePoint);
    this.gradePointList.push(cGradePoint);
    this.gradePointList.push(dGradePoint);
    this.gradePointList.push(fGradePoint);
  }
}

export class Student {
  public id: string;
  public name: string;

  constructor(student?) {
    student = student || {};
    this.id = student.id || null;
    this.name = student.name || null;
  }
}

export class Exam {
  public id: string;
  public name: string;
  public marks: number;

  constructor(exam?) {
    exam = exam || {};
    this.id = exam.id || null;
    this.name = exam.name || null;
    this.marks = exam.marks || 0;
  }
}

export class GradePoint {
  public minimumNumber: number;
  public maximumNumber: number;
  public gradePoint: number;
  public letterGrade: string;

  constructor(gradePoint?) {
    gradePoint = gradePoint || {};
    this.minimumNumber = gradePoint.minimumNumber || 0;
    this.maximumNumber = gradePoint.maximumNumber || 59;
    this.gradePoint = gradePoint.gradePoint || 0;
    this.letterGrade = gradePoint.letterGrade || 'F';
  }
}

export class Grade {
  public student: Student;
  public exam: Exam;
  public number: number;

  constructor(grade?) {
    grade = grade || {};
    this.student = grade.student || null;
    this.exam = grade.exam || null;
    this.number = grade.number || null;
  }
}
</code>```

I have created a StackBlitz for better understanding of the code. Please click on this link to view the code. Click here

I saw a lot of post which is related to Form Arrays but my scenario is quite different. Here I don't have any Add button to push array or calculate the values. And there are fixed forms for all cases. But in my case, the array also will be generated from the list because examList is dynamic.

I assume I have problem with creating on the form or my approaches are wrong. Please help me to accomplish my objective generate total marks and creating Grade list. It would be appreciated. Thanks in advance.

答:
Ok I can see that to meet your requirements you have to use nested arrays, you need to follow this structure, or at least a 2 d array,
grades[][]: grades[studentId][examId], you will understand more when you read the code, there is a lot missing in your code, for example the validations for the marks and the calculation for total and GP fields, I will not bother with these parts (I added a sample for calculation and validation, but you need to modify it), but I will show you how to populate your form group properly, and how to use it, having a dynamic view.
As I mention you need a 2d array, for me I went with more info, so I have an array of object, the object has 2 properties, one is student control (hold student id), and one is an array of grades for this student
here is the loop I used to populate my form group

```<code>createGradeForm(): void {
    this.gradeForm = this.formBuilder.group({
        gradeFields: this.formBuilder.array([])
    });
    //loop all students
    for (let b = 0; b < this.studentList.length; b++) {
    // create a form group to hold student data
        const userGroup = this.formBuilder.group({
            student: this.formBuilder.control(this.studentList[b].id),
            grades: this.formBuilder.array([])
        })
        //populate grades form array
        for (let i = 0; i < this.examList.length; i++) {
            //Bonus, I added a validator for you, max value is the mark, please apply min and other validations on your own.
            userGroup.get('grades').push(this.formBuilder.control('', [Validators.max(this.examList[i].marks)]));
        }
        // add the form group to your array
        this.gradeFields.push(userGroup);
    }
    //Check result here
    console.log(this.gradeFields);

}
</code>```

For your view, you will have nested ng-for, one to loop students rows, and one to loop through your grades (columns)

```<code><tbody>
    <!-- loop through the higher level array (students) -->
    <ng-container *ngFor="let student of gradeFields.controls; let i = index" formArrayName='gradeFields'>
        <ng-container [formGroupName]='i'>
            <tr>
                <th> {{ i + 1 }} </th>
                <-- this is student control -->
                <th> {{ student.get('student').value }} </th>
                <-- loop through your grades array -->
                <th *ngFor="let grade of student.get('grades').controls; let j = index" formArrayName="grades">
                    <-- bonus here, I added an example for validation, add style to your css for .inValid to see when invalid -->
                    <input [class.inValid]='!grade.valid' type="number" [formControlName]="j">
                </th>
                 <-- one more bonus, an example of calculation getTotal -->
                <th>{{getTotal(i)}}</th>
                <th>??</th>
                <th>??</th>
            </tr>
        </ng-container>
    </ng-container>
</tbody>
</code>```

Get Total Function

```<code>//It takes the index of the student, get all grades, and accumlate them, the logic is wrong, please modify it, I just sum all grades, you have to add the logic
getTotal(ind) {
    const studentGrades = this.gradeFields.value[ind].grades;

    return studentGrades.reduce((a, b) => Number(a) + Number(b));
}
</code>```

working stackblitz here

Read More about form arrays and reactive forms

Body:
I am trying to develop a number grading system for a course using Angular 8. The real scenario is quite complex, so I separated the part and created a new project to explain where I have the problem. If you look at the image you will get an idea, what I am trying to accomplish. Assume this is the grade form of one course. For a course, there can have different exams. Students who are enrolled in this course, they will attend those specific exams for this course and then teacher will submit the number using this form. Suppose, for the first row first column (Mid Exam), the form should not allow you to provide more than 25 marks or less than zero. If you put 20 on the Mid Exam field then Total will show 20, GP will show 0.00, Grade will show F. Then if you put 30 on the Final exam field, Total value will be updated to 50, GP will be updated to 0.00 and will be updated to F. Again if you put 40 on the Assessment field,  Total value will be updated to 90, GP will be updated to 4.00 and will be updated to A. Same thing will be happened to for all the row. If you click on the Save button, numbers will be submitted.

Now I am describing the code that I tried and my problem, here studentList,  examList and gradePointList array will populate the data for a course from backend service. I created populateSomeDemoData method to generate this data. studentList is an array of the Student object which contains students' id and name. examList is an array of the Exam object which contains exam id, exam name and total marks of this exam. gradePointList contains the range of the number of letter grade and grade point. Suppose if the total mark is between 90 (minimumNumber) and 100 (maximumNumber) the grade point will be 4.00 and letter grade will be A. I tried to create a form gradeForm and applied a loop on examList for per row to create input field. But for this, I couldn't able to access the specific field using form control that's why I failed to calculate total marks and grade point for a row. Also for the same reason, I failed to create the list of Grade object which will be sent to the backend. Grade is the object of every field which will contain student, exam and number. If a field is updated, this grade object will also be updated. If Save button triggers, this number list will be passed to the backend.

HTML part is:

<form [formGroup]="gradeForm" (ngSubmit)="saveGrade()">

       #
      Student
      {{exam.name}} ({{exam.marks}}%)
      Total
      GP
      Grade

       {{ i + 1 }}
       {{ student.id }}
 {{student.name}}

        <input type="number" [formControlName]="j">

      ??
      ??
      ??

    <button class="button">Save Grade</button>

</form>

TypeScript Part is:

export class AppComponent {

  public gradeForm: FormGroup;

  // This arrays will populate dynamically from the database
  public examList: Exam[] = [];
  public studentList: Student[] = [];
  public gradePointList: GradePoint[] = [];
  public gradeList: Grade[] = [];

  constructor(private formBuilder: FormBuilder) {

    this.populateSomeDemoData();

    this.createGradeForm();
  }

  createGradeForm(): void {
    this.gradeForm = this.formBuilder.group({
      gradeFields: this.formBuilder.array([
        this.formBuilder.control('')
      ])
    });

    for (let i = 0; i < this.examList.length - 1; i++) {
      this.gradeFields.push(this.formBuilder.control(''));
    }
  }

  get gradeFields() {
    return this.gradeForm.get('gradeFields') as FormArray;
  }

  saveGrade(): void {
    console.log(this.gradeForm.get('gradeFields').value);
    console.log(this.gradeList);
    console.log('Grade List Saved');
  }

  populateSomeDemoData(): void {
    // Static value for populating arrays for easy explanation
    const midTerm = new Exam();
    midTerm.id = '1';
    midTerm.name = 'Mid Exam';
    midTerm.marks = 25;

    const finalExam = new Exam();
    finalExam.id = '2';
    finalExam.name = 'Final Exam';
    finalExam.marks = 30;

    const assessmentExam = new Exam();
    assessmentExam.id = '3';
    assessmentExam.name = 'Assessment';
    assessmentExam.marks = 40;

    const attendance = new Exam();
    attendance.id = '4';
    attendance.name = 'Attendance';
    attendance.marks = 5;

    this.examList.push(midTerm);
    this.examList.push(finalExam);
    this.examList.push(assessmentExam);
    this.examList.push(attendance);

    // Static value for populating arrays for easy explanation
    const student1 = new Student();
    student1.id = '14101561';
    student1.name = 'Petey Cruiser';

    const student2 = new Student();
    student2.id = '14112201';
    student2.name = 'Bob Frapples';

    const student3 = new Student();
    student3.id = '14112202';
    student3.name = 'Paul Molive';

    const student4 = new Student();
    student4.id = '16113004';
    student4.name = 'Anna Mull';

    const student5 = new Student();
    student5.id = '16113005';
    student5.name = 'Gail Forcewind';

    this.studentList.push(student1);
    this.studentList.push(student2);
    this.studentList.push(student3);
    this.studentList.push(student4);
    this.studentList.push(student5);

    // Static value for populating arrays for easy explanation
    const aGradePoint = new GradePoint();
    aGradePoint.minimumNumber = 90;
    aGradePoint.maximumNumber = 100;
    aGradePoint.gradePoint = 4;
    aGradePoint.letterGrade = 'A';

    const bGradePoint = new GradePoint();
    bGradePoint.minimumNumber = 80;
    bGradePoint.maximumNumber = 89;
    bGradePoint.gradePoint = 3.5;
    bGradePoint.letterGrade = 'B';

    const cGradePoint = new GradePoint();
    cGradePoint.minimumNumber = 70;
    cGradePoint.maximumNumber = 79;
    cGradePoint.gradePoint = 3;
    cGradePoint.letterGrade = 'C';

    const dGradePoint = new GradePoint();
    dGradePoint.minimumNumber = 60;
    dGradePoint.maximumNumber = 69;
    dGradePoint.gradePoint = 2.5;
    dGradePoint.letterGrade = 'D';

    const fGradePoint = new GradePoint();
    fGradePoint.minimumNumber = 0;
    fGradePoint.maximumNumber = 59;
    fGradePoint.gradePoint = 0;
    fGradePoint.letterGrade = 'F';
    this.gradePointList.push(aGradePoint);
    this.gradePointList.push(bGradePoint);
    this.gradePointList.push(cGradePoint);
    this.gradePointList.push(dGradePoint);
    this.gradePointList.push(fGradePoint);
  }
}

export class Student {
  public id: string;
  public name: string;

  constructor(student?) {
    student = student || {};
    this.id = student.id || null;
    this.name = student.name || null;
  }
}

export class Exam {
  public id: string;
  public name: string;
  public marks: number;

  constructor(exam?) {
    exam = exam || {};
    this.id = exam.id || null;
    this.name = exam.name || null;
    this.marks = exam.marks || 0;
  }
}

export class GradePoint {
  public minimumNumber: number;
  public maximumNumber: number;
  public gradePoint: number;
  public letterGrade: string;

  constructor(gradePoint?) {
    gradePoint = gradePoint || {};
    this.minimumNumber = gradePoint.minimumNumber || 0;
    this.maximumNumber = gradePoint.maximumNumber || 59;
    this.gradePoint = gradePoint.gradePoint || 0;
    this.letterGrade = gradePoint.letterGrade || 'F';
  }
}

export class Grade {
  public student: Student;
  public exam: Exam;
  public number: number;

  constructor(grade?) {
    grade = grade || {};
    this.student = grade.student || null;
    this.exam = grade.exam || null;
    this.number = grade.number || null;
  }
}

I have created a StackBlitz for better understanding of the code. Please click on this link to view the code. Click here

I saw a lot of post which is related to Form Arrays but my scenario is quite different. Here I don't have any Add button to push array or calculate the values. And there are fixed forms for all cases. But in my case, the array also will be generated from the list because examList is dynamic.

I assume I have problem with creating on the form or my approaches are wrong. Please help me to accomplish my objective generate total marks and creating Grade list. It would be appreciated. Thanks in advance.

Body:
Ok I can see that to meet your requirements you have to use nested arrays, you need to follow this structure, or at least a 2 d array,
grades[][]: grades[studentId][examId], you will understand more when you read the code, there is a lot missing in your code, for example the validations for the marks and the calculation for total and GP fields, I will not bother with these parts (I added a sample for calculation and validation, but you need to modify it), but I will show you how to populate your form group properly, and how to use it, having a dynamic view.
As I mention you need a 2d array, for me I went with more info, so I have an array of object, the object has 2 properties, one is student control (hold student id), and one is an array of grades for this student
here is the loop I used to populate my form group

createGradeForm(): void {
    this.gradeForm = this.formBuilder.group({
        gradeFields: this.formBuilder.array([])
    });
    //loop all students
    for (let b = 0; b < this.studentList.length; b++) {
    // create a form group to hold student data
        const userGroup = this.formBuilder.group({
            student: this.formBuilder.control(this.studentList[b].id),
            grades: this.formBuilder.array([])
        })
        //populate grades form array
        for (let i = 0; i < this.examList.length; i++) {
            //Bonus, I added a validator for you, max value is the mark, please apply min and other validations on your own.
            userGroup.get('grades').push(this.formBuilder.control('', [Validators.max(this.examList[i].marks)]));
        }
        // add the form group to your array
        this.gradeFields.push(userGroup);
    }
    //Check result here
    console.log(this.gradeFields);

}

For your view, you will have nested ng-for, one to loop students rows, and one to loop through your grades (columns)

<tbody>
    <!-- loop through the higher level array (students) -->
    <ng-container *ngFor="let student of gradeFields.controls; let i = index" formArrayName='gradeFields'>
        <ng-container [formGroupName]='i'>
            <tr>
                <th> {{ i + 1 }} </th>
                <-- this is student control -->
                <th> {{ student.get('student').value }} </th>
                <-- loop through your grades array -->
                <th *ngFor="let grade of student.get('grades').controls; let j = index" formArrayName="grades">
                    <-- bonus here, I added an example for validation, add style to your css for .inValid to see when invalid -->
                    <input [class.inValid]='!grade.valid' type="number" [formControlName]="j">
                </th>
                 <-- one more bonus, an example of calculation getTotal -->
                <th>{{getTotal(i)}}</th>
                <th>??</th>
                <th>??</th>
            </tr>
        </ng-container>
    </ng-container>
</tbody>

Get Total Function

//It takes the index of the student, get all grades, and accumlate them, the logic is wrong, please modify it, I just sum all grades, you have to add the logic
getTotal(ind) {
    const studentGrades = this.gradeFields.value[ind].grades;

    return studentGrades.reduce((a, b) => Number(a) + Number(b));
}

working stackblitz here

Read More about form arrays and reactive forms


问:
Pagination and manipulating lists in Rails 3
I need help with creating and paginating a list in Rails. I have three classes:

```<code>class User < ActiveRecord::Base
  has_many :rankings, :dependent => :destroy
  #...
  # has id, name, email, etc.
end

class Ranking < ActiveRecord::Base
  belongs_to :essay
  belongs_to :user
  #...
  #has comment, score, essay_id, user_id
end

class Essay < ActiveRecord::Base
  has_many :rankings, :dependent => :destroy
  #...
  #has id, body, author, etc.
end
</code>```

The Ranking class gets created as a review of each essay and then then get its essay_id and user_id set accordingly so we know who ranked which essay.

Now on the home page of the application I want to display a paginated list of all essays which the user has not ranked yet. I want as list of all the essays that the current_user has not raked. For all essays I simple do @essays = Essay.paginate(:page => params[:page]) but I want a particular subset of these. Do I need to create an array of the unranked essays?

答:
This is one suggestion, not using joins.

First get all the ids of essays the user has ranked

```<code>essay_ids = User.first.essay_ids
</code>```

Then get all essays not containing these ids ;)

```<code>@essays = Essay.where('id NOT IN (?)', essay_ids + [0])
</code>```

I like to add the extra 0, so that an empty array won't screw up the query.

You could plant this in a scope in Essay

```<code>scope :not_ranked_by_user, lambda {|user| where('id NOT IN (?)', user.essay_ids + [0]) }
</code>```

Body:
I need help with creating and paginating a list in Rails. I have three classes:

class User < ActiveRecord::Base
  has_many :rankings, :dependent => :destroy
  #...
  # has id, name, email, etc.
end

class Ranking < ActiveRecord::Base
  belongs_to :essay
  belongs_to :user
  #...
  #has comment, score, essay_id, user_id
end

class Essay < ActiveRecord::Base
  has_many :rankings, :dependent => :destroy
  #...
  #has id, body, author, etc.
end

The Ranking class gets created as a review of each essay and then then get its essay_id and user_id set accordingly so we know who ranked which essay.

Now on the home page of the application I want to display a paginated list of all essays which the user has not ranked yet. I want as list of all the essays that the current_user has not raked. For all essays I simple do @essays = Essay.paginate(:page => params[:page]) but I want a particular subset of these. Do I need to create an array of the unranked essays?

Body:
This is one suggestion, not using joins.

First get all the ids of essays the user has ranked

essay_ids = User.first.essay_ids

Then get all essays not containing these ids ;)

@essays = Essay.where('id NOT IN (?)', essay_ids + [0])

I like to add the extra 0, so that an empty array won't screw up the query.

You could plant this in a scope in Essay

scope :not_ranked_by_user, lambda {|user| where('id NOT IN (?)', user.essay_ids + [0]) }


问:
deeplink for .ics hosted file not opening in outlook mobile
I have to generate an ics file and upload to AWS S3 and use the S3 url(https://xyz.s3.aws.com/invite.ics) in the email as a hyperlink to download the ics file. The hyperlink in the generated email is not working in outlook mobile app(saying - 'Unable to launch event'), whereas the hyperlink is working in desktop app. In desktop if I click on the hyperlink, it open the browser and download the ics file from the S3.

ical file content

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//sebbo.net//ical-generator//EN
NAME:my first iCal
X-WR-CALNAME:my first iCal
BEGIN:VEVENT
UID:m8xj@gmail.com
SEQUENCE:0
DTSTAMP:20200528T070711Z
DTSTART:20200527T191500Z
DTEND:20200528T070711Z
SUMMARY:Appoinment
LOCATION:7 Hills
DESCRIPTION:Calendar event test. Refer email for more details
ORGANIZER;CN="Team MCE":mailto:noreply@message.com
END:VEVENT
END:VCALENDAR

答: Did you set the content-type to text/calendar as per https://www.rfc-editor.org/rfc/rfc5545#section-8.1 when uploading to S3 ?</p>