问:
RegEx remove part of string and and replace another part
I have a challenge getting the desired result with RegEx (using C#) and I hope that the community can help.

I have a URL in the following format:
https://somedomain.com/subfolder/category/?abc=text:value&ida=0&idb=1

I want make two modifications, specifically:

1) Remove everything after 'value' e.g. '&ida=0&idb=1'

2) Replace 'category' with e.g. 'newcategory'

So the result is:
https://somedomain.com/subfolder/newcategory/?abc=text:value

I can remove the string from 1) e.g. ^[^&]+ above but I have been unable to figure out how to replace the 'category' substring.

Any help or guidance would be much appreciated.

Thank you in advance.

答:
Using Python and only built-in string methods (there is no need for regular expressions here):

```<code>url = r"https://somedomain.com/subfolder/category/?abc=text:value&ida=0&idb=1"

new_url = (url.split('value')[0] + "value").replace("category", 'newcategory')

print(new_url)
</code>```

Outputs:

```<code>https://somedomain.com/subfolder/newcategory/?abc=text:value
</code>```

Body:
Using Python and only built-in string methods (there is no need for regular expressions here):

url = r"https://somedomain.com/subfolder/category/?abc=text:value&ida=0&idb=1"

new_url = (url.split('value')[0] + "value").replace("category", 'newcategory')

print(new_url)

Outputs:

https://somedomain.com/subfolder/newcategory/?abc=text:value


来源: stackexchange

问:
How to change the color of a QGraphicsRectItem
I can't find where I'm doing wrong. I want to change the color of my item (a QGraphicsRectItem) when a particular event occurs. The fact is that it seems that once the override paint method is called, the color won't change no matter what. This is a simplyfied code of what I've done:

item.h

```<code>class Item : public QGraphicsRectItem
{
public:
    Item(QGraphicsView *graphView);
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) override;

private:
    QPointF newPos;
    QGraphicsView *graph;
};
</code>```

item.cpp

```<code>Item::Item(QGraphicsView *graphWidget) : graph(graphWidget) { }

void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
     painter->setPen(Qt::NoPen);
     painter->setBrush(Qt::black);
     painter->drawEllipse(-7, -7, 20, 20);
}
</code>```

main.cpp

```<code>int main(int argc, char *argv[])
{
     srand(QDateTime::currentDateTime().toMSecsSinceEpoch());
     QApplication a(argc, argv);
     QGraphicsScene scene;
     QGraphicsView view(&scene);

     Item *item = new Item(&view);
     scene.addItem(item);
     item->setPos(0, 0);

     item->setBrush(Qt::red);
     item->update();

     view.show();
     return a.exec();
}
</code>```

答:
If I understand properly your question, the problem is that after item->setBrush(Qt::red), your circle is not being painter red. If this is the case, the problem is that you are forcing a specific pen (Qt::NoPen) and brush (Qt::red) in your paint function, and you are not using Item::pen() and Item::brush() to retrieve the information. Instead, you can do the following:

```<code>Item::Item(QGraphicsView *graphWidget) : graph(graphWidget)
{
  setPen(Qt::NoPen);
  setBrush(Qt::black);
}

void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
  Q_UNUSED(option);
  painter->setPen(pen());
  painter->setBrush(brush());
  painter->drawEllipse(-7, -7, 20, 20);
}
</code>```

This way, you define the default pen and brush in the constructor, but you can still change them using Item::setPen and Item::setBrush. Moreover, for this example you would be better inheriting QAbstractGraphicsShapeItem but then you have to implement Item::boundingRectfunction. The following example outputs a red circle (which is what I suspect you want to do) and also draw the contour with black (although it is not what you wanted, but to show that pen also changes):

```<code>#include <QApplication>
#include <QDateTime>
#include <QGraphicsRectItem>
#include <QGraphicsScene>
#include <QGraphicsView>

class Item : public QAbstractGraphicsShapeItem
{
public:
  Item(QGraphicsView *graphView);

  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) override;

  virtual QRectF boundingRect() const override;

private:
  QPointF newPos;
  QGraphicsView *graph;
};

Item::Item(QGraphicsView *graphWidget) : graph(graphWidget)
{
  setPen(Qt::NoPen);
  setBrush(Qt::black);
}

void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
  Q_UNUSED(option);
  painter->setPen(pen());
  painter->setBrush(brush());
  painter->drawEllipse(-7, -7, 20, 20);
}

QRectF Item::boundingRect() const
{
  double pw = pen().widthF() / 2;
  return QRectF(QPointF(-7 - pw, -7 - pw), QSizeF(20 + 2 * pw, 20 + 2 * pw));
}

int main(int argc, char *argv[])
{
  srand(QDateTime::currentDateTime().toMSecsSinceEpoch());
  QApplication a(argc, argv);
  QGraphicsScene scene;
  QGraphicsView view(&scene);

  Item *item = new Item(&view);
  scene.addItem(item);
  item->setPos(0, 0);

  item->setBrush(Qt::red);
  item->setPen(QPen(Qt::black));
  item->update();

  view.show();
  return a.exec();
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I can't find where I'm doing wrong. I want to change the color of my item (a QGraphicsRectItem) when a particular event occurs. The fact is that it seems that once the override paint method is called, the color won't change no matter what. This is a simplyfied code of what I've done:

item.h

class Item : public QGraphicsRectItem
{
public:
    Item(QGraphicsView *graphView);
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) override;

private:
    QPointF newPos;
    QGraphicsView *graph;
};

item.cpp

Item::Item(QGraphicsView *graphWidget) : graph(graphWidget) { }

void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
     painter->setPen(Qt::NoPen);
     painter->setBrush(Qt::black);
     painter->drawEllipse(-7, -7, 20, 20);
}

main.cpp

int main(int argc, char *argv[])
{
     srand(QDateTime::currentDateTime().toMSecsSinceEpoch());
     QApplication a(argc, argv);
     QGraphicsScene scene;
     QGraphicsView view(&scene);

     Item *item = new Item(&view);
     scene.addItem(item);
     item->setPos(0, 0);

     item->setBrush(Qt::red);
     item->update();

     view.show();
     return a.exec();
}

Body:
If I understand properly your question, the problem is that after item->setBrush(Qt::red), your circle is not being painter red. If this is the case, the problem is that you are forcing a specific pen (Qt::NoPen) and brush (Qt::red) in your paint function, and you are not using Item::pen() and Item::brush() to retrieve the information. Instead, you can do the following:

Item::Item(QGraphicsView *graphWidget) : graph(graphWidget)
{
  setPen(Qt::NoPen);
  setBrush(Qt::black);
}

void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
  Q_UNUSED(option);
  painter->setPen(pen());
  painter->setBrush(brush());
  painter->drawEllipse(-7, -7, 20, 20);
}

This way, you define the default pen and brush in the constructor, but you can still change them using Item::setPen and Item::setBrush. Moreover, for this example you would be better inheriting QAbstractGraphicsShapeItem but then you have to implement Item::boundingRectfunction. The following example outputs a red circle (which is what I suspect you want to do) and also draw the contour with black (although it is not what you wanted, but to show that pen also changes):

#include <QApplication>
#include <QDateTime>
#include <QGraphicsRectItem>
#include <QGraphicsScene>
#include <QGraphicsView>

class Item : public QAbstractGraphicsShapeItem
{
public:
  Item(QGraphicsView *graphView);

  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) override;

  virtual QRectF boundingRect() const override;

private:
  QPointF newPos;
  QGraphicsView *graph;
};

Item::Item(QGraphicsView *graphWidget) : graph(graphWidget)
{
  setPen(Qt::NoPen);
  setBrush(Qt::black);
}

void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
  Q_UNUSED(option);
  painter->setPen(pen());
  painter->setBrush(brush());
  painter->drawEllipse(-7, -7, 20, 20);
}

QRectF Item::boundingRect() const
{
  double pw = pen().widthF() / 2;
  return QRectF(QPointF(-7 - pw, -7 - pw), QSizeF(20 + 2 * pw, 20 + 2 * pw));
}

int main(int argc, char *argv[])
{
  srand(QDateTime::currentDateTime().toMSecsSinceEpoch());
  QApplication a(argc, argv);
  QGraphicsScene scene;
  QGraphicsView view(&scene);

  Item *item = new Item(&view);
  scene.addItem(item);
  item->setPos(0, 0);

  item->setBrush(Qt::red);
  item->setPen(QPen(Qt::black));
  item->update();

  view.show();
  return a.exec();
}


问:
Find a best practice for Business Intelligent data processing
I'm working in a system that manages human resources and it has a BI (Business Intelligent) part to collect and process data from main system, then visualize processed data into charts, tables, ..

For example, we want to see the relation between person age [in range 18 - 38] (in axis 1) and their monthly salary (in axis 2) [in full salary range]. The aggregation value is counting in person. There is also an additional step called Filter, to filter the result only in the organization A.

The expected result is like this:

```<code>                 Age_18<28   Age_28<38 Age_38<48
Salary_<1000         12          25       45
Salary_1000<5000     12          10       2
Salary_>5000         1           1        2
</code>```

The current processing steps are as below:

Search for axis1: Search all people with age range [18-38] in organization A

Search for axis2: Seach all people in in organization A

Merge results for axis1 and axis 2

Counting people for each condition,  for example number of people that has Age_18<28 AND Salary_<1000 is 12, and so on.

Convert to json response

Because there are a lot of cases to handle, the logic becomes complicated to maintain. All steps are handled manually like above.

So I just wonder if this is a common problem and should have a common way to handle, For example a design pattern, or algorithm, or library (Java) or a specific concept to handle such things that I never know before.

Target:
 - make code more simple, readable and maintainable
 - easy to extend, i.e add new cases

What I'm about to try:
- Apply chain of responsibility + strategy patterns
- Just wonder if Apache Kafka would be the right way

Note: the above is just a very simple case, it might contains multiple items in 1 axis, with some additional conditions

答:
One way to think of this is that you are accumulating counts in a 3 x 3 frequency table.

Write a simple method to map the salary to an index as follows:

```<code>  < 1000         => 0
  1000 to < 5000 => 1
  >= 5000        => 2
</code>```

There are various ways to code this method.

Write a simple method to map the age to an index as follows:

```<code>  18 to < 28     => 0
  28 to < 38     => 1
  38 to < 48     => 2
</code>```

Put it together like this:

```<code>  int counts[][] = new int[3][3];
  for each person: p in ...
      counts[ageIndex(p.age)]][salaryIndex(p.salary)] += 1;
</code>```

You could easily implement that in Java, and probably in SQL or in your BI system's query language as well .. if it has one.

You can generalize this to M x M, and more dimensions.  If you put it in bit of effort about it, you can actually implement the mappings as a data driven function; e.g.

```<code> public int mapToIndex(int value, int[] ranges) { ... }
</code>```

Note there is a flaw in what you are doing.  Employees could be younger than 18 or older than 48.

Body:
I'm working in a system that manages human resources and it has a BI (Business Intelligent) part to collect and process data from main system, then visualize processed data into charts, tables, ..

For example, we want to see the relation between person age [in range 18 - 38] (in axis 1) and their monthly salary (in axis 2) [in full salary range]. The aggregation value is counting in person. There is also an additional step called Filter, to filter the result only in the organization A.

The expected result is like this:

                 Age_18<28   Age_28<38 Age_38<48
Salary_<1000         12          25       45
Salary_1000<5000     12          10       2
Salary_>5000         1           1        2

The current processing steps are as below:

Search for axis1: Search all people with age range [18-38] in organization A

Search for axis2: Seach all people in in organization A

Merge results for axis1 and axis 2

Counting people for each condition,  for example number of people that has Age_18<28 AND Salary_<1000 is 12, and so on.

Convert to json response

Because there are a lot of cases to handle, the logic becomes complicated to maintain. All steps are handled manually like above.

So I just wonder if this is a common problem and should have a common way to handle, For example a design pattern, or algorithm, or library (Java) or a specific concept to handle such things that I never know before.

Target:
 - make code more simple, readable and maintainable
 - easy to extend, i.e add new cases

What I'm about to try:
- Apply chain of responsibility + strategy patterns
- Just wonder if Apache Kafka would be the right way

Note: the above is just a very simple case, it might contains multiple items in 1 axis, with some additional conditions

Body:
One way to think of this is that you are accumulating counts in a 3 x 3 frequency table.

Write a simple method to map the salary to an index as follows:

  < 1000         => 0
  1000 to < 5000 => 1
  >= 5000        => 2

There are various ways to code this method.

Write a simple method to map the age to an index as follows:

  18 to < 28     => 0
  28 to < 38     => 1
  38 to < 48     => 2

Put it together like this:

  int counts[][] = new int[3][3];
  for each person: p in ...
      counts[ageIndex(p.age)]][salaryIndex(p.salary)] += 1;

You could easily implement that in Java, and probably in SQL or in your BI system's query language as well .. if it has one.

You can generalize this to M x M, and more dimensions.  If you put it in bit of effort about it, you can actually implement the mappings as a data driven function; e.g.

 public int mapToIndex(int value, int[] ranges) { ... }

Note there is a flaw in what you are doing.  Employees could be younger than 18 or older than 48.


问:
Angular 9 Component Test: Export of name 'ngbNav' not found
I have a modal component which I would like to test.
But it is always complaining about "Export of name 'ngbNav' not found".
Any ideas would be great on how to solve this.

```<code>Error: Export of name 'ngbNav' not found!
        at cacheMatchingLocalNames (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13112:1)
        at resolveDirectives (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12871:1)
        at elementStartFirstCreatePass (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:21229:1)
        at ɵɵelementStart (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:21271:1)
        at TemplateModalComponent_Template (ng:///TemplateModalComponent.js:381:9)
        at executeTemplate (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12129:1)
        at renderView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11899:1)
        at renderComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13509:1)
        at renderChildComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11700:1)
        at renderView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11925:1)
</code>```

template-modal.component.html

```<code>    <div class="modal-header">
  <h4 class="modal-title" ngbTooltip="{{template ? template.id : ''}}" triggers="click:blur">{{"template_edit" | translate}}</h4>
  <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
    <span aria-hidden="true">×</span>
  </button>
</div>
<div class="modal-body">
  <form class="form" [formGroup]="this.templateFormGroup">
    <div formGroupName="template">
      <div class="row">
        <div class="col-md-6">
          <div class="form-group row">
            <label class="col-sm-3 col-form-label">Name</label>
            <div class="col-sm-9">
              <input type="text" class="form-control" name="name" formControlName="name" required/>
            </div>
          </div>
        </div>
        <div class="col-md-6">
          <div class="form-group row">
            <label class="col-sm-3 col-form-label">Instrument Type</label>
            <div class="col-sm-9">
              <input type="text" class="form-control" name="instrumentType" formControlName="instrumentType" value="DERIVATIVE" readonly />
            </div>
          </div>
        </div>
      </div>
      <div class="row" *ngIf="isStandardTemplate">
        <div class="col-md-6">
          <div class="form-group row">
            <label class="col-sm-3 col-form-label">Publisher</label>
            <div class="col-sm-9">
              <select class="form-control" formControlName="publisherId" (change)="resetAdvertiser()">
                <option [value]="null">{{"select-choose" | translate}}</option>
                <option [value]="p.id" *ngFor="let p of publisher | orderBy:'name'">{{p.name}}</option>
              </select>
            </div>
          </div>
        </div>
        <div class="col-md-6">
          <div class="form-group row">
            <label class="col-sm-3 col-form-label">Advertiser</label>
            <div class="col-sm-9">
              <select class="form-control" formControlName="advertiserId" (change)="resetPublisher()">
                <option [value]="null">{{"select-choose" | translate}}</option>
                <option [value]="a.id" *ngFor="let a of advertiser | orderBy:'name'">{{a.name}}</option>
              </select>
            </div>
          </div>
        </div>
      </div>
      <div class="row justify-content-end mb-3" *ngIf="!isStandardTemplate">
        <div class="col-3">
          <button class="btn btn-secondary form-control" (click)="createStandardTemplateModal()">Standard Templates</button>
        </div>
      </div>
      <ul ngbNav #nav="ngbNav" [(activeId)]="active" class="nav-tabs justify-content-center">
        <li [ngbNavItem]="1">
          <a ngbNavLink>Filter</a>
          <ng-template ngbNavContent>
            <ngb-alert type="secondary" *ngIf="!filter || filter.length == 0">Keine Filter vorhanden. Bitte anlegen!
            </ngb-alert>
            <div class="table-responsive" *ngIf="filter.length > 0">
              <table class="table">
                <thead>
                <tr>
                  <th>Name</th>
                  <th>Variable</th>
                  <th>{{"criteria" | translate}}</th>
                  <th>{{"comment" | translate}}</th>
                  <th></th>
                </tr>
                </thead>
                <tbody>
                <tr *ngFor="let f of filter | orderBy:'name'">
                  <td>{{f.name}}</td>
                  <td>{{f.templateVariableName}}</td>
                  <td><span class="badge badge-pill badge-secondary mr-1" *ngFor="let i of f.filterCriteria">
                      {{i.field}}
                      </span></td>
                  <td>{{f.comment}}</td>
                  <td>
                    <span class="prodo-icon prodo-delete-icon cursor-pointer float-right" (click)="deleteFilter(f.id)" ngbTooltip="{{'delete' | translate}}"></span>
                    <span class="prodo-icon prodo-edit-icon cursor-pointer float-right" *ngIf="f.id" ngbTooltip="{{'edit' | translate}}" (click)="chooseFilter(f.id)"></span>

                  </td>
                </tr>
                </tbody>
              </table>
            </div>
            <div class="row">
              <div class="col">
                <button type="button" class="btn btn-secondary"
                        (click)="newFilter()">{{"filter_new" | translate}}</button>
              </div>
            </div>
          </ng-template>
        </li>
        <li [ngbNavItem]="2">
          <a ngbNavLink>HTML-Template</a>
          <ng-template ngbNavContent>
            <div class="row">
              <div class="col-md-12">
                <editor formControlName="html" required name="html" [init]="tinyMceConfig"></editor>
              </div>
            </div>
          </ng-template>
        </li>
        <li [ngbNavItem]="3">
          <a ngbNavLink>{{"disclaimer_page_end" | translate}}</a>
          <ng-template ngbNavContent>
            <div class="row">
              <div class="col-md-12">
                <editor formControlName="disclaimer" name="disclaimer" [init]="tinyMceConfig">
                </editor>
              </div>
            </div>
          </ng-template>
        </li>
        <li [ngbNavItem]="4">
          <a ngbNavLink>{{"disclaimer_at_ad" | translate}}</a>
          <ng-template ngbNavContent>
            <div class="row">
              <div class="col-md-12">
                <editor formControlName="disclaimerJson" name="disclaimerJson" [init]="tinyMceConfig">
                </editor>
              </div>
            </div>
          </ng-template>
        </li>
      </ul>
    </div>
  </form>
  <div [ngbNavOutlet]="nav" class="mt-2"></div>

</div>
<div class="modal-footer">
  <button type="button" class="btn btn-light" (click)="activeModal.dismiss()">Close</button>
  <button type="button" class="btn btn-success" (click)="passBack()" [disabled]="!templateFormGroup.valid">Speichern
  </button>
</div>
</code>```

template-modal.component.ts

```<code>import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {NgbActiveModal, NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
import {StandardTemplateModalComponent} from "./standard-template-modal/standard-template-modal.component";
import {FilterModalComponent} from "./filter-modal/filter-modal.component";
import {Filter} from "../../../model/filter.model";
import {Publisher} from "../../../model/publisher.model";
import {Advertiser} from "../../../model/advertiser.model";
import {Template} from "../../../model/template.model";
import {PublisherService} from "../../../services/publisher.service";
import {AdvertiserService} from "../../../services/advertiser.service";
import {FilterService} from "../../../services/filter.service";
import {TemplateService} from "../../../services/template.service";
import {InstrumentAttributeService} from "../../../services/instrument-attribute.service";
import {StandardTemplate} from "../../../model/standard-template.model";

@Component({
  selector: 'app-template-modal',
  templateUrl: './template-modal.component.html',
  styleUrls: ['./template-modal.component.scss']
})
export class TemplateModalComponent implements OnInit {

  @Input()
  public template;
  @Input()
  advertisementId: string;
  @Input()
  isStandardTemplate: boolean;

  filter: Filter[] = [];
  publisher: Publisher[];
  advertiser: Advertiser[];
  standardTemplates: Template[];
  templateFormGroup: FormGroup;
  usedInstrumentTypesInFilter: string[];
  fieldsOfInstrumentType: any[] = new Array<string>();
  tinyMceConfig: any;

  @Output() passEntry: EventEmitter<any> = new EventEmitter();
  active = 1;

  constructor(
    public activeModal: NgbActiveModal,
    public publisherService: PublisherService,
    public advertiserService: AdvertiserService,
    private filterService: FilterService,
    private templateService: TemplateService,
    private instrumentAttributeService: InstrumentAttributeService,
    private fb: FormBuilder,
    private modalService: NgbModal) {
  }

  ngOnInit() {
    this.loadData();
    this.configureTinyMce();
  }

  createFormGroup() {
    return this.fb.group({
        template: this.fb.group(this.template),
        standardTemplate: new FormControl('')
      }
    );
  }

  loadData() {
    this.publisherService.get().subscribe((data: Publisher[]) => { this.publisher = data; });
    this.advertiserService.get().subscribe((data: Advertiser[]) => { this.advertiser = data; });
    if (!this.isStandardTemplate) {
      this.templateService.getSuitableStandardTemplates(this.advertisementId)
        .subscribe( data => {
          this.standardTemplates = data;
        });
    }
    this.templateFormGroup = this.createFormGroup();
    this.filterService.get(this.template.id)
      .subscribe( data => {

        this.filter = data;
        this.usedInstrumentTypesInFilter = this.filter.map( f => f.zertartId).filter((el, i, a) => i === a.indexOf(el));

        for ( const instrumentType of this.usedInstrumentTypesInFilter) {
          this.filterService.getFilterCriteria(instrumentType).subscribe( fields => {
            this.fieldsOfInstrumentType[instrumentType] = fields;
          });
        }
      });
  }

  createStandardTemplateModal() {
    const modalRef = this.modalService.open(StandardTemplateModalComponent, { centered: true, size: 'lg' });
    modalRef.componentInstance.advertisementId = this.advertisementId;
    modalRef.result.then((result: StandardTemplate) => {
      if (result) {
        // Updating form with values from Standard Template
        this.templateFormGroup.get("template").patchValue(result);
        // Result Object for saving
        const template = this.createTemplateResult();
        this.templateService.putTemplate(this.advertisementId, template).subscribe( t => {
          // Template is saved, now fetch all filter and add them to the template
          this.filterService.get(result.id).subscribe( data => {
            for (const f of data) {
              // setting the new template id of the filter and remove its id, as it will receive a new one
              f.abstractTemplateId = t.id;
              f.id = null;
              this.filterService.post(f).subscribe( _ => this.activeModal.close() );
            }
          });
        });
      }
    });
  }

  newFilter() {
    const modalRef = this.modalService.open(FilterModalComponent, { centered: true, size: 'xl' });
    modalRef.componentInstance._templateId = this.template.id;
    modalRef.result.then((result: Filter) => {
      if (result) {
        this.filterService.post(result).subscribe(_ => {
          this.loadData();
        });
      }
    });
  }

  deleteFilter(filterId: string) {
    this.filterService.delete(filterId).subscribe( _ => {
      this.loadData();
    });
  }

  chooseFilter(filterId: string) {
    const modalRef = this.modalService.open(FilterModalComponent, { centered: true, size: 'xl' });
    modalRef.componentInstance.filterId = filterId;
    modalRef.result.then((result: Filter) => {
      if (result) {
        this.filterService.put(filterId, result).subscribe(_ => {
          this.loadData();
        });
      }
    });
  }

  configureTinyMce() {
    const that = this;

    this.tinyMceConfig = {
      menubar: false,
      branding: false,
      height: 300,
      base_url: '/tinymce',
      suffix: '.min',
      inline: false,
      valid_elements: '*[*]',
      plugins: [
        'advlist lists link image directionality',
        'searchreplace visualblocks visualchars media table paste pagebreak code'
      ],
      toolbar: 'filterbutton filterIterationButton | undo redo formatselect table | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat hr pagebreak code',
      table_resize_bars: false,
      setup: function (editor) {
        const test = that.filter.map(f => {
          if ( f.maximumNumberOfResults <= 1) {
            return {
              type: 'nestedmenuitem',
              text: f.templateVariableName,
              icon: 'template',
              getSubmenuItems: function () {
                return f.allowedFields.map(field => {
                  return {
                    type: 'menuitem',
                    text: field,
                    icon: 'paste-text',
                    onAction: function () {
                      editor.insertContent(
                        '<span th:text="${' + f.templateVariableName + '.' + field + '}">' + f.templateVariableName + '.' + field + '</span>'
                      );
                    }
                  };
                });
              }
            };
          } else {
            return [];
          }
        });
        const filterIteration = that.filter.map(f => {
          if (f.maximumNumberOfResults > 1) {
            return {
              type: 'nestedmenuitem',
              text: f.templateVariableName,
              icon: 'template',
              getSubmenuItems: function() {
                const filterWithMultipleResults = (element: Filter) => element.maximumNumberOfResults > 1;
                if ( that.filter.some(filterWithMultipleResults) ) {
                  return f.allowedFields.map( field => { return {
                    type: 'menuitem',
                    text: field,
                    icon: 'paste-text',
                    onAction: function () {
                      const iteration =
                        '<table>' +
                        '<tr th:each="item: ${' + f.templateVariableName + '}">' +
                        '<td th:text="${item.' + field + '}" />' +
                        '</tr>' +
                        '</table>';
                      console.log("inserting:");
                      console.log(iteration);
                      editor.insertContent(iteration);

                    }
                  }; });
                } else {
                  return [];
                }

              }
            };
          } else {
            return [];
          }

        });
        /* example, adding a toolbar menu button */
        editor.ui.registry.addMenuButton('filterbutton', {
          text: 'Filter',
          fetch: function (callback) {
            callback(test);
          }
        });
        editor.ui.registry.addMenuButton('filterIterationButton', {
          text: 'Filter Iteration',
          fetch: function (callback) {
            callback(filterIteration);
          }
        });
      },
      image_advtab: true,
      imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions',
      paste_data_images: !0,
      importcss_append: !0,
      images_upload_handler: function (e, t, a) {
        t('data:' + e.blob().type + ';base64,' + e.base64());
      },
    };
  }

  resetAdvertiser() {
    this.templateFormGroup.get("template").get("advertiserId").reset();
  }

  resetPublisher() {
    this.templateFormGroup.get("template").get("publisherId").reset();
  }

  createTemplateResult() {
    let result;
    if (this.isStandardTemplate) {
      result =  Object.assign({}, this.templateFormGroup.get('template').value) as StandardTemplate;
    } else {
      result =  Object.assign({}, this.templateFormGroup.get('template').value) as Template;
    }
    result = Object.assign({}, result);
    return result;
  }

  passBack() {
    const result = this.createTemplateResult();
    this.activeModal.close(result);
  }

}
</code>```

In my test file I am going this way:

```<code>import {async, TestBed} from '@angular/core/testing';

import {TemplateModalComponent} from './template-modal.component';
import {HttpClient} from "@angular/common/http";
import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing";
import {RouterTestingModule} from "@angular/router/testing";
import {TranslateLoader, TranslateModule} from "@ngx-translate/core";
import {HttpLoaderFactory} from "../../../app.module";
import {FormBuilder, FormsModule, NgForm} from "@angular/forms";
import {NgbActiveModal, NgbModal, NgbNav, NgbNavConfig} from "@ng-bootstrap/ng-bootstrap";
import {AdslotService} from "../../../services/adslot.service";
import {ErrorHandlingService} from "../../../services/error-handling.service";
import {ToastService} from "../../../services/toast.service";

describe('TemplateModalComponent', () => {
  let httpClient: HttpClient;
  let httpTestingController: HttpTestingController;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
          }
        }),
      ],
      declarations: [ TemplateModalComponent ],
      providers: [
        FormsModule,
        NgbActiveModal,
        AdslotService,
        ErrorHandlingService,
        ToastService,
        FormBuilder,
      ]
    }).compileComponents();
    // Inject the http service and test controller for each test
    httpClient = TestBed.get(HttpClient);
    httpTestingController = TestBed.get(HttpTestingController);

  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(TemplateModalComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  });
});
</code>```

I really appreciate any hints or helping steps to debug this.
Cheers Maik

答:
You should import NgbNavModule</p>

```<code>imports: [NgbNavModule],
</code>```

Body:
I have a modal component which I would like to test.
But it is always complaining about "Export of name 'ngbNav' not found".
Any ideas would be great on how to solve this.

Error: Export of name 'ngbNav' not found!
        at cacheMatchingLocalNames (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13112:1)
        at resolveDirectives (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12871:1)
        at elementStartFirstCreatePass (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:21229:1)
        at ɵɵelementStart (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:21271:1)
        at TemplateModalComponent_Template (ng:///TemplateModalComponent.js:381:9)
        at executeTemplate (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12129:1)
        at renderView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11899:1)
        at renderComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13509:1)
        at renderChildComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11700:1)
        at renderView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11925:1)

template-modal.component.html

{{"template_edit" | translate}}

  <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
    ×
  </button>

  <form class="form" [formGroup]="this.templateFormGroup">

            Name

              <input type="text" class="form-control" name="name" formControlName="name" required/>

            Instrument Type

              <input type="text" class="form-control" name="instrumentType" formControlName="instrumentType" value="DERIVATIVE" readonly />

            Publisher

              <select class="form-control" formControlName="publisherId" (change)="resetAdvertiser()">
                <option [value]="null">{{"select-choose" | translate}}</option>
                <option [value]="p.id" *ngFor="let p of publisher | orderBy:'name'">{{p.name}}</option>
              </select>

            Advertiser

              <select class="form-control" formControlName="advertiserId" (change)="resetPublisher()">
                <option [value]="null">{{"select-choose" | translate}}</option>
                <option [value]="a.id" *ngFor="let a of advertiser | orderBy:'name'">{{a.name}}</option>
              </select>

          <button class="btn btn-secondary form-control" (click)="createStandardTemplateModal()">Standard Templates</button>

          Filter
          <ng-template ngbNavContent>
            <ngb-alert type="secondary" *ngIf="!filter || filter.length == 0">Keine Filter vorhanden. Bitte anlegen!
            </ngb-alert>

 0">

                  Name
                  Variable
                  {{"criteria" | translate}}
                  {{"comment" | translate}}

                  {{f.name}}
                  {{f.templateVariableName}}

                      {{i.field}}

                  {{f.comment}}

                <button type="button" class="btn btn-secondary"
                        (click)="newFilter()">{{"filter_new" | translate}}</button>

          </ng-template>

          HTML-Template
          <ng-template ngbNavContent>

                <editor formControlName="html" required name="html" [init]="tinyMceConfig"></editor>

          </ng-template>

          {{"disclaimer_page_end" | translate}}
          <ng-template ngbNavContent>

                <editor formControlName="disclaimer" name="disclaimer" [init]="tinyMceConfig">
                </editor>

          </ng-template>

          {{"disclaimer_at_ad" | translate}}
          <ng-template ngbNavContent>

                <editor formControlName="disclaimerJson" name="disclaimerJson" [init]="tinyMceConfig">
                </editor>

          </ng-template>

  </form>

  <button type="button" class="btn btn-light" (click)="activeModal.dismiss()">Close</button>
  <button type="button" class="btn btn-success" (click)="passBack()" [disabled]="!templateFormGroup.valid">Speichern
  </button>

template-modal.component.ts

import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {NgbActiveModal, NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
import {StandardTemplateModalComponent} from "./standard-template-modal/standard-template-modal.component";
import {FilterModalComponent} from "./filter-modal/filter-modal.component";
import {Filter} from "../../../model/filter.model";
import {Publisher} from "../../../model/publisher.model";
import {Advertiser} from "../../../model/advertiser.model";
import {Template} from "../../../model/template.model";
import {PublisherService} from "../../../services/publisher.service";
import {AdvertiserService} from "../../../services/advertiser.service";
import {FilterService} from "../../../services/filter.service";
import {TemplateService} from "../../../services/template.service";
import {InstrumentAttributeService} from "../../../services/instrument-attribute.service";
import {StandardTemplate} from "../../../model/standard-template.model";

@Component({
  selector: 'app-template-modal',
  templateUrl: './template-modal.component.html',
  styleUrls: ['./template-modal.component.scss']
})
export class TemplateModalComponent implements OnInit {

  @Input()
  public template;
  @Input()
  advertisementId: string;
  @Input()
  isStandardTemplate: boolean;

  filter: Filter[] = [];
  publisher: Publisher[];
  advertiser: Advertiser[];
  standardTemplates: Template[];
  templateFormGroup: FormGroup;
  usedInstrumentTypesInFilter: string[];
  fieldsOfInstrumentType: any[] = new Array<string>();
  tinyMceConfig: any;

  @Output() passEntry: EventEmitter<any> = new EventEmitter();
  active = 1;

  constructor(
    public activeModal: NgbActiveModal,
    public publisherService: PublisherService,
    public advertiserService: AdvertiserService,
    private filterService: FilterService,
    private templateService: TemplateService,
    private instrumentAttributeService: InstrumentAttributeService,
    private fb: FormBuilder,
    private modalService: NgbModal) {
  }

  ngOnInit() {
    this.loadData();
    this.configureTinyMce();
  }

  createFormGroup() {
    return this.fb.group({
        template: this.fb.group(this.template),
        standardTemplate: new FormControl('')
      }
    );
  }

  loadData() {
    this.publisherService.get().subscribe((data: Publisher[]) => { this.publisher = data; });
    this.advertiserService.get().subscribe((data: Advertiser[]) => { this.advertiser = data; });
    if (!this.isStandardTemplate) {
      this.templateService.getSuitableStandardTemplates(this.advertisementId)
        .subscribe( data => {
          this.standardTemplates = data;
        });
    }
    this.templateFormGroup = this.createFormGroup();
    this.filterService.get(this.template.id)
      .subscribe( data => {

        this.filter = data;
        this.usedInstrumentTypesInFilter = this.filter.map( f => f.zertartId).filter((el, i, a) => i === a.indexOf(el));

        for ( const instrumentType of this.usedInstrumentTypesInFilter) {
          this.filterService.getFilterCriteria(instrumentType).subscribe( fields => {
            this.fieldsOfInstrumentType[instrumentType] = fields;
          });
        }
      });
  }

  createStandardTemplateModal() {
    const modalRef = this.modalService.open(StandardTemplateModalComponent, { centered: true, size: 'lg' });
    modalRef.componentInstance.advertisementId = this.advertisementId;
    modalRef.result.then((result: StandardTemplate) => {
      if (result) {
        // Updating form with values from Standard Template
        this.templateFormGroup.get("template").patchValue(result);
        // Result Object for saving
        const template = this.createTemplateResult();
        this.templateService.putTemplate(this.advertisementId, template).subscribe( t => {
          // Template is saved, now fetch all filter and add them to the template
          this.filterService.get(result.id).subscribe( data => {
            for (const f of data) {
              // setting the new template id of the filter and remove its id, as it will receive a new one
              f.abstractTemplateId = t.id;
              f.id = null;
              this.filterService.post(f).subscribe( _ => this.activeModal.close() );
            }
          });
        });
      }
    });
  }

  newFilter() {
    const modalRef = this.modalService.open(FilterModalComponent, { centered: true, size: 'xl' });
    modalRef.componentInstance._templateId = this.template.id;
    modalRef.result.then((result: Filter) => {
      if (result) {
        this.filterService.post(result).subscribe(_ => {
          this.loadData();
        });
      }
    });
  }

  deleteFilter(filterId: string) {
    this.filterService.delete(filterId).subscribe( _ => {
      this.loadData();
    });
  }

  chooseFilter(filterId: string) {
    const modalRef = this.modalService.open(FilterModalComponent, { centered: true, size: 'xl' });
    modalRef.componentInstance.filterId = filterId;
    modalRef.result.then((result: Filter) => {
      if (result) {
        this.filterService.put(filterId, result).subscribe(_ => {
          this.loadData();
        });
      }
    });
  }

  configureTinyMce() {
    const that = this;

    this.tinyMceConfig = {
      menubar: false,
      branding: false,
      height: 300,
      base_url: '/tinymce',
      suffix: '.min',
      inline: false,
      valid_elements: '*[*]',
      plugins: [
        'advlist lists link image directionality',
        'searchreplace visualblocks visualchars media table paste pagebreak code'
      ],
      toolbar: 'filterbutton filterIterationButton | undo redo formatselect table | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat hr pagebreak code',
      table_resize_bars: false,
      setup: function (editor) {
        const test = that.filter.map(f => {
          if ( f.maximumNumberOfResults <= 1) {
            return {
              type: 'nestedmenuitem',
              text: f.templateVariableName,
              icon: 'template',
              getSubmenuItems: function () {
                return f.allowedFields.map(field => {
                  return {
                    type: 'menuitem',
                    text: field,
                    icon: 'paste-text',
                    onAction: function () {
                      editor.insertContent(
                        '' + f.templateVariableName + '.' + field + ''
                      );
                    }
                  };
                });
              }
            };
          } else {
            return [];
          }
        });
        const filterIteration = that.filter.map(f => {
          if (f.maximumNumberOfResults > 1) {
            return {
              type: 'nestedmenuitem',
              text: f.templateVariableName,
              icon: 'template',
              getSubmenuItems: function() {
                const filterWithMultipleResults = (element: Filter) => element.maximumNumberOfResults > 1;
                if ( that.filter.some(filterWithMultipleResults) ) {
                  return f.allowedFields.map( field => { return {
                    type: 'menuitem',
                    text: field,
                    icon: 'paste-text',
                    onAction: function () {
                      const iteration =
                        '
' +
                        '
' +
                        '' +
                        '
' +
                        '
';
                      console.log("inserting:");
                      console.log(iteration);
                      editor.insertContent(iteration);

                    }
                  }; });
                } else {
                  return [];
                }

              }
            };
          } else {
            return [];
          }

        });
        /* example, adding a toolbar menu button */
        editor.ui.registry.addMenuButton('filterbutton', {
          text: 'Filter',
          fetch: function (callback) {
            callback(test);
          }
        });
        editor.ui.registry.addMenuButton('filterIterationButton', {
          text: 'Filter Iteration',
          fetch: function (callback) {
            callback(filterIteration);
          }
        });
      },
      image_advtab: true,
      imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions',
      paste_data_images: !0,
      importcss_append: !0,
      images_upload_handler: function (e, t, a) {
        t('data:' + e.blob().type + ';base64,' + e.base64());
      },
    };
  }

  resetAdvertiser() {
    this.templateFormGroup.get("template").get("advertiserId").reset();
  }

  resetPublisher() {
    this.templateFormGroup.get("template").get("publisherId").reset();
  }

  createTemplateResult() {
    let result;
    if (this.isStandardTemplate) {
      result =  Object.assign({}, this.templateFormGroup.get('template').value) as StandardTemplate;
    } else {
      result =  Object.assign({}, this.templateFormGroup.get('template').value) as Template;
    }
    result = Object.assign({}, result);
    return result;
  }

  passBack() {
    const result = this.createTemplateResult();
    this.activeModal.close(result);
  }

}

In my test file I am going this way:

import {async, TestBed} from '@angular/core/testing';

import {TemplateModalComponent} from './template-modal.component';
import {HttpClient} from "@angular/common/http";
import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing";
import {RouterTestingModule} from "@angular/router/testing";
import {TranslateLoader, TranslateModule} from "@ngx-translate/core";
import {HttpLoaderFactory} from "../../../app.module";
import {FormBuilder, FormsModule, NgForm} from "@angular/forms";
import {NgbActiveModal, NgbModal, NgbNav, NgbNavConfig} from "@ng-bootstrap/ng-bootstrap";
import {AdslotService} from "../../../services/adslot.service";
import {ErrorHandlingService} from "../../../services/error-handling.service";
import {ToastService} from "../../../services/toast.service";

describe('TemplateModalComponent', () => {
  let httpClient: HttpClient;
  let httpTestingController: HttpTestingController;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
          }
        }),
      ],
      declarations: [ TemplateModalComponent ],
      providers: [
        FormsModule,
        NgbActiveModal,
        AdslotService,
        ErrorHandlingService,
        ToastService,
        FormBuilder,
      ]
    }).compileComponents();
    // Inject the http service and test controller for each test
    httpClient = TestBed.get(HttpClient);
    httpTestingController = TestBed.get(HttpTestingController);

  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(TemplateModalComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  });
});

I really appreciate any hints or helping steps to debug this.
Cheers Maik

Body:
You should import NgbNavModule

imports: [NgbNavModule],


问:
Frustrating TCP Serialization Exception: Binary stream '0' does not contain a valid BinaryHeader
I posted a question on how to send large objects over TCP and it seems like the primary issue is solved, but now frequently I get another exception:

Binary stream '0' does not contain a
valid BinaryHeader. Possible causes
are invalid stream or object version
change between serialization and
deserialization.

The issue is still in my Receive method:

```<code>public Message Receive()
{
    if (_tcpClient == null || !_tcpClient.Connected)
    {
        throw new TransportException("Client Not Connected");
    }

    // buffers
    byte[] msgBuffer;
    byte[] sizeBuffer = new byte[sizeof(int)];

    // bites read
    int readSize = 0;
    // message size
    int size = 0;

    MemoryStream memStream = new MemoryStream();
    NetworkStream netStream = _tcpClient.GetStream();
    BinaryFormatter formatter = new BinaryFormatter();
    try
    {
        // Read the message length
        netStream.Read(sizeBuffer, 0, sizeof(int));

        // Extract the message length
        size = BitConverter.ToInt32(sizeBuffer, 0);
        msgBuffer = new byte[size];

        // Fill up the message msgBuffer
        do
        {
            // Clear the buffer
            Array.Clear(msgBuffer, 0, size);

            // Read the message
            readSize += netStream.Read(msgBuffer, 0, _tcpClient.ReceiveBufferSize);

            // Write the msgBuffer to the memory streamvb
            memStream.Write(msgBuffer, 0, readSize);

        } while (readSize < size);

        // Reset the memory stream position
        memStream.Position = 0;

        // Deserialize the message
        return (Message)formatter.Deserialize(memStream); // <-- Exception here

    }
    catch (System.Exception e)
    {
        if (_tcpClient == null || !_tcpClient.Connected)
        {
            throw new TransportException("Client Not Connected");
        }
        else
        {
            throw e;
        }
    }
}
</code>```

The rest of the code relevant to this example can be found in my original question.

Does anybody know what is causing this exception and how I can avoid it?

Update

Changed the Read to read a maximum of _tcpClient.ReceiveBufferSize bytes at a time, rather than trying to read the full message size (which can be larger than the buffer size) and while the frequency of the Exception decreased slightly, it's still occurring quite often.

答: WCF not so good in client-server. Th polling duplex is quite raw technology.</p>

ContentLicense: CC BY-SA 2.5

Body:
I posted a question on how to send large objects over TCP and it seems like the primary issue is solved, but now frequently I get another exception:

Binary stream '0' does not contain a
valid BinaryHeader. Possible causes
are invalid stream or object version
change between serialization and
deserialization.

The issue is still in my Receive method:

public Message Receive()
{
    if (_tcpClient == null || !_tcpClient.Connected)
    {
        throw new TransportException("Client Not Connected");
    }

    // buffers
    byte[] msgBuffer;
    byte[] sizeBuffer = new byte[sizeof(int)];

    // bites read
    int readSize = 0;
    // message size
    int size = 0;

    MemoryStream memStream = new MemoryStream();
    NetworkStream netStream = _tcpClient.GetStream();
    BinaryFormatter formatter = new BinaryFormatter();
    try
    {
        // Read the message length
        netStream.Read(sizeBuffer, 0, sizeof(int));

        // Extract the message length
        size = BitConverter.ToInt32(sizeBuffer, 0);
        msgBuffer = new byte[size];

        // Fill up the message msgBuffer
        do
        {
            // Clear the buffer
            Array.Clear(msgBuffer, 0, size);

            // Read the message
            readSize += netStream.Read(msgBuffer, 0, _tcpClient.ReceiveBufferSize);

            // Write the msgBuffer to the memory streamvb
            memStream.Write(msgBuffer, 0, readSize);

        } while (readSize < size);

        // Reset the memory stream position
        memStream.Position = 0;

        // Deserialize the message
        return (Message)formatter.Deserialize(memStream); // <-- Exception here

    }
    catch (System.Exception e)
    {
        if (_tcpClient == null || !_tcpClient.Connected)
        {
            throw new TransportException("Client Not Connected");
        }
        else
        {
            throw e;
        }
    }
}

The rest of the code relevant to this example can be found in my original question.

Does anybody know what is causing this exception and how I can avoid it?

Update

Changed the Read to read a maximum of _tcpClient.ReceiveBufferSize bytes at a time, rather than trying to read the full message size (which can be larger than the buffer size) and while the frequency of the Exception decreased slightly, it's still occurring quite often.

ContentLicense: CC BY-SA 3.0


问:
AWS Amplify S3 Protected File - Lambda Function Invocation
I have a file saved as a 'protected' file in a S3 bucket. I have setup (through CLI) a lambda function to trigger when a file is added to the bucket. Lambda function works as intended for the public files. However for the protected files, when  i try to access the file via the lambda function (s3.GetObject), i'm getting the following error:

An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist.

I have the relevant policies setup to gain access to the S3 bucket and right now pretty much exhausted all the options. Really appreciate someone point me at the right direction.

答:
Found what's causing the issue. The 'folder' in the bucket contained a ':'. When the bucket name and key passed into the lambda trigger, it was encoded. So the ':' turned to a %3A hence the NoSuchKey error.

In order to address that, i've decoded the key back to normal form in python.


问:
Overwrite django choices output in graphene
I'm working with graphene and graphene-django and I have a problem with a IntegerField with choices. graphene create an Enum and the output is "A_1" if the value is 1; "A_2" if the value is 2 and so on. Example:

```<code># model
class Foo(models.Model):
    score = models.IntegerField(choices=((1, 1), (2, 2), (3, 3), (4, 4), (5, 5)))

# query

query {
    foo {
       score
    }
}

# response

{
  "data": {
    "foo": {
      "source": "A_1"
    }
  }
}
</code>```

I found a function that convert the choices values.

```<code>def convert_choice_name(name):
    name = to_const(force_text(name))
    try:
        assert_valid_name(name)
    except AssertionError:
        name = "A_%s" % name
    return name
</code>```

And assert_valid_name has this regular expression:

```<code>r'^[_a-zA-Z][_a-zA-Z0-9]*$'
</code>```

Therefore, whatever begins with number, it will convert it to "A_...".

How I can overwrite this output?

答:
Having just bumped into this myself, an alternate is to define your field outside of the Meta (use only_fields) as just a graphene.Int , then you can provide your own resolver function and just return the value of the field, which will end up as a number.

My code snippet (the problem field was resource_type which is the Enum):

```<code>class ResourceItem(DjangoObjectType):
    class Meta:
        model = Resource
        only_fields = (
            "id",
            "title",
            "description",
            "icon",
            "target",
            "session_reveal",
            "metadata",
            "payload",
        )

    resource_type = graphene.Int()

    def resolve_resource_type(self, info):
        return self.resource_type
</code>```

Body:
I'm working with graphene and graphene-django and I have a problem with a IntegerField with choices. graphene create an Enum and the output is "A_1" if the value is 1; "A_2" if the value is 2 and so on. Example:

# model
class Foo(models.Model):
    score = models.IntegerField(choices=((1, 1), (2, 2), (3, 3), (4, 4), (5, 5)))

# query

query {
    foo {
       score
    }
}

# response

{
  "data": {
    "foo": {
      "source": "A_1"
    }
  }
}

I found a function that convert the choices values.

def convert_choice_name(name):
    name = to_const(force_text(name))
    try:
        assert_valid_name(name)
    except AssertionError:
        name = "A_%s" % name
    return name

And assert_valid_name has this regular expression:

r'^[_a-zA-Z][_a-zA-Z0-9]*$'

Therefore, whatever begins with number, it will convert it to "A_...".

How I can overwrite this output?

Body:
Having just bumped into this myself, an alternate is to define your field outside of the Meta (use only_fields) as just a graphene.Int , then you can provide your own resolver function and just return the value of the field, which will end up as a number.

My code snippet (the problem field was resource_type which is the Enum):

class ResourceItem(DjangoObjectType):
    class Meta:
        model = Resource
        only_fields = (
            "id",
            "title",
            "description",
            "icon",
            "target",
            "session_reveal",
            "metadata",
            "payload",
        )

    resource_type = graphene.Int()

    def resolve_resource_type(self, info):
        return self.resource_type


问:
angular component, check if attribute exists
Say I have an angular component ie <this-thing></this-thing> which does it's thing.

Now I want to add something extra to it, ie <this-thing glows></this-thing>
I would like the component to change a little if the glow attribute is there.

I have managed to do it via <this-thing [glows]="true"></this-thing> and in the component I have

```<code>@Input() public set glows(value: boolean) {
    console.log(value);
}
</code>```

But that becomes too verbose.

If glows attribute is not on the component, then it's false and if it is, then true.

Is there a better way to acheive this?

Thanks for looking.

答:
use @Attribute and @optional in constructor see the docs

```<code>constructor(@Optional() @Attribute('glow') glow: any) {
  console.log(glow)
  console.log(glow==undefined)
}

<hello glow></hello> //give you '',false
<hello></hello> //give you null,true
</code>```

Body:
Say I have an angular component ie <this-thing></this-thing> which does it's thing.

Now I want to add something extra to it, ie <this-thing glows></this-thing>
I would like the component to change a little if the glow attribute is there.

I have managed to do it via <this-thing [glows]="true"></this-thing> and in the component I have

@Input() public set glows(value: boolean) {
    console.log(value);
}

But that becomes too verbose.

If glows attribute is not on the component, then it's false and if it is, then true.

Is there a better way to acheive this?

Thanks for looking.

Body:
use @Attribute and @optional in constructor see the docs

constructor(@Optional() @Attribute('glow') glow: any) {
  console.log(glow)
  console.log(glow==undefined)
}

<hello glow></hello> //give you '',false
<hello></hello> //give you null,true


问:
How to send a HTML email with attachment using MailApp in Google Apps Script?
I'm trying write code in Google Apps Script to send a HTML email with an attachment to a list of my contacts.
The main error I recieve is with the line

```<code>    MailApp.sendEmail(
    emailid[i],
    "test email",
    Message,
    htmlBody: HtmlMessage,
    attachments: [file.getAs(MimeType.PDF)]
    );
</code>```

The error is with reference to htmlBody: HtmlMessage : SyntaxError: missing ) after argument list (line 48, file "Code.gs")

I have tried other methods online including

```<code>    MailApp.sendEmail({
    to: emailid[i],
    subject: "This is a test email",
    htmlBody: HtmlMessage,
    attachments: [file.getAs(MimeType.PDF)]
  });
</code>```

I get the error : Exception: Invalid email: [Ljava.lang.Object;@1456304b (line 51, file "Code")

The entire Code :

```<code>function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();

  //BASIC DETAILS
  var name = sheet.getRange(1, 1, 3).getValues();
  var emailid = sheet.getRange(1, 2, 3).getValues();
  var company = sheet.getRange(1, 3, 3).getValues();

  //ATTACHMENTS
  var file = DriveApp.getFileById('XXXXXXXXXXXXXXXXX').getAs('application/pdf').setName('XXXX.pdf');

  //HTML
  var HtmlOutput = HtmlService.createHtmlOutputFromFile('html');
  var HtmlMessage = HtmlOutput.getContent();

  //PLAIN TEXT
  var Message =
    "Dear <?= name ?>,"+"\n"+
    "XXXXXXXXXXXXXxXXXX"+"\n"+
    "XXXXXXXXXXXX <?= company ?> XXXXXXXXXXXXXXXXXXX"+"\n"+
    "XXXX Link: https://www.XXXX/XXXX"+"\n"+
    "XXXX."+"\n"+
    "With Warm Regards,"+"\n"+
    "XXX"+"\n"+
    "Call: XXXXX"+"\n"+
    "Email: XXXX"+"\n";
  var OriginalMessage = Message;
  var OriginalHtmlMessage = HtmlMessage;

  for( var i = 0 ; i <= 2 ; i++)
  {
    Message = Message.replace("<?= name ?>", name[i]);
    Message = Message.replace("<?= company ?>", company[i]);

    HtmlMessage = HtmlMessage.replace("%name", name[i]);
    HtmlMessage = HtmlMessage.replace("%company", company[i]);

    MailApp.sendEmail(
    emailid[i],
    "test email",
    Message,
    htmlBody: HtmlMessage,
    attachments: [file.getAs(MimeType.PDF), blob]
    );

    Message = OriginalMessage;
    HtmlMessage = OriginalHtmlMessage;
  }
}
</code>```

Here is the HTML File :

```<code><!DOCTYPE html>
<html>

<head>
    <base target="_top">
</head>

<body style="font-family: 'Times New Roman', Times, serif;font-size: 1.5em; padding: 5%;">
    Dear %name,<br>
    <div style="line-height: 2;margin-left:5%;">
        XXXX  XXXXXX XXXXXXX XXXXXXX XXXXXXXX XXXX.<br>
        XXXX  XXXXXX XXXXX %company XXXXXXXX XXXXXXXX XXXXX. <br>
        XXXX  XXXXXX XXXXX: <a href="https://www.XXXX">Link</a><br>
        I XXXXXX XXXX  XXXXX<br></div>
    <div style="line-height: 1.5; padding: 5%;">
        With Warm Regards,<br>
        <b>XXXXx</b><br>
        <a href="tel:+XX-XXXXX">Call: +XX-XXXXX</a><br>
        <a href="mailto:XX@XXXXXX.com">Email: XX@XXXXXX.com</a><br></div>
</body>

</html>
</code>```

How should the parameters for MailApp.SendMail() be placed?

答:
The method syntax is sendEmail(recipient, subject, body, options)

whereby both attachments and htmlBody are options and options are

a JavaScript object that specifies advanced parameters

So you need to pass the options as a JSON object with key-value pairs:

```<code>  MailApp.sendEmail(
    emailid[i][0],
    "test email",
    Message,
    {
      htmlBody: HtmlMessage,
      attachments: [file.getAs(MimeType.PDF)]
    }
  );
</code>```

Body:
I'm trying write code in Google Apps Script to send a HTML email with an attachment to a list of my contacts.
The main error I recieve is with the line

    MailApp.sendEmail(
    emailid[i],
    "test email",
    Message,
    htmlBody: HtmlMessage,
    attachments: [file.getAs(MimeType.PDF)]
    );

The error is with reference to htmlBody: HtmlMessage : SyntaxError: missing ) after argument list (line 48, file "Code.gs")

I have tried other methods online including

    MailApp.sendEmail({
    to: emailid[i],
    subject: "This is a test email",
    htmlBody: HtmlMessage,
    attachments: [file.getAs(MimeType.PDF)]
  });

I get the error : Exception: Invalid email: [Ljava.lang.Object;@1456304b (line 51, file "Code")

The entire Code :

function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();

  //BASIC DETAILS
  var name = sheet.getRange(1, 1, 3).getValues();
  var emailid = sheet.getRange(1, 2, 3).getValues();
  var company = sheet.getRange(1, 3, 3).getValues();

  //ATTACHMENTS
  var file = DriveApp.getFileById('XXXXXXXXXXXXXXXXX').getAs('application/pdf').setName('XXXX.pdf');

  //HTML
  var HtmlOutput = HtmlService.createHtmlOutputFromFile('html');
  var HtmlMessage = HtmlOutput.getContent();

  //PLAIN TEXT
  var Message =
    "Dear <?= name ?>,"+"\n"+
    "XXXXXXXXXXXXXxXXXX"+"\n"+
    "XXXXXXXXXXXX <?= company ?> XXXXXXXXXXXXXXXXXXX"+"\n"+
    "XXXX Link: https://www.XXXX/XXXX"+"\n"+
    "XXXX."+"\n"+
    "With Warm Regards,"+"\n"+
    "XXX"+"\n"+
    "Call: XXXXX"+"\n"+
    "Email: XXXX"+"\n";
  var OriginalMessage = Message;
  var OriginalHtmlMessage = HtmlMessage;

  for( var i = 0 ; i <= 2 ; i++)
  {
    Message = Message.replace("<?= name ?>", name[i]);
    Message = Message.replace("<?= company ?>", company[i]);

    HtmlMessage = HtmlMessage.replace("%name", name[i]);
    HtmlMessage = HtmlMessage.replace("%company", company[i]);

    MailApp.sendEmail(
    emailid[i],
    "test email",
    Message,
    htmlBody: HtmlMessage,
    attachments: [file.getAs(MimeType.PDF), blob]
    );

    Message = OriginalMessage;
    HtmlMessage = OriginalHtmlMessage;
  }
}

Here is the HTML File :

<!DOCTYPE html>

    <base target="_top">

    Dear %name,

        XXXX  XXXXXX XXXXXXX XXXXXXX XXXXXXXX XXXX.

        XXXX  XXXXXX XXXXX %company XXXXXXXX XXXXXXXX XXXXX.

        XXXX  XXXXXX XXXXX: Link

        I XXXXXX XXXX  XXXXX

        With Warm Regards,

        XXXXx

        Call: +XX-XXXXX

        Email: XX@XXXXXX.com

How should the parameters for MailApp.SendMail() be placed?

Body:
The method syntax is sendEmail(recipient, subject, body, options)

whereby both attachments and htmlBody are options and options are

a JavaScript object that specifies advanced parameters

So you need to pass the options as a JSON object with key-value pairs:

  MailApp.sendEmail(
    emailid[i][0],
    "test email",
    Message,
    {
      htmlBody: HtmlMessage,
      attachments: [file.getAs(MimeType.PDF)]
    }
  );


问:
simplest way to do a recurring text file upload to sql server
i have a TAB DELIMITTED log file where new data in this log file needs to be dumped into a sql server 2008 database. i am wondering what is the best way to automate this? is there a service i can use inside the management studio that will help me? </p>

答:
If you have SQL Server Integration Services (SSIS) installed, you could use that to load the Tab delimited file into SQL Server table. In this link (SQL Integration Services to load tab delimited file), I have explained it step-by-step on how to load a tab delimited file into SQL Server table using SSIS.

If you would also like to loop through multiple files of same format in a given folder and load the data into a table, here is another Stack Overflow link (Loading multiple files) that might help you do that.

Hope that helps.


问:
How to include column values as null even when condition is not met?

Write a query to show ALL building names, their metering company name and meter type for all buildings that do not have postpaid meters.

The image 1 is the result that I should get and image 2 is the results that i am getting:

```<code>USE Ultimate_DataBase
GO

SELECT [Bld_Name], [Elec_company_name], [Mtype_Name]
FROM [dbo].[Metering_Company] A
FULL OUTER JOIN [dbo].[Metering_Type] D
ON A.[MType_ID]= D.MType_ID
FULL OUTER JOIN [dbo].[Building_metering] B
ON A.[Elec_ID]= B.[Elec_ID]
FULL OUTER JOIN [dbo].[Building] C
ON C.[Bld_ID]= B.[Bld_ID]
WHERE [Mtype_Name] != 'POSTPAID'
</code>```

答:
FULL JOIN isn't seem necessary -- in fact FULL JOIN is almost never needed, and especially not for routine JOINs in a well-structured database.

The structure of the question suggests NOT EXISTS:

```<code>SELECT b.*
FROM dbo.Building b
WHERE NOT EXISTS (SELECT 1
                  FROM dbo.Building_metering bm JOIN
                       dbo.Metering_Company mc
                       ON bm.Elec_ID = mc.Elec_ID JOIN
                       dbo.Metering_Type mt
                       ON mt.MType_ID = mc.MType_ID
                  WHERE bm.Bld_ID = b.Bld_ID AND mt.Mtype_Name = 'POSTPAID'
                 );
</code>```

You can also express this as a LEFT JOIN and filtering:

```<code>SELECT b.*
FROM dbo.Building b LEFT JOIN
     dbo.Building_metering bm
     ON bm.Bld_ID = b.Bld_ID LEFT JOIN
     dbo.Metering_Company mc
     ON bm.Elec_ID = mc.Elec_ID LEFT JOIN
     dbo.Metering_Type mt
     ON mt.MType_ID = mc.MType_ID AND
        mt.Mtype_Name = 'POSTPAID'
WHERE mt.MType_ID IS NULL;
</code>```

This allows you to select columns from any of the tables.

Notes:

FULL JOIN is almost never needed.

Use meaningful table aliases!  Arbitrary letters mean nothing.  Use table abbreviations.

Escaping column and table names with square braces just makes code harder to write and to read.

Body:
Write a query to show ALL building names, their metering company name and meter type for all buildings that do not have postpaid meters.

The image 1 is the result that I should get and image 2 is the results that i am getting:

USE Ultimate_DataBase
GO

SELECT [Bld_Name], [Elec_company_name], [Mtype_Name]
FROM [dbo].[Metering_Company] A
FULL OUTER JOIN [dbo].[Metering_Type] D
ON A.[MType_ID]= D.MType_ID
FULL OUTER JOIN [dbo].[Building_metering] B
ON A.[Elec_ID]= B.[Elec_ID]
FULL OUTER JOIN [dbo].[Building] C
ON C.[Bld_ID]= B.[Bld_ID]
WHERE [Mtype_Name] != 'POSTPAID'

Body:
FULL JOIN isn't seem necessary -- in fact FULL JOIN is almost never needed, and especially not for routine JOINs in a well-structured database.

The structure of the question suggests NOT EXISTS:

SELECT b.*
FROM dbo.Building b
WHERE NOT EXISTS (SELECT 1
                  FROM dbo.Building_metering bm JOIN
                       dbo.Metering_Company mc
                       ON bm.Elec_ID = mc.Elec_ID JOIN
                       dbo.Metering_Type mt
                       ON mt.MType_ID = mc.MType_ID
                  WHERE bm.Bld_ID = b.Bld_ID AND mt.Mtype_Name = 'POSTPAID'
                 );

You can also express this as a LEFT JOIN and filtering:

SELECT b.*
FROM dbo.Building b LEFT JOIN
     dbo.Building_metering bm
     ON bm.Bld_ID = b.Bld_ID LEFT JOIN
     dbo.Metering_Company mc
     ON bm.Elec_ID = mc.Elec_ID LEFT JOIN
     dbo.Metering_Type mt
     ON mt.MType_ID = mc.MType_ID AND
        mt.Mtype_Name = 'POSTPAID'
WHERE mt.MType_ID IS NULL;

This allows you to select columns from any of the tables.

Notes:

FULL JOIN is almost never needed.

Use meaningful table aliases!  Arbitrary letters mean nothing.  Use table abbreviations.

Escaping column and table names with square braces just makes code harder to write and to read.


问:
C# Should I use lock statement when I am only reading and not changing queue?
I am using list as a queue in my multithreading C# application.
I am locking my custom Enqueue and Dequeue methods. Because multiple threads can call those methods.

From: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement
I think I should but I would still ask the question here.
Should I lock Peek method that is only telling me which element is at zero index?
For the purpose of example consider that I have list(queue) of integers.

```<code>list = [1, 2, 2, 5]
Enqueue(list, 6)
// [1, 2, 2, 5, 6]

var element = Dequeue(list) // element = 1;
// [2, 2, 5, 6]

var peekElement = Peek(list) // peekElement = 2
// [2, 2, 5, 6]
</code>```

答:
From the documentation of the Queue<T> class:

Public static members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

A Queue<T> can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. For a thread-safe queue, see ConcurrentQueue<T>.

So if you call Peek from one thread while the queue is modified concurrently by other threads, without synchronizing properly the access to the queue using a lock or other means, you are breaking the guarantees offered by the manufacturer of the class. The behavior of the class becomes officially "undefined". This is not a good idea if you are trying to make a program that should be reliable regarding the correctness of its results.

Body:
I am using list as a queue in my multithreading C# application.
I am locking my custom Enqueue and Dequeue methods. Because multiple threads can call those methods.

From: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement
I think I should but I would still ask the question here.
Should I lock Peek method that is only telling me which element is at zero index?
For the purpose of example consider that I have list(queue) of integers.

list = [1, 2, 2, 5]
Enqueue(list, 6)
// [1, 2, 2, 5, 6]

var element = Dequeue(list) // element = 1;
// [2, 2, 5, 6]

var peekElement = Peek(list) // peekElement = 2
// [2, 2, 5, 6]


问:
How to use convert date in billboardJS
it's the first time i am using billboard.js so i'm having difficulties working with timeseries data, here's my try:

exemple of the data:

```<code>{
  "values":{
    [5,8],[2020-02-07T07:06:01.591Z,2020-02-07T07:06:03.812Z]
  }
}
</code>```

how i'm trying to display it (not sure if MS exists):

```<code>chart = bb.generate({
  bindto: "#chart",
  data: {
      x: "x",
      xFormat: "%Y-%m-%dT%H:%M:%S.%MSZ",
      type: "line",
      columns: [
          ["x",data.values[1]],
          ["nbr evenements",data.values[0]]
      ]
  },
  axis:{
    x:{
      type:"timeseries",
      localtime:false,
      tick: {
        format: "%Y-%m-%d %H:%M:%S.%MS"
      }
    }
  }
});
</code>```

答:
i tried this instead, it worked fine:    </p>

```<code>chart = bb.generate({
  bindto: "#chart",
  data: {
      x: "x",
      xFormat: "%Y-%m-%dT%H:%M:%S.%LZ",
      type: "line",
      columns: [
          ["x"].concat(data.values[1]),
          ["nbr evenements"].concat(data.values[0])
      ]
  },
  axis:{
    x:{
      type:"timeseries",
      localtime:false,
      tick: {
        format: "%Y-%m-%dT%H:%M:%S"
      }
    }
  }
});
</code>```

Title: How to use convert date in billboardJS

Body:
it's the first time i am using billboard.js so i'm having difficulties working with timeseries data, here's my try:

exemple of the data:

{
  "values":{
    [5,8],[2020-02-07T07:06:01.591Z,2020-02-07T07:06:03.812Z]
  }
}

how i'm trying to display it (not sure if MS exists):

chart = bb.generate({
  bindto: "#chart",
  data: {
      x: "x",
      xFormat: "%Y-%m-%dT%H:%M:%S.%MSZ",
      type: "line",
      columns: [
          ["x",data.values[1]],
          ["nbr evenements",data.values[0]]
      ]
  },
  axis:{
    x:{
      type:"timeseries",
      localtime:false,
      tick: {
        format: "%Y-%m-%d %H:%M:%S.%MS"
      }
    }
  }
});

Body:
i tried this instead, it worked fine:

chart = bb.generate({
  bindto: "#chart",
  data: {
      x: "x",
      xFormat: "%Y-%m-%dT%H:%M:%S.%LZ",
      type: "line",
      columns: [
          ["x"].concat(data.values[1]),
          ["nbr evenements"].concat(data.values[0])
      ]
  },
  axis:{
    x:{
      type:"timeseries",
      localtime:false,
      tick: {
        format: "%Y-%m-%dT%H:%M:%S"
      }
    }
  }
});


问:
Is there a STL algorithm that finds last but that it also works on pointers?
I have existing code where I can not switch to iterators.
Still I would like to use STL if possible to find the last item(or first if you consider we are iterating from end).
Is that possible?

std::find_end beside being worst named algorithm ever seems quite ugly to use(I would need a fake 1 element sequence and binary predicate that ignores values of 1 element in comparison).

What I have now is quite ugly(especially since reverse of reverse of bool* is not bool* so I have to do ugly stuff to get std::distance.

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

int main()
{
    {
    bool arr[6] = {true,false,true,true,true,false};
    auto e = std::make_reverse_iterator(&arr[0]);
    auto b = std::make_reverse_iterator(&arr[6]);
    auto it = std::find(b,e, false);
    if (it!=e){
        std::cout << "index of last false is " << &(*it) - &arr[0] << std::endl;
    }
    }
    // repeat test to make sure result is not an accident
    {
    bool arr[6] = {true,false,true,true,false,true};
    auto e = std::make_reverse_iterator(&arr[0]);
    auto b = std::make_reverse_iterator(&arr[6]);
    auto it = std::find(b,e, false);
    if (it!=e){
        std::cout << "index of last false is " << &(*it) - &arr[0] << std::endl;
    }
    }
}
</code>```

答:
I am not sure if I get right what you need but this code seems to work ok:</p>

```<code>int arr[6] = { 1, 2, 3, 4, 5 };
int pattern[1] = { 4 };
auto it = std::find_end(arr, arr + 5, pattern, pattern + 1);
</code>```

Body:
I have existing code where I can not switch to iterators.
Still I would like to use STL if possible to find the last item(or first if you consider we are iterating from end).
Is that possible?

std::find_end beside being worst named algorithm ever seems quite ugly to use(I would need a fake 1 element sequence and binary predicate that ignores values of 1 element in comparison).

What I have now is quite ugly(especially since reverse of reverse of bool* is not bool* so I have to do ugly stuff to get std::distance.

#include <algorithm>
#include <iostream>

int main()
{
    {
    bool arr[6] = {true,false,true,true,true,false};
    auto e = std::make_reverse_iterator(&arr[0]);
    auto b = std::make_reverse_iterator(&arr[6]);
    auto it = std::find(b,e, false);
    if (it!=e){
        std::cout << "index of last false is " << &(*it) - &arr[0] << std::endl;
    }
    }
    // repeat test to make sure result is not an accident
    {
    bool arr[6] = {true,false,true,true,false,true};
    auto e = std::make_reverse_iterator(&arr[0]);
    auto b = std::make_reverse_iterator(&arr[6]);
    auto it = std::find(b,e, false);
    if (it!=e){
        std::cout << "index of last false is " << &(*it) - &arr[0] << std::endl;
    }
    }
}

Body:
I am not sure if I get right what you need but this code seems to work ok:

int arr[6] = { 1, 2, 3, 4, 5 };
int pattern[1] = { 4 };
auto it = std::find_end(arr, arr + 5, pattern, pattern + 1);


问:
rxjs6: RetryWhen not work when returning timer
I'm building a small function that will refresh the access token after a specific time (base on calculation).

```<code>public buildRefreshTokenTimerAsync(): Observable<LoginResultViewModel> {

        let accessToken = '';
        let refreshToken = '';
        let lastRefreshTokenTime: number;
        let issuedTokenTime: number;
        let accessTokenLifeTime = ACCESS_TOKEN_LIFE_TIME;
        let user: ProfileViewModel;
        let retriedTime = 0;

        // Load the last time the application refresh the access token.
        const loadLastRefreshTokenTimeObservable = this.storageMap
            .get<number>(LocalStorageKeyConstant.lastRefreshTokenAt)
            .pipe(
                tap((time: number) => {
                    lastRefreshTokenTime = time;
                })
            );

        // Load login result from storage map observable.
        const loadLoginResultObservable = this.storageMap
            .get<LoginResultViewModel>(LocalStorageKeyConstant.loginResult)
            .pipe(
                tap((loginResult: LoginResultViewModel) => {
                    if (!loginResult || !loginResult.accessToken || !loginResult.accessToken.trim()) {
                        throw new Error(ExceptionCodeConstant.accessTokenNotFound);
                    }

                    if (!loginResult.refreshToken || !loginResult.refreshToken.trim()) {
                        throw new Error(ExceptionCodeConstant.refreshTokenNotFound);
                    }

                    accessToken = loginResult.accessToken;
                    refreshToken = loginResult.refreshToken;
                    issuedTokenTime = loginResult.issuedAt;
                    accessTokenLifeTime = loginResult.lifeTime;
                    user = loginResult.user;
                })
            );

        return of(null)
            .pipe(
                flatMap(_ => {
                    return forkJoin([
                        loadLastRefreshTokenTimeObservable,
                        loadLoginResultObservable]);
                }),
                flatMap(() => {

                    // Get the current time in the system.
                    const currentTime = new Date().getTime();

                    // Calculate the time to refresh the access token.
                    const timeToRefreshToken = this.calculateAccessTokenRefreshTime(issuedTokenTime, ACCESS_TOKEN_LIFE_TIME);

                    // Access token hasn't been refreshed before.
                    if (lastRefreshTokenTime === undefined || lastRefreshTokenTime === null) {

                        // Refresh time was in the past. Refresh the token now.
                        if (currentTime >= timeToRefreshToken) {
                            return timer(0);
                        }
                    }

                    // Access token has refreshed before, however, another thread is handling the operation.
                    // Retry after the specific time.
                    if (currentTime - lastRefreshTokenTime < REFRESH_TIME_GAP) {
                        throw new Error(ExceptionCodeConstant.accessTokenIsRefreshing);
                    }

                    // Refresh time is in the future.
                    if (currentTime < timeToRefreshToken) {
                        const delayTime = timeToRefreshToken - currentTime;
                        return timer(delayTime);
                    }

                    return timer(0);
                }),
                flatMap(_ => this.loadRefreshTokenAsync(refreshToken)),
                flatMap((loginResult: LoginResultViewModel) => {
                    loginResult.user = user;
                    return this.storageMap
                        .set(LocalStorageKeyConstant.loginResult, loginResult)
                        .pipe(
                            flatMap(_ => {
                                return this.storageMap.set(LocalStorageKeyConstant.lastRefreshTokenAt, new Date().getTime());
                            }),
                            map(() => {
                                return loginResult;
                            })
                        );
                }),
                retryWhen(errors => {
                    return errors
                        .pipe(
                            flatMap(error => {
                                retriedTime++;
                                if (retriedTime > 2) {
                                    throw error;
                                }

                                if (!(error instanceof Error)) {
                                    return throwError(error);
                                }

                                if (ExceptionCodeConstant.accessTokenIsRefreshing === (error as Error).message) {
                                    return timer(2000);
                                }

                                return throwError(error);
                            })
                        );
                })
            );
    }
</code>```

What I expect is when ACCESS_TOKEN_IS_REFRESHING exception is thrown, the function will retry after 2 seconds.

If I use retry instead of retryWhen, the function is OK, but when I changed to retryWhen and return a timer, function does not retry after 2 second.

Am I doing anything wrong ?

答:
First:

I'm building a small function

Posts a +100 line function with major indentations :D

Second:

I think you shouldn't use flatMap but a delayWhen:

```<code>retryWhen((errors) => errors.pipe(
  delayWhen((error) => {
    retriedTime++;

    if (retriedTime > 2) {
      throw error;
    }

    if (!(error instanceof Error)) {
      return throwError(error);
    }

    if (ExceptionCodeConstant.accessTokenIsRefreshing === (error as Error).message) {
      return timer(2000);
    }

    return throwError(error);
  })
))
</code>```

Simplified stackblitz showing it works

Body:
I'm building a small function that will refresh the access token after a specific time (base on calculation).

public buildRefreshTokenTimerAsync(): Observable<LoginResultViewModel> {

        let accessToken = '';
        let refreshToken = '';
        let lastRefreshTokenTime: number;
        let issuedTokenTime: number;
        let accessTokenLifeTime = ACCESS_TOKEN_LIFE_TIME;
        let user: ProfileViewModel;
        let retriedTime = 0;

        // Load the last time the application refresh the access token.
        const loadLastRefreshTokenTimeObservable = this.storageMap
            .get<number>(LocalStorageKeyConstant.lastRefreshTokenAt)
            .pipe(
                tap((time: number) => {
                    lastRefreshTokenTime = time;
                })
            );

        // Load login result from storage map observable.
        const loadLoginResultObservable = this.storageMap
            .get<LoginResultViewModel>(LocalStorageKeyConstant.loginResult)
            .pipe(
                tap((loginResult: LoginResultViewModel) => {
                    if (!loginResult || !loginResult.accessToken || !loginResult.accessToken.trim()) {
                        throw new Error(ExceptionCodeConstant.accessTokenNotFound);
                    }

                    if (!loginResult.refreshToken || !loginResult.refreshToken.trim()) {
                        throw new Error(ExceptionCodeConstant.refreshTokenNotFound);
                    }

                    accessToken = loginResult.accessToken;
                    refreshToken = loginResult.refreshToken;
                    issuedTokenTime = loginResult.issuedAt;
                    accessTokenLifeTime = loginResult.lifeTime;
                    user = loginResult.user;
                })
            );

        return of(null)
            .pipe(
                flatMap(_ => {
                    return forkJoin([
                        loadLastRefreshTokenTimeObservable,
                        loadLoginResultObservable]);
                }),
                flatMap(() => {

                    // Get the current time in the system.
                    const currentTime = new Date().getTime();

                    // Calculate the time to refresh the access token.
                    const timeToRefreshToken = this.calculateAccessTokenRefreshTime(issuedTokenTime, ACCESS_TOKEN_LIFE_TIME);

                    // Access token hasn't been refreshed before.
                    if (lastRefreshTokenTime === undefined || lastRefreshTokenTime === null) {

                        // Refresh time was in the past. Refresh the token now.
                        if (currentTime >= timeToRefreshToken) {
                            return timer(0);
                        }
                    }

                    // Access token has refreshed before, however, another thread is handling the operation.
                    // Retry after the specific time.
                    if (currentTime - lastRefreshTokenTime < REFRESH_TIME_GAP) {
                        throw new Error(ExceptionCodeConstant.accessTokenIsRefreshing);
                    }

                    // Refresh time is in the future.
                    if (currentTime < timeToRefreshToken) {
                        const delayTime = timeToRefreshToken - currentTime;
                        return timer(delayTime);
                    }

                    return timer(0);
                }),
                flatMap(_ => this.loadRefreshTokenAsync(refreshToken)),
                flatMap((loginResult: LoginResultViewModel) => {
                    loginResult.user = user;
                    return this.storageMap
                        .set(LocalStorageKeyConstant.loginResult, loginResult)
                        .pipe(
                            flatMap(_ => {
                                return this.storageMap.set(LocalStorageKeyConstant.lastRefreshTokenAt, new Date().getTime());
                            }),
                            map(() => {
                                return loginResult;
                            })
                        );
                }),
                retryWhen(errors => {
                    return errors
                        .pipe(
                            flatMap(error => {
                                retriedTime++;
                                if (retriedTime > 2) {
                                    throw error;
                                }

                                if (!(error instanceof Error)) {
                                    return throwError(error);
                                }

                                if (ExceptionCodeConstant.accessTokenIsRefreshing === (error as Error).message) {
                                    return timer(2000);
                                }

                                return throwError(error);
                            })
                        );
                })
            );
    }

What I expect is when ACCESS_TOKEN_IS_REFRESHING exception is thrown, the function will retry after 2 seconds.

If I use retry instead of retryWhen, the function is OK, but when I changed to retryWhen and return a timer, function does not retry after 2 second.

Am I doing anything wrong ?

Body:
First:

I'm building a small function

Posts a +100 line function with major indentations :D

Second:

I think you shouldn't use flatMap but a delayWhen:

retryWhen((errors) => errors.pipe(
  delayWhen((error) => {
    retriedTime++;

    if (retriedTime > 2) {
      throw error;
    }

    if (!(error instanceof Error)) {
      return throwError(error);
    }

    if (ExceptionCodeConstant.accessTokenIsRefreshing === (error as Error).message) {
      return timer(2000);
    }

    return throwError(error);
  })
))

Simplified stackblitz showing it works


问:
How can I patch / mock logging.getlogger()
I have this code that I want to test:

```<code>log = logging.getLogger(__name__)

class A(object):
    def __init__(self):
        log.debug('Init')
</code>```

but I cannot figure out how to assert that log.debug was called with 'Init'

I tried patching logger but inspecting it I only found a getLogger mock.

I'm sure its simple, but I just cant figure it!

Thanks in advance for any and all help!

答:
Here is a complete example

"""
Source to test
"""
import logging

logger = logging.getLogger("abc")

def my_fonction():
    logger.warning("Oops")

"""
Testing part
"""
import unittest
from unittest.mock import patch, MagicMock

abc_logger = logging.getLogger("abc")

class TestApp(unittest.TestCase):

    @patch.object(abc_logger, "warning", MagicMock())
    def test_my_fonction(self):
        # When
        my_fonction()
        # Then
        abc_logger.warning.assert_called_once()

```

Body:
I have this code that I want to test:

log = logging.getLogger(__name__)

class A(object):
    def __init__(self):
        log.debug('Init')

but I cannot figure out how to assert that log.debug was called with 'Init'

I tried patching logger but inspecting it I only found a getLogger mock.

I'm sure its simple, but I just cant figure it!

Thanks in advance for any and all help!


问:
I want to select rows(checkbox) in ag-grid based on a condition
Basically, there is a button which when clicked gets an array. I need to compare that array with existing ag-grid and if there is a match need to select the corresponding checkbox / rows. i.e.based on the combination. Ag-grid and the array that we receive from the button has common keys that needs to be compared.

Here, importExcel() gets an array on firing which is to be compared with the ag grid -

```<code>button class="btn btn-sm btn-secondary font-shrink pull-right" *ngIf='this.showUploadbtnSec' (click)="importExcel()" placement="top"
                  tooltip="Upload now!" container="body">
                    <i class="lni-upload iconsize1"></i>
                  </button>
</code>```

Ag-grid gridoptions

```<code>   public gridColumnDefs = [
        {
            headerName: 'Portfolio Name',
            field: 'portfolioName',
            cellRenderer: 'agGroupCellRenderer',
            headerCheckboxSelection: true,
            headerCheckboxSelectionFilteredOnly: true,
            checkboxSelection: true,
            pinned: 'left',
            filter: true
        },
]
</code>```

答:
Have you tired isRowSelectable(). It will always row selection based on some conditions.

Is Row selectable

Body:
Basically, there is a button which when clicked gets an array. I need to compare that array with existing ag-grid and if there is a match need to select the corresponding checkbox / rows. i.e.based on the combination. Ag-grid and the array that we receive from the button has common keys that needs to be compared.

Here, importExcel() gets an array on firing which is to be compared with the ag grid -

button class="btn btn-sm btn-secondary font-shrink pull-right" *ngIf='this.showUploadbtnSec' (click)="importExcel()" placement="top"
                  tooltip="Upload now!" container="body">

                  </button>

Ag-grid gridoptions

   public gridColumnDefs = [
        {
            headerName: 'Portfolio Name',
            field: 'portfolioName',
            cellRenderer: 'agGroupCellRenderer',
            headerCheckboxSelection: true,
            headerCheckboxSelectionFilteredOnly: true,
            checkboxSelection: true,
            pinned: 'left',
            filter: true
        },
]


问:
Python function to return concatenated string from a list, where the length of the string is more than 2 characters
Newbie learning Python here, be nice!!

I have an assignment as part of my course to write simple programs, but there is one I am struggling with. For all elements in a list that have more than 2 characters, should be concatenated. The code itself is working, but it's returning the first string in the list as well as the other strings which are more than 2 characters. It's because of the way I have written the code I know, but I can't figure out a way to exclude the first string. Iteration should be utilised.

My code:

```<code>def concatenate(strings):
    start = strings[0]
    for string in strings:
        if len(string) > 2:
            start += string
    return start

print(concatenate(["a", "de", "fg", "hijk", "abc"]))
</code>```

It's correctly concatenating hijkabc, but it's also including the "a" at the beginning, so the result I'm actually getting is ahijkabc.

What do I need to do?

Thanks!

答:
Got it! Thanks - I just needed an empty string to begin with, so

```<code>start = ''
</code>```

Rather than

```<code>start = strings[0]
</code>```

It was as easy as that, and now I feel silly! But, it's all a learning curve.
Thanks for all the help!

Body:
Newbie learning Python here, be nice!!

I have an assignment as part of my course to write simple programs, but there is one I am struggling with. For all elements in a list that have more than 2 characters, should be concatenated. The code itself is working, but it's returning the first string in the list as well as the other strings which are more than 2 characters. It's because of the way I have written the code I know, but I can't figure out a way to exclude the first string. Iteration should be utilised.

My code:

def concatenate(strings):
    start = strings[0]
    for string in strings:
        if len(string) > 2:
            start += string
    return start

print(concatenate(["a", "de", "fg", "hijk", "abc"]))

It's correctly concatenating hijkabc, but it's also including the "a" at the beginning, so the result I'm actually getting is ahijkabc.

What do I need to do?

Thanks!

Body:
Got it! Thanks - I just needed an empty string to begin with, so

start = ''

Rather than

start = strings[0]

It was as easy as that, and now I feel silly! But, it's all a learning curve.
Thanks for all the help!