问:
How to test in jest for target instanceof window.Window
I have a function that performs the following (NOTE: this is using typescript hence the type defs you see in the args)...

```<code>function scroll(target: HTMLElement, {posX, posY}: ScrollPosition): void {
    if (target instanceof window.Window) {
        target.scrollTo(posX, posY);
    } else {
        /* eslint-disable no-param-reassign */
        target.scrollLeft = posX;
        target.scrollTop = posY;
        /* eslint-enable no-param-reassign */
    }
}
</code>```

With the current jest setup that I have, it covers for the else statement, but I need to also test when target instanceof window.Window. This is some of what I have so far at least to get a spy on the scrollTo...

```<code>const spyScrollTo = jest.fn();

beforeEach(() => {
    Object.defineProperty(global.window, 'scrollTo', {value: spyScrollTo});
    spyScrollTo.mockClear();
});
</code>```

...but I haven't gotten far enough along to figure out how to make the target getting passed as part of window.Window. I've tried messing around with the jsdom library with little success.

答:
window.scrollTo property descriptor should be configurable in order to be set multiple times. It should be cleaned up in afterEach to avoid test cross-contamination.

Currently window === global and not an instance of Window in Jest, so it won't pass target instanceof window.Window condition which would be true in a browser.

It can be tested with stubbed Window instance:

```<code>test('...', () => {
  let mockWindow = Object.create(Window.prototype, { scrollTo: { value: jest.fn() } });
  scroll(mockWindow, {posX: 100, posY: 200});
  expect(mockWindow.scrollTo).toBeCalledWith(100, 200);
});
</code>```

Body:
I have a function that performs the following (NOTE: this is using typescript hence the type defs you see in the args)...

function scroll(target: HTMLElement, {posX, posY}: ScrollPosition): void {
    if (target instanceof window.Window) {
        target.scrollTo(posX, posY);
    } else {
        /* eslint-disable no-param-reassign */
        target.scrollLeft = posX;
        target.scrollTop = posY;
        /* eslint-enable no-param-reassign */
    }
}

With the current jest setup that I have, it covers for the else statement, but I need to also test when target instanceof window.Window. This is some of what I have so far at least to get a spy on the scrollTo...

const spyScrollTo = jest.fn();

beforeEach(() => {
    Object.defineProperty(global.window, 'scrollTo', {value: spyScrollTo});
    spyScrollTo.mockClear();
});

...but I haven't gotten far enough along to figure out how to make the target getting passed as part of window.Window. I've tried messing around with the jsdom library with little success.

Body:
window.scrollTo property descriptor should be configurable in order to be set multiple times. It should be cleaned up in afterEach to avoid test cross-contamination.

Currently window === global and not an instance of Window in Jest, so it won't pass target instanceof window.Window condition which would be true in a browser.

It can be tested with stubbed Window instance:

test('...', () => {
  let mockWindow = Object.create(Window.prototype, { scrollTo: { value: jest.fn() } });
  scroll(mockWindow, {posX: 100, posY: 200});
  expect(mockWindow.scrollTo).toBeCalledWith(100, 200);
});


来源: stackexchange

问:
"Dimensions" options in Data pane
I am using Tableau Server Version: 2020.2.0 (20202.20.0425.1206) 64-bit Linux

I am trying to use geographic data.

From a tutorial

In the Data pane, under Dimensions, double-click State.

I can't find "Dimensions" options, where is it?

答:
In your case Province and Gender are the dimensions - those values above [Measure Names] (which is also a dimension).

Since 2020.2 (as per your comment) it looks like Dimensions and Measures aren't separated with a title. They are separated by the horizontal line and also the colour - with dimensions blue by default and measures green.

ContentLicense: CC BY-SA 4.0

Title: "Dimensions" options in Data pane


问:
How to toggle dark theme in Angular when I click on the switch?
I am using angular and I am trying to switch between light and dark themes. The toggle switch is in my header component. Please see below

And my header component is the child component in the app component. See below also

```<code>// app.component.html

    <app-header (mode)="receiveMode($event)"></app-header>

     <router-outlet></router-outlet>
</code>```

Therefore, I set the boolean value for the toggle theme in my header component TS file

```<code>// header.component.ts

import { Component, OnInit , Output, EventEmitter} from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  @Output() mode = new EventEmitter<boolean>();

  setDark = false;

  constructor() { }

  ngOnInit(): void {

  }

  onChangeToggle() {
    this.setDark = !this.setDark;
    this.mode.emit(this.setDark);
    console.log(this.setDark);
  }

}
</code>```

I then pass that value to the parent component with the Output decorator and receive it in the app.component.ts file so that all other components can have the theme as well, (not just HomeComponent).

```<code>// app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  setMode = false;

  receiveMode($event) {
    this.setMode = $event;
    console.log("MODEEEE", this.setMode);
  }

  title = 'about-me';
}
</code>```

I then receive the boolean value from the app-header in the app.component.html file

```<code>// app.component.html

    <app-header (mode)="receiveMode($event)"></app-header>

    <router-outlet></router-outlet>
</code>```

And I added the darkTheme class to my global stylessheet in styles.css

```<code>.darkTheme {
    background-color: black;
}
</code>```

I want to know how  can use ngClass or ngStyle to set it conditionally based on the boolean value.

答:
Check out this Stackblitz https://stackblitz.com/edit/angular-ivy-prkazr I've created for this question.

app.component.ts:

```<code>import { Component, ViewEncapsulation } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class AppComponent {
  setMode = false;

  receiveMode($event) {
    this.setMode = $event;
    console.log("MODEEEE", this.setMode);
  }
}
</code>```

you need encapsulation: ViewEncapsulation.ShadowDom in your app.component decoration to enable using the parent's styles in it's children components see https://angular.io/api/core/ViewEncapsulation, this is because ::ng-deep is deprecated see https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep for more info.

app.component.html

```<code><div id="main-container" [ngClass]="[setMode ? 'darkTheme' : '']">

    <app-header (mode)="receiveMode($event)"></app-header>

    <router-outlet></router-outlet>

</div>
</code>```

app.component.css

```<code>#main-container{
  width: 100%;
  min-height: 100vh;
}

#main-container.darkTheme {
  background-color: #000;
}

#main-container.darkTheme h1{
 color: white;
}

#main-container.darkTheme nav{
 background-color: #fafafa;
}

#main-container.darkTheme .nav-link{
 color: #000;
}

#main-container.darkTheme .nav-link.is-active{
 color: #cb2d67;
}
</code>```

header.component.html

```<code><nav>
    <a routerLink="/" routerLinkActive="is-active" [routerLinkActiveOptions]="{exact: true}" class="nav-link" tabindex="1">
        Home
    </a>
    <a routerLink="/about" routerLinkActive="is-active" [routerLinkActiveOptions]="{exact: true}" class="nav-link" tabindex="1">
        About
    </a>

  <button (click)="onChangeToggle()">Toggle Theme</button>
</nav>
</code>```

Body:
I am using angular and I am trying to switch between light and dark themes. The toggle switch is in my header component. Please see below

And my header component is the child component in the app component. See below also

// app.component.html

    <app-header (mode)="receiveMode($event)"></app-header>

     <router-outlet></router-outlet>

Therefore, I set the boolean value for the toggle theme in my header component TS file

// header.component.ts

import { Component, OnInit , Output, EventEmitter} from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  @Output() mode = new EventEmitter<boolean>();

  setDark = false;

  constructor() { }

  ngOnInit(): void {

  }

  onChangeToggle() {
    this.setDark = !this.setDark;
    this.mode.emit(this.setDark);
    console.log(this.setDark);
  }

}

I then pass that value to the parent component with the Output decorator and receive it in the app.component.ts file so that all other components can have the theme as well, (not just HomeComponent).

// app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  setMode = false;

  receiveMode($event) {
    this.setMode = $event;
    console.log("MODEEEE", this.setMode);
  }

  title = 'about-me';
}

I then receive the boolean value from the app-header in the app.component.html file

// app.component.html

    <app-header (mode)="receiveMode($event)"></app-header>

    <router-outlet></router-outlet>

And I added the darkTheme class to my global stylessheet in styles.css

.darkTheme {
    background-color: black;
}

I want to know how  can use ngClass or ngStyle to set it conditionally based on the boolean value.

Body:
Check out this Stackblitz https://stackblitz.com/edit/angular-ivy-prkazr I've created for this question.

app.component.ts:

import { Component, ViewEncapsulation } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class AppComponent {
  setMode = false;

  receiveMode($event) {
    this.setMode = $event;
    console.log("MODEEEE", this.setMode);
  }
}

you need encapsulation: ViewEncapsulation.ShadowDom in your app.component decoration to enable using the parent's styles in it's children components see https://angular.io/api/core/ViewEncapsulation, this is because ::ng-deep is deprecated see https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep for more info.

app.component.html

<div id="main-container" [ngClass]="[setMode ? 'darkTheme' : '']">

    <app-header (mode)="receiveMode($event)"></app-header>

    <router-outlet></router-outlet>

</div>

app.component.css

#main-container{
  width: 100%;
  min-height: 100vh;
}

#main-container.darkTheme {
  background-color: #000;
}

#main-container.darkTheme h1{
 color: white;
}

#main-container.darkTheme nav{
 background-color: #fafafa;
}

#main-container.darkTheme .nav-link{
 color: #000;
}

#main-container.darkTheme .nav-link.is-active{
 color: #cb2d67;
}

header.component.html

<nav>
    <a routerLink="/" routerLinkActive="is-active" [routerLinkActiveOptions]="{exact: true}" class="nav-link" tabindex="1">
        Home
    </a>
    <a routerLink="/about" routerLinkActive="is-active" [routerLinkActiveOptions]="{exact: true}" class="nav-link" tabindex="1">
        About
    </a>

  <button (click)="onChangeToggle()">Toggle Theme</button>
</nav>


问:
Having trouble with implementing a system that detects if an input is a integer or not
I'm trying to make a system that asks the user how many times they want a phrase to be repeated and then it checks if the answer is an integer or a string. The program works well when I don't try to implement this system and leave it just at asking the phrase and how many times it should be repeated but it falls appart when I try to check if the amount of times is an integer or not.

```<code>import java.util.*;

public class Phrase {
    public static Scanner phraseScan = new Scanner (System.in);
    public static Scanner amountScan = new Scanner (System.in);
    public static void main (String[] args ) {

        System.out.println("What phrase do you want repeated?");
        String phrase = phraseScan.nextLine();
        int phraseLoops = 0;

        System.out.println("How many " + phrase + "s" + " do you want?");
        int desiredPhraseLoops = amountScan.nextInt();

        for (;;) {
            if (!amountScan.hasNextInt()) {
                System.out.println("Integers only please");
                amountScan.next();

            }
            desiredPhraseLoops = amountScan.nextInt();
            if (desiredPhraseLoops >= 0) {
                System.out.println("Valid amount!");
                continue;
            } else {
                break;

            }
        }

        System.out.println(desiredPhraseLoops + " " + phrase + "s coming your way!");

        do {
            System.out.println(phrase);
            phraseLoops++;

        } while (phraseLoops != desiredPhraseLoops);

        System.out.println("You printed " + phraseLoops + " " + phrase + "s" );
    }
}

</code>```

What I've tried:

```<code>try {
          desiredPhraseLoops = amountScan.nextInt();

        } catch (InputMismatchException exception) {
            System.out.println("This is not an integer.");
        }

          if (!amountScan.hasNextInt()) {
            System.out.println("Good.");
        } else {
            System.out.println("Enter an Integer please.");
        }

</code>```

Any time I tried anything, it would ask which phrase I wanted and how many times I wanted it repeated. And then the program just stopped afterward, no matter if I put in an integer or a string, it just didnt give me any other prompts.

The output is this:

What phrase do you want repeated?
Test
How many Tests do you want?
3

And that's it.

答:
To begin with, just use one Scanner object. You don't need more than that for keyboard input.

If you like, you can just stick with the Scanner#nextLine() method, for example:

```<code>Scanner userInput = new Scanner(System.in);

String phrase = "";
while (phrase.equals("")) {
    System.out.println("What phrase do you want repeated?");
    phrase = userInput.nextLine();
    // VALIDATION:
    // Was anything other than a empty string (spaces)
    // or longer than 2 characters supplied?
    if (phrase.trim().equals("") || phrase.length() < 3) {
        // Nope!
        System.err.println("Invalid Input!. Enter a proper phrase!");
        phrase = "";
    }
    // Yes, allow the prompt loop to exit.
}

String phraseLoopsNumber = "";
while (phraseLoopsNumber.equals("")) {
    System.out.println("How many " + phrase + "s" + " do you want?");
    phraseLoopsNumber = userInput.nextLine();
    // VALIDATION:
    // Did the User supply a string representation of an integer value?
    if (!phraseLoopsNumber.matches("\\d+")) {
        // Nope!
        System.out.println("Invalid Input (" + phraseLoopsNumber + ")! An integer value is expected!");
        phraseLoopsNumber = "";
    }
    // Yes he/she/it did...Allow prompt loop to exit.
}

int numberOfLoops = Integer.parseInt(phraseLoopsNumber);

// Do what you have to do with the desired number of loops contained
// within the numberOfLoops integer variable.
</code>```

In the above code, the String#matches() method was used along with a small Regular Expression (RegEx). The "\\d" expression passed to the matches() method checks to see if the string it is working against contains all (1 or more) digits.

If however you're hell bent on using the Scanner#nextInt() method then you can do it this way:

```<code>int numberOfLoops = -1;
while (numberOfLoops == -1) {
    System.out.println("How many " + phrase + "'s" + " do you want?");
    // Trap any input errors against the Scanner.nextInt() method...
    // This would be a form of validation.
    try {
        numberOfLoops = userInput.nextInt();
        // Consume the newline from ENTER key in case a nextLine() prompt is next.
        userInput.nextLine();
    } catch (Exception ex) {
        System.out.println("Invalid Input! An integer value is expected!");
        // Consume the newline from ENTER key in case a nextLine() prompt is next.
        // The first one above would of been skipped past if nextInt() threw an exception.
        userInput.nextLine();
        numberOfLoops = -1;
        continue;  // continue loop so as to re-prompt
    }
    // Further Validation:
    // Did the User supply a number greater than 0?
    if (numberOfLoops < 1 ) {
        // Nope!
        System.out.println("Invalid Input (" + numberOfLoops + ")! A value 1 or greater is expected!");
        numberOfLoops = -1;
    }
    // Yes he/she did...Allow prompt loop to exit.
}
// Do what you have to do with the desired number of loops contained
// within the numberOfLoops integer variable.
</code>```

Body:
I'm trying to make a system that asks the user how many times they want a phrase to be repeated and then it checks if the answer is an integer or a string. The program works well when I don't try to implement this system and leave it just at asking the phrase and how many times it should be repeated but it falls appart when I try to check if the amount of times is an integer or not.

import java.util.*;

public class Phrase {
    public static Scanner phraseScan = new Scanner (System.in);
    public static Scanner amountScan = new Scanner (System.in);
    public static void main (String[] args ) {

        System.out.println("What phrase do you want repeated?");
        String phrase = phraseScan.nextLine();
        int phraseLoops = 0;

        System.out.println("How many " + phrase + "s" + " do you want?");
        int desiredPhraseLoops = amountScan.nextInt();

        for (;;) {
            if (!amountScan.hasNextInt()) {
                System.out.println("Integers only please");
                amountScan.next();

            }
            desiredPhraseLoops = amountScan.nextInt();
            if (desiredPhraseLoops >= 0) {
                System.out.println("Valid amount!");
                continue;
            } else {
                break;

            }
        }

        System.out.println(desiredPhraseLoops + " " + phrase + "s coming your way!");

        do {
            System.out.println(phrase);
            phraseLoops++;

        } while (phraseLoops != desiredPhraseLoops);

        System.out.println("You printed " + phraseLoops + " " + phrase + "s" );
    }
}

What I've tried:

try {
          desiredPhraseLoops = amountScan.nextInt();

        } catch (InputMismatchException exception) {
            System.out.println("This is not an integer.");
        }

          if (!amountScan.hasNextInt()) {
            System.out.println("Good.");
        } else {
            System.out.println("Enter an Integer please.");
        }

Any time I tried anything, it would ask which phrase I wanted and how many times I wanted it repeated. And then the program just stopped afterward, no matter if I put in an integer or a string, it just didnt give me any other prompts.

The output is this:

What phrase do you want repeated?
Test
How many Tests do you want?
3

And that's it.

Body:
To begin with, just use one Scanner object. You don't need more than that for keyboard input.

If you like, you can just stick with the Scanner#nextLine() method, for example:

Scanner userInput = new Scanner(System.in);

String phrase = "";
while (phrase.equals("")) {
    System.out.println("What phrase do you want repeated?");
    phrase = userInput.nextLine();
    // VALIDATION:
    // Was anything other than a empty string (spaces)
    // or longer than 2 characters supplied?
    if (phrase.trim().equals("") || phrase.length() < 3) {
        // Nope!
        System.err.println("Invalid Input!. Enter a proper phrase!");
        phrase = "";
    }
    // Yes, allow the prompt loop to exit.
}

String phraseLoopsNumber = "";
while (phraseLoopsNumber.equals("")) {
    System.out.println("How many " + phrase + "s" + " do you want?");
    phraseLoopsNumber = userInput.nextLine();
    // VALIDATION:
    // Did the User supply a string representation of an integer value?
    if (!phraseLoopsNumber.matches("\\d+")) {
        // Nope!
        System.out.println("Invalid Input (" + phraseLoopsNumber + ")! An integer value is expected!");
        phraseLoopsNumber = "";
    }
    // Yes he/she/it did...Allow prompt loop to exit.
}

int numberOfLoops = Integer.parseInt(phraseLoopsNumber);

// Do what you have to do with the desired number of loops contained
// within the numberOfLoops integer variable.

In the above code, the String#matches() method was used along with a small Regular Expression (RegEx). The "\\d" expression passed to the matches() method checks to see if the string it is working against contains all (1 or more) digits.

If however you're hell bent on using the Scanner#nextInt() method then you can do it this way:

int numberOfLoops = -1;
while (numberOfLoops == -1) {
    System.out.println("How many " + phrase + "'s" + " do you want?");
    // Trap any input errors against the Scanner.nextInt() method...
    // This would be a form of validation.
    try {
        numberOfLoops = userInput.nextInt();
        // Consume the newline from ENTER key in case a nextLine() prompt is next.
        userInput.nextLine();
    } catch (Exception ex) {
        System.out.println("Invalid Input! An integer value is expected!");
        // Consume the newline from ENTER key in case a nextLine() prompt is next.
        // The first one above would of been skipped past if nextInt() threw an exception.
        userInput.nextLine();
        numberOfLoops = -1;
        continue;  // continue loop so as to re-prompt
    }
    // Further Validation:
    // Did the User supply a number greater than 0?
    if (numberOfLoops < 1 ) {
        // Nope!
        System.out.println("Invalid Input (" + numberOfLoops + ")! A value 1 or greater is expected!");
        numberOfLoops = -1;
    }
    // Yes he/she did...Allow prompt loop to exit.
}
// Do what you have to do with the desired number of loops contained
// within the numberOfLoops integer variable.


问:
Create a New Column by evaluating multiple columns
I have a data.frame dt_info that looks like the following:

```<code>date       col_1     col_2    col_3  ... col_100
d/m/y       info1     n/a      n/a   ...  n/a
d/m/y       n/a       n/a     info2  ...  n/a
d/m/y       n/a       n/a       n/a  ...  infon
</code>```

The output I'm looking for should be like this:

```<code>date       col_1     col_2    col_3  ... col_100    new_col
d/m/y       info1     n/a      n/a   ...  n/a         info1
d/m/y       n/a       n/a     info2  ...  n/a         info2
d/m/y       n/a       n/a       n/a  ...  infon       infon
</code>```

I'm using this code line

```<code>dt_info$new_col <- apply(dt_info[2],1, function(x){
ifelse(x != "n/a", x, "")})
</code>```

That kinda do what I want but I have two issues
I'm not able to go do it for each column using [1:n]
If I change Manually the [] index and run the code, the whole column got replaced.

What am I lacking in my script?
Is there another way to achieve what I'm trying to do?

答:
A vectorized way using max.col :

```<code>cols <- grep('col', names(dt_info))
dt_info$new_col <- dt_info[cols][cbind(1:nrow(dt_info),
                       max.col(dt_info[cols] != 'n/a', ties.method = 'first'))]
</code>```

Assuming you'll always have a non-'n/a' value in a row this will return the first one of it.

Body:
I have a data.frame dt_info that looks like the following:

date       col_1     col_2    col_3  ... col_100
d/m/y       info1     n/a      n/a   ...  n/a
d/m/y       n/a       n/a     info2  ...  n/a
d/m/y       n/a       n/a       n/a  ...  infon

The output I'm looking for should be like this:

date       col_1     col_2    col_3  ... col_100    new_col
d/m/y       info1     n/a      n/a   ...  n/a         info1
d/m/y       n/a       n/a     info2  ...  n/a         info2
d/m/y       n/a       n/a       n/a  ...  infon       infon

I'm using this code line

dt_info$new_col <- apply(dt_info[2],1, function(x){
ifelse(x != "n/a", x, "")})

That kinda do what I want but I have two issues
I'm not able to go do it for each column using [1:n]
If I change Manually the [] index and run the code, the whole column got replaced.

What am I lacking in my script?
Is there another way to achieve what I'm trying to do?

Body:
A vectorized way using max.col :

cols <- grep('col', names(dt_info))
dt_info$new_col <- dt_info[cols][cbind(1:nrow(dt_info),
                       max.col(dt_info[cols] != 'n/a', ties.method = 'first'))]

Assuming you'll always have a non-'n/a' value in a row this will return the first one of it.


问:
Express.js req.body undefined
I have this as configuration of my Express server

```<code>app.use(app.router);
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());
</code>```

But still when I ask for req.body.something in my routes I get some error pointing out that body is undefined. Here is an example of a route that uses req.body :

```<code>app.post('/admin', function(req, res){
    console.log(req.body.name);
});
</code>```

I read that this problem is caused by the lack of app.use(express.bodyParser()); but as you can see I call it before the routes.

Any clue?

答:
In my case, it was because of using body-parser after including the routes.

The correct code should be

```<code>app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(indexRoutes);
app.use(userRoutes);
app.use(adminRoutes);
</code>```

ContentLicense: CC BY-SA 3.0

Title: Express.js req.body undefined

Body:
I have this as configuration of my Express server

app.use(app.router);
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

But still when I ask for req.body.something in my routes I get some error pointing out that body is undefined. Here is an example of a route that uses req.body :

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

I read that this problem is caused by the lack of app.use(express.bodyParser()); but as you can see I call it before the routes.

Any clue?

Body:
In my case, it was because of using body-parser after including the routes.

The correct code should be

app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(indexRoutes);
app.use(userRoutes);
app.use(adminRoutes);


问:
Unable to see Notebook under Notebooks Section in AI Platform
I created a new Deep Learning VM and I'm unable to see it under AI Platform Notebooks nor I can access the proxy URL.

```<code>gcloud compute instances create nb-2 \
 --image-project=deeplearning-platform-release \
 --image-family=tf2-latest-gpu \
 --maintenance-policy TERMINATE \
 --metadata="proxy-mode=service_account,install-nvidia-driver=True" \
 --boot-disk-size 300GB \
 --zone=us-west1-a
</code>```

Serial log:

```<code>May 31 06:46:26 nb-2 c2d-startup[470]: --> /opt/c2d/scripts/02-swap-binaries.sh, exit_code=0/SUCCESS
May 31 06:46:26 nb-2 c2d-startup[470]: --> Running: /opt/c2d/scripts/03-enable-jupyter.sh
May 31 06:46:26 nb-2 c2d-startup[470]: mount: special device /dev/sdb does not exist
May 31 06:46:26 nb-2 c2d-startup[470]: mke2fs 1.43.4 (31-Jan-2017)
May 31 06:46:26 nb-2 c2d-startup[470]: The file /dev/sdb does not exist and no size was specified.
May 31 06:46:26 nb-2 c2d-startup[470]: WARNING: failed to format data disk, please ignore if this is a single disk instance
May 31 06:46:26 nb-2 c2d-startup[470]: Created symlink /etc/systemd/system/multi-user.target.wants/jupyter.service → /lib/systemd/system/jupyter.service.
May 31 06:46:26 nb-2 systemd[1]: Started Jupyter Notebook.
May 31 06:46:26 nb-2 c2d-startup[470]: --> /opt/c2d/scripts/03-enable-jupyter.sh, exit_code=0/SUCCESS
May 31 06:46:26 nb-2 c2d-startup[470]: --> Running: /opt/c2d/scripts/04-attempt-register-vm-on-proxy.sh
May 31 06:46:30 nb-2 bash[1321]: [I 06:46:30.283 LabApp] Writing notebook server cookie secret to /home/jupyter/.local/share/jupyter/runtime/notebook_cookie_secret
May 31 06:46:30 nb-2 bash[1321]: [W 06:46:30.832 LabApp] All authentication is disabled.  Anyone who can connect to this server will be able to run code.
May 31 06:46:31 nb-2 bash[1321]: [I 06:46:31.296 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.7/site-packages/jupyterlab
May 31 06:46:31 nb-2 bash[1321]: [I 06:46:31.297 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
May 31 06:46:31 nb-2 bash[1321]: [I 06:46:31.873 LabApp] [nb_conda] enabled
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.488 LabApp] ✓ nbpresent HTML export ENABLED
May 31 06:46:32 nb-2 bash[1321]: [W 06:46:32.489 LabApp] ✗ nbpresent PDF export DISABLED: No module named 'nbbrowserpdf'
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.489 LabApp] Serving notebooks from local directory: /home/jupyter
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.490 LabApp] The Jupyter Notebook is running at:
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.491 LabApp] http://localhost:8080/
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.491 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
May 31 06:46:49 nb-2 c2d-startup[470]: ERROR: (gcloud.compute.instances.describe) Could not fetch resource:
May 31 06:46:49 nb-2 c2d-startup[470]:  - Insufficient Permission: Request had insufficient authentication scopes.
May 31 06:46:49 nb-2 c2d-startup[470]: Proxy mode is service account with service account
May 31 06:46:51 nb-2 c2d-startup[470]: Copying gs://dl-platform-public-configs/proxy-agent-config.json...
May 31 06:46:51 nb-2 c2d-startup[470]: / [0 files][    0.0 B/  2.5 KiB]                                                #015/ [1 files][  2.5 KiB/  2.5 KiB]
May 31 06:46:51 nb-2 c2d-startup[470]: Operation completed over 1 objects/2.5 KiB.
May 31 06:46:51 nb-2 c2d-startup[470]: sha256:9e34ced9f64ee8efd643c60af345dcb0401f121a6d6fa3bac572c150a3010ee1: Pulling from inverting-proxy/agent
May 31 06:46:51 nb-2 c2d-startup[470]: Digest: sha256:9e34ced9f64ee8efd643c60af345dcb0401f121a6d6fa3bac572c150a3010ee1
May 31 06:46:51 nb-2 c2d-startup[470]: Status: Image is up to date for gcr.io/inverting-proxy/agent@sha256:9e34ced9f64ee8efd643c60af345dcb0401f121a6d6fa3bac572c150a3010ee1
May 31 06:46:51 nb-2 c2d-startup[470]: gcr.io/inverting-proxy/agent@sha256:9e34ced9f64ee8efd643c60af345dcb0401f121a6d6fa3bac572c150a3010ee1
May 31 06:46:52 nb-2 c2d-startup[470]: Proxy URL from the config: https://us-west1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14
May 31 06:46:52 nb-2 c2d-startup[470]: Response from the registration server: {"backendID":"336824c42b7dbf0b","hostname":"336824c42b7dbf0b-dot-us-west1.notebooks.googleusercontent.com"}
May 31 06:46:52 nb-2 c2d-startup[470]: Hostname: 336824c42b7dbf0b-dot-us-west1.notebooks.googleusercontent.com
May 31 06:46:52 nb-2 c2d-startup[470]: Backend id: 336824c42b7dbf0b
May 31 06:46:52 nb-2 c2d-startup[470]: d4d2fdc2179f2f1406e61d471c2fa9db95b332d0eb41faba44e801844fb72280
May 31 06:46:53 nb-2 containerd[669]: time="2020-05-31T06:46:53.051564534Z" level=info msg="shim containerd-shim started" address="/containerd-shim/moby/d4d2fdc2179f2f1406e61d471c2fa9db95b332d0eb41faba44e801844fb72280/shim.sock" debug=false pid=1706
May 31 06:47:14 nb-2 c2d-startup[470]: ERROR: (gcloud.compute.instances.add-metadata) Could not fetch resource:
May 31 06:47:14 nb-2 c2d-startup[470]:  - Insufficient Permission: Request had insufficient authentication scopes.
May 31 06:47:14 nb-2 c2d-startup[470]: --> /opt/c2d/scripts/04-attempt-register-vm-on-proxy.sh, exit_code=1/FAILURE
May 31 06:47:14 nb-2 c2d-startup[470]: --> Running: /opt/c2d/scripts/05-set-metadata.sh
May 31 06:47:14 nb-2 c2d-startup[470]: Instance title: TensorFlow2.1/Keras.CUDA10.1
May 31 06:47:14 nb-2 c2d-startup[470]: Instance version: 46
May 31 06:47:14 nb-2 c2d-startup[470]: Instance framework: TensorFlow:2.1
May 31 06:47:35 nb-2 c2d-startup[470]: ERROR: (gcloud.compute.instances.add-metadata) Could not fetch resource:
May 31 06:47:35 nb-2 c2d-startup[470]:  - Insufficient Permission: Request had insufficient authentication scopes.
</code>```

答:
You need to include the scopes when creating the instance, for example:

```<code>gcloud compute instances create nb-1 \
 --image-project=deeplearning-platform-release \
 --image-family=tf2-latest-gpu \
 --maintenance-policy TERMINATE \
 --metadata="proxy-mode=service_account,install-nvidia-driver=True" \
 --boot-disk-size 300GB \
 --scopes=https://www.googleapis.com/auth/cloud-platform \
 --zone=us-west1-a
</code>```

Body:
I created a new Deep Learning VM and I'm unable to see it under AI Platform Notebooks nor I can access the proxy URL.

gcloud compute instances create nb-2 \
 --image-project=deeplearning-platform-release \
 --image-family=tf2-latest-gpu \
 --maintenance-policy TERMINATE \
 --metadata="proxy-mode=service_account,install-nvidia-driver=True" \
 --boot-disk-size 300GB \
 --zone=us-west1-a

Serial log:

May 31 06:46:26 nb-2 c2d-startup[470]: --> /opt/c2d/scripts/02-swap-binaries.sh, exit_code=0/SUCCESS
May 31 06:46:26 nb-2 c2d-startup[470]: --> Running: /opt/c2d/scripts/03-enable-jupyter.sh
May 31 06:46:26 nb-2 c2d-startup[470]: mount: special device /dev/sdb does not exist
May 31 06:46:26 nb-2 c2d-startup[470]: mke2fs 1.43.4 (31-Jan-2017)
May 31 06:46:26 nb-2 c2d-startup[470]: The file /dev/sdb does not exist and no size was specified.
May 31 06:46:26 nb-2 c2d-startup[470]: WARNING: failed to format data disk, please ignore if this is a single disk instance
May 31 06:46:26 nb-2 c2d-startup[470]: Created symlink /etc/systemd/system/multi-user.target.wants/jupyter.service → /lib/systemd/system/jupyter.service.
May 31 06:46:26 nb-2 systemd[1]: Started Jupyter Notebook.
May 31 06:46:26 nb-2 c2d-startup[470]: --> /opt/c2d/scripts/03-enable-jupyter.sh, exit_code=0/SUCCESS
May 31 06:46:26 nb-2 c2d-startup[470]: --> Running: /opt/c2d/scripts/04-attempt-register-vm-on-proxy.sh
May 31 06:46:30 nb-2 bash[1321]: [I 06:46:30.283 LabApp] Writing notebook server cookie secret to /home/jupyter/.local/share/jupyter/runtime/notebook_cookie_secret
May 31 06:46:30 nb-2 bash[1321]: [W 06:46:30.832 LabApp] All authentication is disabled.  Anyone who can connect to this server will be able to run code.
May 31 06:46:31 nb-2 bash[1321]: [I 06:46:31.296 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.7/site-packages/jupyterlab
May 31 06:46:31 nb-2 bash[1321]: [I 06:46:31.297 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
May 31 06:46:31 nb-2 bash[1321]: [I 06:46:31.873 LabApp] [nb_conda] enabled
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.488 LabApp] ✓ nbpresent HTML export ENABLED
May 31 06:46:32 nb-2 bash[1321]: [W 06:46:32.489 LabApp] ✗ nbpresent PDF export DISABLED: No module named 'nbbrowserpdf'
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.489 LabApp] Serving notebooks from local directory: /home/jupyter
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.490 LabApp] The Jupyter Notebook is running at:
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.491 LabApp] http://localhost:8080/
May 31 06:46:32 nb-2 bash[1321]: [I 06:46:32.491 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
May 31 06:46:49 nb-2 c2d-startup[470]: ERROR: (gcloud.compute.instances.describe) Could not fetch resource:
May 31 06:46:49 nb-2 c2d-startup[470]:  - Insufficient Permission: Request had insufficient authentication scopes.
May 31 06:46:49 nb-2 c2d-startup[470]: Proxy mode is service account with service account
May 31 06:46:51 nb-2 c2d-startup[470]: Copying gs://dl-platform-public-configs/proxy-agent-config.json...
May 31 06:46:51 nb-2 c2d-startup[470]: / [0 files][    0.0 B/  2.5 KiB]                                                #015/ [1 files][  2.5 KiB/  2.5 KiB]
May 31 06:46:51 nb-2 c2d-startup[470]: Operation completed over 1 objects/2.5 KiB.
May 31 06:46:51 nb-2 c2d-startup[470]: sha256:9e34ced9f64ee8efd643c60af345dcb0401f121a6d6fa3bac572c150a3010ee1: Pulling from inverting-proxy/agent
May 31 06:46:51 nb-2 c2d-startup[470]: Digest: sha256:9e34ced9f64ee8efd643c60af345dcb0401f121a6d6fa3bac572c150a3010ee1
May 31 06:46:51 nb-2 c2d-startup[470]: Status: Image is up to date for gcr.io/inverting-proxy/agent@sha256:9e34ced9f64ee8efd643c60af345dcb0401f121a6d6fa3bac572c150a3010ee1
May 31 06:46:51 nb-2 c2d-startup[470]: gcr.io/inverting-proxy/agent@sha256:9e34ced9f64ee8efd643c60af345dcb0401f121a6d6fa3bac572c150a3010ee1
May 31 06:46:52 nb-2 c2d-startup[470]: Proxy URL from the config: https://us-west1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14
May 31 06:46:52 nb-2 c2d-startup[470]: Response from the registration server: {"backendID":"336824c42b7dbf0b","hostname":"336824c42b7dbf0b-dot-us-west1.notebooks.googleusercontent.com"}
May 31 06:46:52 nb-2 c2d-startup[470]: Hostname: 336824c42b7dbf0b-dot-us-west1.notebooks.googleusercontent.com
May 31 06:46:52 nb-2 c2d-startup[470]: Backend id: 336824c42b7dbf0b
May 31 06:46:52 nb-2 c2d-startup[470]: d4d2fdc2179f2f1406e61d471c2fa9db95b332d0eb41faba44e801844fb72280
May 31 06:46:53 nb-2 containerd[669]: time="2020-05-31T06:46:53.051564534Z" level=info msg="shim containerd-shim started" address="/containerd-shim/moby/d4d2fdc2179f2f1406e61d471c2fa9db95b332d0eb41faba44e801844fb72280/shim.sock" debug=false pid=1706
May 31 06:47:14 nb-2 c2d-startup[470]: ERROR: (gcloud.compute.instances.add-metadata) Could not fetch resource:
May 31 06:47:14 nb-2 c2d-startup[470]:  - Insufficient Permission: Request had insufficient authentication scopes.
May 31 06:47:14 nb-2 c2d-startup[470]: --> /opt/c2d/scripts/04-attempt-register-vm-on-proxy.sh, exit_code=1/FAILURE
May 31 06:47:14 nb-2 c2d-startup[470]: --> Running: /opt/c2d/scripts/05-set-metadata.sh
May 31 06:47:14 nb-2 c2d-startup[470]: Instance title: TensorFlow2.1/Keras.CUDA10.1
May 31 06:47:14 nb-2 c2d-startup[470]: Instance version: 46
May 31 06:47:14 nb-2 c2d-startup[470]: Instance framework: TensorFlow:2.1
May 31 06:47:35 nb-2 c2d-startup[470]: ERROR: (gcloud.compute.instances.add-metadata) Could not fetch resource:
May 31 06:47:35 nb-2 c2d-startup[470]:  - Insufficient Permission: Request had insufficient authentication scopes.

Body:
You need to include the scopes when creating the instance, for example:

gcloud compute instances create nb-1 \
 --image-project=deeplearning-platform-release \
 --image-family=tf2-latest-gpu \
 --maintenance-policy TERMINATE \
 --metadata="proxy-mode=service_account,install-nvidia-driver=True" \
 --boot-disk-size 300GB \
 --scopes=https://www.googleapis.com/auth/cloud-platform \
 --zone=us-west1-a


问:
Modal not showing up in react with react-bootstrap
I am trying to create a modal to have a login/register pop-up when clicking on the NavBar.Item Login/Register.

My modal is defined as below:

```<code>import React from "react";
import '../assets/styles/GenericTheme.css'
import { Modal } from "react-bootstrap";

class LoginRegisterModal extends React.Component {
    constructor(props, context) {
        super(props);
        this.state = {show: false};
    }

    open = () => {
        this.setState({show: true});
    }

    close = () => {
        this.setState({show: false});
    }

    render() {
        return (
     //   <Modal show={this.state.show} onHide={this.close} dialogClassName="popup-inner">
        <Modal show={this.state.show} fade={false} style={{width: "200px", display: "block"}}>
            <Modal.Body>test</Modal.Body>
        </Modal>
        );
    }
}

export default LoginRegisterModal;
</code>```

In the NavBar, I have added the reference to the Modal as below:

```<code>import React, {}  from 'react';
import { Navbar, Nav, NavDropdown } from 'react-bootstrap';
import SearchForm from '../HeaderFooter/SearchForm';
import SiteLogo from '../../assets/images/village-logo.svg';
import '../../assets/styles/HeaderTheme.css'
import LoginRegisterModal from '../LoginRegisterModal';

class NavHeader extends React.Component {

    constructor(props, context) {
        super(props);
        this.state = {showLogin: false};
    }

    openLogin = () => {
        this.setState({showLogin: !this.state.showLogin});
    }

    render() {
        return (
            <div>
            <Navbar className="village-header" width="100" expand="lg">
                <Navbar.Brand href="/">
                    <img
                        src= { SiteLogo }
                        width="214"
                        height="28"
                        className="d-inline-block align-top"
                        alt="Village"
                    />
                </Navbar.Brand>
                <SearchForm />
                <Navbar.Toggle aria-controls="basic-navbar-nav" />
                <Navbar.Collapse id="basic-navbar-nav">
                    <Nav className="mr-auto village-header">
                    <Nav.Link href="/discover">Discover</Nav.Link>
                    <Nav.Link href="/create">Create</Nav.Link>
                    <Nav.Link href="/howitworks">How it Works</Nav.Link>
                    <Nav.Link ref="LoginRegisterModal" eventKey={1} href="#" onClick={this.openLogin}>Login/Register</Nav.Link>
                    <NavDropdown title="Profile" id="basic-nav-dropdown">
                        <NavDropdown.Item>Firstname LastName</NavDropdown.Item>
                        <NavDropdown.Divider />
                        <NavDropdown.Item href="/profile">Profile</NavDropdown.Item>
                        <NavDropdown.Item href="/messages">Messages</NavDropdown.Item>
                        <NavDropdown.Item href="/settings">Settings</NavDropdown.Item>
                        <NavDropdown.Item href="/logout">Logout</NavDropdown.Item>
                    </NavDropdown>
                    </Nav>
                </Navbar.Collapse>
            </Navbar>
            <LoginRegisterModal show={this.state.showLogin} />
            </div>
            );
        }
}

export default NavHeader;

</code>```

When I click on the Login/Register:

Login/Register

nothing happens, no pop-up or modal is shown. Also I have added the line below in the NavBar

<LoginRegisterModal show={this.state.showLogin} /> but nothin change. I tried also by adding a className and forcing the z-layer to 2 but it's not working as well.

Any ideas ?
Regards

答:
Your modal component isn't "listening" for any passed props, i.e. the show prop being passed from NavHeader. A quick dirty would be to implement the componentDidUpdate lifecycle function to check for the show prop value change. Also use the show prop value to set initial state in the case it's displayed open upon mounting.

```<code>class LoginRegisterModal extends React.Component {
  constructor(props, context) {
    super(props);
    this.state = {
      show: props.show, // use the initial show value
    };
  }

  open = () => {
    this.setState({ show: true });
  }

  close = () => {
    this.setState({ show: false });
  }

  componentDidUpdate(prevProps) {
    const { show } = this.props;
    if (prevProps.show !== show) {
      if (show) {
        open(); // open if parent says to
      } else {
        close(); // close if parent says to
      }
    }
  }

  render() {
    return (
    //   <Modal
    //     show={this.state.show}
    //     onHide={this.close}
    //     dialogClassName="popup-inner"
    //   >
      <Modal
        show={this.state.show}
        fade={false}
        style={{width: "200px", display: "block"}}
      >
        <Modal.Body>test</Modal.Body>
      </Modal>
    );
  }
}
</code>```

This allows the parent to to toggle the modal's display state, but what if the modal is closed/dismissed from within. You may want some way to signal back out to the NavHeader that the modal was closed so it can "sync" its state. The onHide prop  does that, and you have it commented out. I suggest also exposing out to the LoginRegisterModal API an onHide prop.

```<code>close = () => {
  this.setState({show: false});
  this.props.onHide();
}
</code>```

The the parent uses as such

```<code><LoginRegisterModal
  show={this.state.showLogin}
  onHide={() => this.setState({ showLogin: false })}
/>
</code>```

This however, creates code duplication. It may be a better design to make LoginRegisterModal a controlled component and simply pass the show and onHide props passed from NavHeader to the internal Modal component of LoginRegisterModal.

```<code>const LoginRegisterModal = props => (
  <Modal
    // pass props on through to Modal
    {...props}
    // set any props here that you don't want "overridable" by passed props
    fade={false}
    style={{ width: "200px", display: "block" }}
  >
    <Modal.Body>test</Modal.Body>
  </Modal>
);
</code>```

Body:
I am trying to create a modal to have a login/register pop-up when clicking on the NavBar.Item Login/Register.

My modal is defined as below:

import React from "react";
import '../assets/styles/GenericTheme.css'
import { Modal } from "react-bootstrap";

class LoginRegisterModal extends React.Component {
    constructor(props, context) {
        super(props);
        this.state = {show: false};
    }

    open = () => {
        this.setState({show: true});
    }

    close = () => {
        this.setState({show: false});
    }

    render() {
        return (
     //   <Modal show={this.state.show} onHide={this.close} dialogClassName="popup-inner">
        <Modal show={this.state.show} fade={false} style={{width: "200px", display: "block"}}>
            <Modal.Body>test</Modal.Body>
        </Modal>
        );
    }
}

export default LoginRegisterModal;

In the NavBar, I have added the reference to the Modal as below:

import React, {}  from 'react';
import { Navbar, Nav, NavDropdown } from 'react-bootstrap';
import SearchForm from '../HeaderFooter/SearchForm';
import SiteLogo from '../../assets/images/village-logo.svg';
import '../../assets/styles/HeaderTheme.css'
import LoginRegisterModal from '../LoginRegisterModal';

class NavHeader extends React.Component {

    constructor(props, context) {
        super(props);
        this.state = {showLogin: false};
    }

    openLogin = () => {
        this.setState({showLogin: !this.state.showLogin});
    }

    render() {
        return (

            <Navbar className="village-header" width="100" expand="lg">
                <Navbar.Brand href="/">

                </Navbar.Brand>
                <SearchForm />
                <Navbar.Toggle aria-controls="basic-navbar-nav" />
                <Navbar.Collapse id="basic-navbar-nav">

                    Discover
                    Create
                    How it Works
                    Login/Register
                    <NavDropdown title="Profile" id="basic-nav-dropdown">
                        <NavDropdown.Item>Firstname LastName</NavDropdown.Item>
                        <NavDropdown.Divider />
                        <NavDropdown.Item href="/profile">Profile</NavDropdown.Item>
                        <NavDropdown.Item href="/messages">Messages</NavDropdown.Item>
                        <NavDropdown.Item href="/settings">Settings</NavDropdown.Item>
                        <NavDropdown.Item href="/logout">Logout</NavDropdown.Item>
                    </NavDropdown>

                </Navbar.Collapse>
            </Navbar>
            <LoginRegisterModal show={this.state.showLogin} />

            );
        }
}

export default NavHeader;

When I click on the Login/Register:

Login/Register

nothing happens, no pop-up or modal is shown. Also I have added the line below in the NavBar

<LoginRegisterModal show={this.state.showLogin} /> but nothin change. I tried also by adding a className and forcing the z-layer to 2 but it's not working as well.

Any ideas ?
Regards

Body:
Your modal component isn't "listening" for any passed props, i.e. the show prop being passed from NavHeader. A quick dirty would be to implement the componentDidUpdate lifecycle function to check for the show prop value change. Also use the show prop value to set initial state in the case it's displayed open upon mounting.

class LoginRegisterModal extends React.Component {
  constructor(props, context) {
    super(props);
    this.state = {
      show: props.show, // use the initial show value
    };
  }

  open = () => {
    this.setState({ show: true });
  }

  close = () => {
    this.setState({ show: false });
  }

  componentDidUpdate(prevProps) {
    const { show } = this.props;
    if (prevProps.show !== show) {
      if (show) {
        open(); // open if parent says to
      } else {
        close(); // close if parent says to
      }
    }
  }

  render() {
    return (
    //   <Modal
    //     show={this.state.show}
    //     onHide={this.close}
    //     dialogClassName="popup-inner"
    //   >
      <Modal
        show={this.state.show}
        fade={false}
        style={{width: "200px", display: "block"}}
      >
        <Modal.Body>test</Modal.Body>
      </Modal>
    );
  }
}

This allows the parent to to toggle the modal's display state, but what if the modal is closed/dismissed from within. You may want some way to signal back out to the NavHeader that the modal was closed so it can "sync" its state. The onHide prop  does that, and you have it commented out. I suggest also exposing out to the LoginRegisterModal API an onHide prop.

close = () => {
  this.setState({show: false});
  this.props.onHide();
}

The the parent uses as such

<LoginRegisterModal
  show={this.state.showLogin}
  onHide={() => this.setState({ showLogin: false })}
/>

This however, creates code duplication. It may be a better design to make LoginRegisterModal a controlled component and simply pass the show and onHide props passed from NavHeader to the internal Modal component of LoginRegisterModal.

const LoginRegisterModal = props => (
  <Modal
    // pass props on through to Modal
    {...props}
    // set any props here that you don't want "overridable" by passed props
    fade={false}
    style={{ width: "200px", display: "block" }}
  >
    <Modal.Body>test</Modal.Body>
  </Modal>
);


问:
Can't get <select> input from form?
I can figure out how to loop through input and select. My function below does not include select lists.

Any help welcome.

```<code>$('input', '#consumer_form').each(function(key, value)
{
    if ((this.type === "radio" || this.type === "checkbox") && this.checked === false) {
        return;
    } else {
         val = this.value;
    }

         //alert($('#'+this.id).attr('name')+'='+replaceAmp(val));
             formData += '&'+this.name+'='+replaceAmp(val);

});
</code>```

Thanks

答:
With jQuery you can get all input and select elements by doing this:

```<code>$('input, select')
</code>```

So you would need to do something like

```<code>$('input, select').each(function(key, value) {
     if ($(this).is('select')) do_select_stuff();
     else if ($(this).is(':checkbox')) do_checkbox_stuff();
     else if ($(this).is(':radio')) do_radio_stuff();
});
</code>```

Title: Can't get <select> input from form?

Body:
I can figure out how to loop through input and select. My function below does not include select lists.

Any help welcome.

$('input', '#consumer_form').each(function(key, value)
{
    if ((this.type === "radio" || this.type === "checkbox") && this.checked === false) {
        return;
    } else {
         val = this.value;
    }

         //alert($('#'+this.id).attr('name')+'='+replaceAmp(val));
             formData += '&'+this.name+'='+replaceAmp(val);

});

Thanks

Body:
With jQuery you can get all input and select elements by doing this:

$('input, select')

So you would need to do something like

$('input, select').each(function(key, value) {
     if ($(this).is('select')) do_select_stuff();
     else if ($(this).is(':checkbox')) do_checkbox_stuff();
     else if ($(this).is(':radio')) do_radio_stuff();
});


问:
Scroll down to element with a class name on Vuejs component
I have a component with unordered list and what I want to do is when component is loaded I want the component to be scrolled down to <li> element with a class name 'actual-month' so it can be visible. </p>

```<code><b-card no-body header="<i class='fa fa-align-justify'></i> Unorderd List"  style="height: 680px">
          <b-tabs card pills>
              <b-tab v-for="debt in user_debts"  :title="Debts list"  :key="debt.id" class="card-height">
                 <table class="table table-sm amortization-header header-fixed">
                  <thead>
                      <tr>
                        <th>Month</th>
                        <th>Balance</th>
                        <th>Paid</th>
                        <th>Debt</th>
                        <th>Nominal Interest</th>
                      </tr>
                  </thead>
                  <tbody>
                    <tr v-for="month in amortization.schedule" :class="{'actual-month' : month.month == amortization.actual_month}">
                      <td>{{month.month}}</td>
                      <td>{{month.balance.toLocaleString()}}<span class="total">€</span></td>
                      <td>{{month.monthly_payment}}<span class="total">€</span></td>
                      <td>{{month.principle}}<span class="total">€</span></td>
                      <td>{{month.interest}}<span class="total">€</span></td>
                    </tr>
                  </tbody>
                </table>
              </b-tab>
          </b-tabs>
        </b-card>
</code>```

答:
Adding to Julien's answer, for a lot of use cases, animating automated actions such as jumping to a part of a page, smooth scrolling improves ux:</p>
```<code>el.scrollIntoView({ behavior: 'smooth' })
</code>```

Body:
I have a component with unordered list and what I want to do is when component is loaded I want the component to be scrolled down to
 element with a class name 'actual-month' so it can be visible.

<b-card no-body header=" Unorderd List"  style="height: 680px">

                        Month
                        Balance
                        Paid
                        Debt
                        Nominal Interest

                      {{month.month}}
                      {{month.balance.toLocaleString()}}€
                      {{month.monthly_payment}}€
                      {{month.principle}}€
                      {{month.interest}}€

Body:
Adding to Julien's answer, for a lot of use cases, animating automated actions such as jumping to a part of a page, smooth scrolling improves ux:

el.scrollIntoView({ behavior: 'smooth' })


问:
What is the proper way to stack ASM visitors?
I have the following code:

```<code>for (Map.Entry<String, ClassReader> e : classes.entrySet())
{
    ClassReader reader = e.getValue();
    ClassWriter writer = new ClassWriter(Opcodes.ASM7);

    // Process all visitors
    reader.accept(new StringRemapper(writer, "String A", "String A!!"), ClassReader.EXPAND_FRAMES);
    reader.accept(new StringRemapper(writer, "String B", "String B!!"), ClassReader.EXPAND_FRAMES);

    // Update the class
    reader = new ClassReader(writer.toByteArray());
    e.setValue(reader);
}
</code>```

The issue with the code above is that it is writing everything twice, because there are two visitors writing to the same writer (I guess).

To fix this issue, I need to add the code below after every reader.accept:

```<code>reader = new ClassReader(writer.toByteArray());
writer = new ClassWriter(Opcodes.ASM7);
</code>```

The thing is, by doing so, am I misusing the visitor pattern? I mean, why do I need to create a new reader/writer and visit it only once? Shouldn't I be able to have multiple visitors?

I found this similar question Easy way to stack up a couple of ASM-Bytecode visitors? but couldn't understand the accepted answer.

I tried to pass the first visitor as a parameter to the second instead of the original ClassWriter, had the same result, duplicated code.

```<code>ClassVisitor last;
// Process all visitors
reader.accept(last = new StringRemapper(writer, "String A", "String A!!"), ClassReader.EXPAND_FRAMES);
reader.accept(new StringRemapper(last, "String B", "String B!!"), ClassReader.EXPAND_FRAMES);
</code>```

答:
You are right, you did miss something: The ClassWriter is a ClassVisitor itself.

The right way to stack the visitors is to pass it's parent visitor to the constructor:

```<code>// The root visitor is the ClassWriter
ClassVisitor cv = writer;

// Add a visitor
cv = new StringRemapper(cv, "String A", "String A!!");
// Add another one
cv = new StringRemapper(cv, "String B", "String B!!");
// maybe add more?

// Process them
reader.accept(cv, ClassReader.EXPAND_FRAMES);
byte[] classFile = writer.toByteArray();
</code>```

If your StringRemapper only takes a ClassWriter as parameter, then you should change it to accept ClassVisitors instread.

Another thing I noticed is your classes variable: It contains ClassReaders as values.

It might be an easier design to use ClassVisitors as value - with an initial ClassWriter value.

But this is a bigger design change.

Body:
I have the following code:

for (Map.Entry<String, ClassReader> e : classes.entrySet())
{
    ClassReader reader = e.getValue();
    ClassWriter writer = new ClassWriter(Opcodes.ASM7);

    // Process all visitors
    reader.accept(new StringRemapper(writer, "String A", "String A!!"), ClassReader.EXPAND_FRAMES);
    reader.accept(new StringRemapper(writer, "String B", "String B!!"), ClassReader.EXPAND_FRAMES);

    // Update the class
    reader = new ClassReader(writer.toByteArray());
    e.setValue(reader);
}

The issue with the code above is that it is writing everything twice, because there are two visitors writing to the same writer (I guess).

To fix this issue, I need to add the code below after every reader.accept:

reader = new ClassReader(writer.toByteArray());
writer = new ClassWriter(Opcodes.ASM7);

The thing is, by doing so, am I misusing the visitor pattern? I mean, why do I need to create a new reader/writer and visit it only once? Shouldn't I be able to have multiple visitors?

I found this similar question Easy way to stack up a couple of ASM-Bytecode visitors? but couldn't understand the accepted answer.

I tried to pass the first visitor as a parameter to the second instead of the original ClassWriter, had the same result, duplicated code.

ClassVisitor last;
// Process all visitors
reader.accept(last = new StringRemapper(writer, "String A", "String A!!"), ClassReader.EXPAND_FRAMES);
reader.accept(new StringRemapper(last, "String B", "String B!!"), ClassReader.EXPAND_FRAMES);

Body:
You are right, you did miss something: The ClassWriter is a ClassVisitor itself.

The right way to stack the visitors is to pass it's parent visitor to the constructor:

// The root visitor is the ClassWriter
ClassVisitor cv = writer;

// Add a visitor
cv = new StringRemapper(cv, "String A", "String A!!");
// Add another one
cv = new StringRemapper(cv, "String B", "String B!!");
// maybe add more?

// Process them
reader.accept(cv, ClassReader.EXPAND_FRAMES);
byte[] classFile = writer.toByteArray();

If your StringRemapper only takes a ClassWriter as parameter, then you should change it to accept ClassVisitors instread.

Another thing I noticed is your classes variable: It contains ClassReaders as values.

It might be an easier design to use ClassVisitors as value - with an initial ClassWriter value.

But this is a bigger design change.


问:
Stripe saying 'Payment not completed' Stripe connect php
When transferring money to a connected account on Stripe using this code

```<code>// // Create a PaymentIntent:
$method = \Stripe\PaymentMethod::create([
  'type' => 'card',
  'card' => [
    'number' => '4242424242424242',
    'exp_month' => 12,
    'exp_year' => 2020,
    'cvc' => '314',
  ],
]);

$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => $AMOUNT1,
'currency' => 'nzd',
'payment_method_types' => ['card'],
'payment_method' => $method->id,
'customer' => CUSTOMER_ID,
'transfer_group' => '{ORDER'.$_SESSION['order_id'].'}',
]);

// Create a Transfer to a connected account (later):
$transfer = \Stripe\Transfer::create([
'amount' => $AMOUNT2,
'currency' => 'nzd',
'destination' => $ACC_ID,
'transfer_group' => '{ORDER'.$_SESSION['order_id'].'}',
]);
</code>```

The payment stores on the connected account's dashboard and says its completed but when it stores on my Payments tab it says that the payment is incomplete and that the buyer has not completed the payment

Prev1
Prev2

答:
You need to confirm the payment intent, either by providing confirm=true at creation or by making a call to /confirm.

You're creating a transfer from your account to the connected one, which succeeds, and a payment that you never complete.

Body:
When transferring money to a connected account on Stripe using this code

// // Create a PaymentIntent:
$method = \Stripe\PaymentMethod::create([
  'type' => 'card',
  'card' => [
    'number' => '4242424242424242',
    'exp_month' => 12,
    'exp_year' => 2020,
    'cvc' => '314',
  ],
]);

$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => $AMOUNT1,
'currency' => 'nzd',
'payment_method_types' => ['card'],
'payment_method' => $method->id,
'customer' => CUSTOMER_ID,
'transfer_group' => '{ORDER'.$_SESSION['order_id'].'}',
]);

// Create a Transfer to a connected account (later):
$transfer = \Stripe\Transfer::create([
'amount' => $AMOUNT2,
'currency' => 'nzd',
'destination' => $ACC_ID,
'transfer_group' => '{ORDER'.$_SESSION['order_id'].'}',
]);

The payment stores on the connected account's dashboard and says its completed but when it stores on my Payments tab it says that the payment is incomplete and that the buyer has not completed the payment

Prev1
Prev2


问:
Efficient Dictionary lookup
For my C++ application, there is a requirement to check if a word is a valid English dictionary word or not. What is the best way to do it. Is there freely available dictionary that I can make use of. I just need a collection of all possible words. How to make this lookup least expensive. Do I need to hash it. </p>

答:
Use either a std::set<std::string> or a std::unordered_set<std::string>.  The latter is new in C++0x and may or may not be supported by your C++ Standard Library implementation; if it does not support it, it may include a hash_set of some kind:  consult your documentation to find out.

Which of these (set, which uses a binary search tree, and unordered_set, which uses a hashtable) is more efficient depends on the number of elements you are storing in the container and how your Standard Library implementation implements them.  Your best bet is to try both and see which performs better for your specific scenario.

Alternatively, if the list of words is fixed, you might consider using a sorted std::vector and using std::binary_search to find words in it.

Title: Efficient Dictionary lookup


问:
PyTorch paste values into tensor by row index with increasing column index
I have a tensor output into which I want to put some values. I know the row that each value should go in, but I don't have an index tensor describing the columns. Instead, if there are k values that belong to one row, they should go in columns 0, 1, ..., k-1. This is perhaps better explained with an example:

import torch

n = 4
max_cols = 5
output = torch.zeros(n, max_cols)
row_idx = torch.tensor([0, 0, 0, 0, 1, 1, 2, 2, 2, 3])
values = torch.arange(len(row_idx)).float() # the values could be anything, not just arange
# output[??] = values
```

<p>Here the first 4 values should be in output at [0, 0], ... [0, 3], the next 2 values at [1, 0], [1, 1], and so on.</p>

<p>Here's how I'm doing this now</p>

<pre class="lang-py prettyprint-override"><code>_, counts = torch.unique(row_idx, return_counts=True)
range_ = torch.arange(max_cols)
col_idx = torch.cat([range_[:c] for c in counts])
output[row_idx, col_idx] = values
output
</code>```

```<code>tensor([[0., 1., 2., 3., 0.],
        [4., 5., 0., 0., 0.],
        [6., 7., 8., 0., 0.],
        [9., 0., 0., 0., 0.]])
</code>```

Is there any more efficient way to paste these values into the appropriate positions?

(feel free to suggest a better title for this if you can think of one)

答:
I think your solution has linear time complexity. So, I am not sure if it can be further improved. However, I think the solution you provided is not correct. Let me give an example.

For the following input:

```<code>row_idx = torch.tensor([0, 0, 1, 0, 0, 1, 2, 2, 2, 3])
</code>```

Your solution outputs the following.

```<code>tensor([[4., 1., 3., 3., 0.],
        [2., 5., 2., 0., 0.],
        [6., 7., 8., 0., 0.],
        [9., 0., 0., 0., 0.]])
</code>```

However, I think your expected output is:

```<code>tensor([[0., 1., 3., 4., 0.],
        [2., 5., 0., 0., 0.],
        [6., 7., 8., 0., 0.],
        [9., 0., 0., 0., 0.]])
</code>```

So, I suggest the following solution that I believe is correct.

```<code>def helper(a):
    idx = a.cumsum(-1)
    id_arr = torch.ones(idx[-1], dtype=int)
    id_arr[0] = 0
    id_arr[idx[:-1]] = -a[:-1]+1
    return id_arr.cumsum(-1)

n = 4
max_cols = 5
output = torch.zeros(n, max_cols)
row_idx = torch.tensor([0, 0, 1, 0, 0, 1, 2, 2, 2, 3])
values = torch.arange(len(row_idx)).float()

count = torch.unique(row_idx, return_counts=True)[1]
col_idx = helper(count)[row_idx.argsort().argsort()]
output[row_idx, col_idx] = values
print(output)
</code>```

Update

You can simply add one line to your code as follows to make it work correctly.

```<code>_, counts = torch.unique(row_idx, return_counts=True)
range_ = torch.arange(max_cols)
col_idx = torch.cat([range_[:c] for c in counts])
col_idx = col_idx[row_idx.argsort().argsort()] # <== UPDATE
output[row_idx, col_idx] = values
print(output)
</code>```

Body:
I have a tensor output into which I want to put some values. I know the row that each value should go in, but I don't have an index tensor describing the columns. Instead, if there are k values that belong to one row, they should go in columns 0, 1, ..., k-1. This is perhaps better explained with an example:

import torch

n = 4
max_cols = 5
output = torch.zeros(n, max_cols)
row_idx = torch.tensor([0, 0, 0, 0, 1, 1, 2, 2, 2, 3])
values = torch.arange(len(row_idx)).float() # the values could be anything, not just arange
# output[??] = values

Here the first 4 values should be in output at [0, 0], ... [0, 3], the next 2 values at [1, 0], [1, 1], and so on.

Here's how I'm doing this now

_, counts = torch.unique(row_idx, return_counts=True)
range_ = torch.arange(max_cols)
col_idx = torch.cat([range_[:c] for c in counts])
output[row_idx, col_idx] = values
output

tensor([[0., 1., 2., 3., 0.],
        [4., 5., 0., 0., 0.],
        [6., 7., 8., 0., 0.],
        [9., 0., 0., 0., 0.]])

Is there any more efficient way to paste these values into the appropriate positions?

(feel free to suggest a better title for this if you can think of one)

Body:
I think your solution has linear time complexity. So, I am not sure if it can be further improved. However, I think the solution you provided is not correct. Let me give an example.

For the following input:

row_idx = torch.tensor([0, 0, 1, 0, 0, 1, 2, 2, 2, 3])

Your solution outputs the following.

tensor([[4., 1., 3., 3., 0.],
        [2., 5., 2., 0., 0.],
        [6., 7., 8., 0., 0.],
        [9., 0., 0., 0., 0.]])

However, I think your expected output is:

tensor([[0., 1., 3., 4., 0.],
        [2., 5., 0., 0., 0.],
        [6., 7., 8., 0., 0.],
        [9., 0., 0., 0., 0.]])

So, I suggest the following solution that I believe is correct.

def helper(a):
    idx = a.cumsum(-1)
    id_arr = torch.ones(idx[-1], dtype=int)
    id_arr[0] = 0
    id_arr[idx[:-1]] = -a[:-1]+1
    return id_arr.cumsum(-1)

n = 4
max_cols = 5
output = torch.zeros(n, max_cols)
row_idx = torch.tensor([0, 0, 1, 0, 0, 1, 2, 2, 2, 3])
values = torch.arange(len(row_idx)).float()

count = torch.unique(row_idx, return_counts=True)[1]
col_idx = helper(count)[row_idx.argsort().argsort()]
output[row_idx, col_idx] = values
print(output)

Update

You can simply add one line to your code as follows to make it work correctly.

_, counts = torch.unique(row_idx, return_counts=True)
range_ = torch.arange(max_cols)
col_idx = torch.cat([range_[:c] for c in counts])
col_idx = col_idx[row_idx.argsort().argsort()] # <== UPDATE
output[row_idx, col_idx] = values
print(output)


问:
JFrog Artifactory intermittently rejects authentication with 403 forbidden
I am having a hard time configuring zypper clients (SLES and OpenSUSE) to work with our RPM Repository in JFrog due to some "authentication" issues. At first, I thought it was just an issue with zypper and opensuse so I first focused on our efforts to make things work with zypper. This was the previous question.

But these authentication-related errors come up every now and then with yum clients as well (centOS), although not that often.

So I tried doing man-in-the-middle to see what's happening under the hood, and this is the sequence with zypper:

Scenario 1 - successful authentication

The following is the sequence of a zypper refresh --repo myrepo:

(1) zypper sends an HTTP HEAD request with the base64-encoded username::

```<code>HEAD /myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml HTTP/1.1
Host: rpm.example.com
Authorization: Basic dXNlcm5hbWU6
User-Agent: ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
Accept: */*
Connection: close
</code>```

(2) jfrog responds with HTTP 401 Unauthorized with the WWW-Authenticate header:

```<code>HTTP/1.1 401 Unauthorized
Date: Thu, 28 May 2020 08:20:04 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
WWW-Authenticate: Basic realm="Artifactory Realm"
</code>```

(3) zypper sends another HTTP HEAD request, this time with the base64-encoded username:password:

```<code>HEAD /myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml HTTP/1.1
Host: rpm.example.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
User-Agent: ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
Accept: */*
Connection: close
</code>```

(4) jfrog finally responds with an HTTP 200.

```<code>HTTP/1.1 200 OK
Date: Thu, 28 May 2020 08:20:04 GMT
Content-Type: application/xml
Content-Length: 1394
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
Last-Modified: Fri, 08 May 2020 10:25:19 GMT
Accept-Ranges: bytes
X-Artifactory-Filename: repomd.xml
Cache-Control: no-store
</code>```

These are logged by Artifactory:

artifactory-request.log:

```<code>2020-05-28T08:20:34.566Z [5f78297c2aeabaa8] [DENIED LOGIN]   for client : username / 213.1.1.1.
2020-05-28T08:20:34.870Z [570978212a5318e3] [ACCEPTED DOWNLOAD] myapp-release-rpm-cache:stable/myapp/2019/3/repodata/repomd.xml  for client : username / 213.1.1.1.
</code>```

artifactory-access.log:

```<code>2020-05-28T08:20:34.566Z|5f78297c2aeabaa8|213.2.2.2|non_authenticated_user|HEAD|/myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml|401|-1|0|8|ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
2020-05-28T08:20:34.721Z|8018b7cbc9c424e8|213.2.2.2|username|HEAD|/myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml|200|-1|1394|3|ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
2020-05-28T08:20:34.870Z|570978212a5318e3|213.2.2.2|username|GET|/myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml|200|-1|1394|2|ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
...
</code>```

So basically, zypper comes in with a HEAD request, JFrog says "you're not authenticated", zypper responds back and tries to authenticate, and finally JFrog authenticates zypper. Makes sense so far.

Scenario 2 - 403 forbidden

Do some work, then run the same zypper refresh --repo myrepo command after a few minutes or so, and here is the result:

(1) zypper sends an HTTP HEAD request with the base64-encoded username::

```<code>HEAD /myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml HTTP/1.1
Host: rpm.example.com
Authorization: Basic dXNlcm5hbWU6
User-Agent: ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
Accept: */*
Connection: close
</code>```

(2) jfrog responds with HTTP 401 Unauthorized with the WWW-Authenticate header:

```<code>HTTP/1.1 401 Unauthorized
Date: Thu, 28 May 2020 08:30:44 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
WWW-Authenticate: Basic realm="Artifactory Realm"
</code>```

(3) zypper sends another HTTP HEAD request, this time with the base64-encoded username:password:

```<code>HEAD /myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml HTTP/1.1
Host: rpm.example.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
User-Agent: ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
Accept: */*
Connection: close
</code>```

(4) this time, jfrog responds with 403 Forbidden instead of 200 OK.

```<code>HTTP/1.1 403 Forbidden
Date: Thu, 28 May 2020 08:30:44 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
WWW-Authenticate: Basic realm="Artifactory Realm"
</code>```

artifactory-request.log:

```<code>HTTP/1.1 401 Unauthorized
Date: Thu, 28 May 2020 08:20:04 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
WWW-Authenticate: Basic realm="Artifactory Realm"
</code>```0

artifactory-access.log:

```<code>HTTP/1.1 401 Unauthorized
Date: Thu, 28 May 2020 08:20:04 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
WWW-Authenticate: Basic realm="Artifactory Realm"
</code>```1

Notice that zypper sends the same Authorization header value when asked to authenticate, but on the second scenario, JFrog fails to authenticate the request.

Did anybody have this same issue with JFrog before? We are guessing this is an issue with JFrog 7 since ours was just recently upgraded, but there is no way for us to verify this. And unfortunately for us, we are on the paid plan which doesn't even have a support license.

Any suggestions and comments will be very much appreciated.

Additional information

It might be worth-noting that yum clients (centos and rhel) do not have this exact issue with JFrog Artifactory, and it's most likely because yum always sends the username and password hash in the HTTP header, avoiding the 401 Unauthorized re-authentication sequence.

More details

I submitted a bug report to JFrog last May, and so far did not get any update.

答:
did you try setting the baseurl to:

```<code>http://username:apikey@some.url/artifactory
</code>```

?

Body:
I am having a hard time configuring zypper clients (SLES and OpenSUSE) to work with our RPM Repository in JFrog due to some "authentication" issues. At first, I thought it was just an issue with zypper and opensuse so I first focused on our efforts to make things work with zypper. This was the previous question.

But these authentication-related errors come up every now and then with yum clients as well (centOS), although not that often.

So I tried doing man-in-the-middle to see what's happening under the hood, and this is the sequence with zypper:

Scenario 1 - successful authentication

The following is the sequence of a zypper refresh --repo myrepo:

(1) zypper sends an HTTP HEAD request with the base64-encoded username::

HEAD /myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml HTTP/1.1
Host: rpm.example.com
Authorization: Basic dXNlcm5hbWU6
User-Agent: ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
Accept: */*
Connection: close

(2) jfrog responds with HTTP 401 Unauthorized with the WWW-Authenticate header:

HTTP/1.1 401 Unauthorized
Date: Thu, 28 May 2020 08:20:04 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
WWW-Authenticate: Basic realm="Artifactory Realm"

(3) zypper sends another HTTP HEAD request, this time with the base64-encoded username:password:

HEAD /myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml HTTP/1.1
Host: rpm.example.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
User-Agent: ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
Accept: */*
Connection: close

(4) jfrog finally responds with an HTTP 200.

HTTP/1.1 200 OK
Date: Thu, 28 May 2020 08:20:04 GMT
Content-Type: application/xml
Content-Length: 1394
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
Last-Modified: Fri, 08 May 2020 10:25:19 GMT
Accept-Ranges: bytes
X-Artifactory-Filename: repomd.xml
Cache-Control: no-store

These are logged by Artifactory:

artifactory-request.log:

2020-05-28T08:20:34.566Z [5f78297c2aeabaa8] [DENIED LOGIN]   for client : username / 213.1.1.1.
2020-05-28T08:20:34.870Z [570978212a5318e3] [ACCEPTED DOWNLOAD] myapp-release-rpm-cache:stable/myapp/2019/3/repodata/repomd.xml  for client : username / 213.1.1.1.

artifactory-access.log:

2020-05-28T08:20:34.566Z|5f78297c2aeabaa8|213.2.2.2|non_authenticated_user|HEAD|/myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml|401|-1|0|8|ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
2020-05-28T08:20:34.721Z|8018b7cbc9c424e8|213.2.2.2|username|HEAD|/myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml|200|-1|1394|3|ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
2020-05-28T08:20:34.870Z|570978212a5318e3|213.2.2.2|username|GET|/myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml|200|-1|1394|2|ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
...

So basically, zypper comes in with a HEAD request, JFrog says "you're not authenticated", zypper responds back and tries to authenticate, and finally JFrog authenticates zypper. Makes sense so far.

Scenario 2 - 403 forbidden

Do some work, then run the same zypper refresh --repo myrepo command after a few minutes or so, and here is the result:

(1) zypper sends an HTTP HEAD request with the base64-encoded username::

HEAD /myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml HTTP/1.1
Host: rpm.example.com
Authorization: Basic dXNlcm5hbWU6
User-Agent: ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
Accept: */*
Connection: close

(2) jfrog responds with HTTP 401 Unauthorized with the WWW-Authenticate header:

HTTP/1.1 401 Unauthorized
Date: Thu, 28 May 2020 08:30:44 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
WWW-Authenticate: Basic realm="Artifactory Realm"

(3) zypper sends another HTTP HEAD request, this time with the base64-encoded username:password:

HEAD /myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml HTTP/1.1
Host: rpm.example.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
User-Agent: ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
Accept: */*
Connection: close

(4) this time, jfrog responds with 403 Forbidden instead of 200 OK.

HTTP/1.1 403 Forbidden
Date: Thu, 28 May 2020 08:30:44 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Artifactory/7.4.3 70403900
X-Artifactory-Id: 2148103ba10eacbb:-16f1c4c1:172093a231a:-8000
X-Artifactory-Node-Id: artifactory-server
WWW-Authenticate: Basic realm="Artifactory Realm"

artifactory-request.log:

2020-05-28T08:30:44.496Z [46c81a2450623166] [DENIED LOGIN]   for client : username / 213.1.1.1.
2020-05-28T08:30:44.630Z [769ed41c652daa7a] [DENIED LOGIN]   for client : username / 213.1.1.1.

artifactory-access.log:

2020-05-28T08:30:44.496Z|46c81a2450623166|213.2.2.2|non_authenticated_user|HEAD|/myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml|401|-1|0|9|ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64
2020-05-28T08:30:44.630Z|769ed41c652daa7a|213.2.2.2|non_authenticated_user|HEAD|/myapp-release-rpm/stable/myapp/2019/3/repodata/repomd.xml|403|-1|0|1|ZYpp 17.19.0 (curl 7.60.0) openSUSE-Leap-15.1-x86_64

Notice that zypper sends the same Authorization header value when asked to authenticate, but on the second scenario, JFrog fails to authenticate the request.

Did anybody have this same issue with JFrog before? We are guessing this is an issue with JFrog 7 since ours was just recently upgraded, but there is no way for us to verify this. And unfortunately for us, we are on the paid plan which doesn't even have a support license.

Any suggestions and comments will be very much appreciated.

Additional information

It might be worth-noting that yum clients (centos and rhel) do not have this exact issue with JFrog Artifactory, and it's most likely because yum always sends the username and password hash in the HTTP header, avoiding the 401 Unauthorized re-authentication sequence.

More details

I submitted a bug report to JFrog last May, and so far did not get any update.

Body:
did you try setting the baseurl to:

http://username:apikey@some.url/artifactory

?


问:
How to retrieve data from a one to many sql relationship using PHP
I have two tables. One is called "employee" and has a column named "role". I have another table with the name "role" that has two columns in it "role_id" and "name".

I have linked the two in MySQL with a foreign key (I think!), by going to relationship view through phpmyadmin and selecting the appropriate settings.

Now in PHP I have the following code:

```<code>$employees = "SELECT employee_id, first_name, last_name, role
                 FROM employee
                 WHERE status = 1";
$employee = mysqli_query($link, $employees);

foreach ($employee as $employeeInfo) {
    <?php echo $employeeInfo['role'];?>
}
</code>```

However, this returns the number I have assigned to the role in the employee's table. Not the name from the linked table.

I think it has something to do with having to use the JOIN condition is the PHP code. However, doing some experimentation just gets me blank results.

Do you have any tips for outputting the role name from the second table in this case?

Thank you

答:
Use join to get the name of the role.</p>

```<code>$employees = "SELECT a.employee_id, a.first_name, a.last_name, b.name as role
                 FROM employee a join role b on a.role = b.role_id
                 WHERE a.status = 1";
$employee = mysqli_query($link, $employees);

foreach ($employee as $employeeInfo) {
    echo $employeeInfo['role'];
}
</code>```

Body:
I have two tables. One is called "employee" and has a column named "role". I have another table with the name "role" that has two columns in it "role_id" and "name".

I have linked the two in MySQL with a foreign key (I think!), by going to relationship view through phpmyadmin and selecting the appropriate settings.

Now in PHP I have the following code:

$employees = "SELECT employee_id, first_name, last_name, role
                 FROM employee
                 WHERE status = 1";
$employee = mysqli_query($link, $employees);

foreach ($employee as $employeeInfo) {
    <?php echo $employeeInfo['role'];?>
}

However, this returns the number I have assigned to the role in the employee's table. Not the name from the linked table.

I think it has something to do with having to use the JOIN condition is the PHP code. However, doing some experimentation just gets me blank results.

Do you have any tips for outputting the role name from the second table in this case?

Thank you

Body:
Use join to get the name of the role.

$employees = "SELECT a.employee_id, a.first_name, a.last_name, b.name as role
                 FROM employee a join role b on a.role = b.role_id
                 WHERE a.status = 1";
$employee = mysqli_query($link, $employees);

foreach ($employee as $employeeInfo) {
    echo $employeeInfo['role'];
}


问:
Vue - Component won't re-render when updating data with a method
I have a very simple vue components that looks like this:

```<code><template>
  <div class="incrementor">
    <p v-text="counter"></p>
    <button v-on:click="increment()">Increment</button>
  </div>
</template>

<script lang="ts" src="../scripts/incrementor.ts"></script>
<style lang="scss" src="../styles/incrementor.scss"></style>
</code>```

This is my 'incrementor.ts' script file:

```<code>import { Component, Vue, Prop } from "vue-property-decorator";

@Component({})
export default class Incrementor extends Vue {
  private counter: number = 0;

  increment = () => {
    this.counter++;
  };
}
</code>```

My problem is that when i click the button i can see the counter increasing in the console but the component doesn't re-render so the 'counter' text in the browser stays at 0.

I know i can do it like this:

```<code><template>
  <div class="incrementor">
    <p v-text="counter"></p>
    <button v-on:click="counter++">Increment</button>
  </div>
</template>

<script lang="ts" src="../scripts/incrementor.ts"></script>
<style lang="scss" src="../styles/incrementor.scss"></style>
</code>```

And it works but i want to be able to use my own methods for this.

答:
Few issues here:

Instead of calling the function directly, we need to pass the function reference like:

```<code> <button v-on:click="increment">
</code>```

Next, as mentioned in the docs, component methods can be declared as instance methods like:

```<code> increment() {
    this.counter++;
 };
</code>```

After implementing these changes, the increment counter will work fine.

Body:
I have a very simple vue components that looks like this:

<template>

    <button v-on:click="increment()">Increment</button>

</template>

This is my 'incrementor.ts' script file:

import { Component, Vue, Prop } from "vue-property-decorator";

@Component({})
export default class Incrementor extends Vue {
  private counter: number = 0;

  increment = () => {
    this.counter++;
  };
}

My problem is that when i click the button i can see the counter increasing in the console but the component doesn't re-render so the 'counter' text in the browser stays at 0.

I know i can do it like this:

<template>

    <button v-on:click="counter++">Increment</button>

</template>

And it works but i want to be able to use my own methods for this.

Body:
Few issues here:

Instead of calling the function directly, we need to pass the function reference like:

 <button v-on:click="increment">

Next, as mentioned in the docs, component methods can be declared as instance methods like:

 increment() {
    this.counter++;
 };

After implementing these changes, the increment counter will work fine.


问:
working of fork in c language
Now I have a problem in understanding the working of fork() system call.
I write a code which is following :

```<code>#include<stdio.h>
int main()
{
    int a, b;
    b=fork();

    printf("\n the value of b = %d",b);
}
</code>```

The output of  this code is following :

Now I don't understand why the output is like this ?

After that i just add a line to my  code and output is completely different.
my code is following:

```<code>int main()
{
    int a, b;
    b=fork();
</code>```

When i run the code the output is following
 2389my name is manish

```<code> the value of b = 0
</code>```

Now I'm totally confused about the working of fork() call.

My question are following:

How fork() works?

Where the control goes after the fork() call?

Can any body explain why the outputs of codes written in problem?

Why the output of b occurring at different places means in first code
the output of b = 2260 is just before the output b = 0 while the value of b = 2389 is not just before the b = 0?

Please explain me the working of fork in the code written in the problem so that I can learn it properly .

答:
It might help to first understand why the word fork was used to name this function. Ever heard of a "fork on the road?" At a fork, the process has to split paths.

First there is a single process executing normally until you reach the fork call. When fork is called, a new process is created, which is identical in virtually every way as the original process, except for the return value of the fork function. The newly created process is called the child process, and hence the process that spawned it is referred to as the parent process.

Since you'd want to perform different tasks for each branch of the fork, it necessitates that you be able to distinguish the child process from the parent process. That's where the return value of fork comes in: fork returns the process id (pid) of the child (the newly created process) to the parent; it returns 0 to the child. Also, should the execution of fork go wrong, the return value is -1.

In your code, you don't distinguish between the child and parent process, so both processes run the entire code that follows after the fork call.

```<code>//what the child process looks like after fork is called
int main()
{
    int a, b;
    b=fork(); // <-- current line of execution: 0 is returned to b
    printf("\nmy name is manish\n");
    printf("\n my name is anil\n");
    printf("\n the value of b = %d",b);
}

// what the parent process looks like after fork is called
int main()
{
    int a, b;
    b=fork(); // <-- current line: child process id is returned
    printf("\nmy name is manish\n");
    printf("\n my name is anil\n");
    printf("\n the value of b = %d",b);
}
</code>```

As you can see, both processes have the same code following the fork, hence the output is repeated. Perhaps if you want the parent process to output Manish and the child to output Anil, then you can do something like:

```<code>int main()
{
    pid_t b; // note that the actual return type of fork is
             // pid_t, though it's probably just an int typedef'd or macro'd

    b = fork();
    if (b == -1) perror("Fork failed");
    else if (b > 0) {
        printf("My name is Manish\n"); // parent process
    else
        printf("My name is Anil\n"); // child process

    printf("The value of b is %d\n", b);
    return 0;
}
</code>```

Finally, the last comment that must be made is that in your code, the output appears to have been executed first by one process in its entirety and then the other process in its entirety. That may not always be the case. For example, the operating system might allow the parent to execute the 'manish' output, then make this process wait, and handing the cpu over to the child process, which then executes 'manish'. However, the child process may continue and execute 'anil' and 'b' outputs, completing execution of the child process and thus returning execution back to the parent process. Now the parent finishes its execution by outputting 'anil' and 'b' itself. The final output of running this program may look something like:

```
my name is manish     // executed by parent
my name is anil       // child
the value of b = 0    // child
my name is anil       // parent
the value of b = 2244 // parent
manish.yadav@ws40-man-lin:~$
```

Take a look at the man page for fork.
Also look at waitpid for proper handling of child processes by parent processes so you don't create zombies.

Edit: In response to your questions in the comments, I'll answer how you can simply run each process consecutively.

```<code>int main()
{
     pid_t pid;
     int i;

     for (i=0; i<NUM_PROCESSES; i++)
     {
         pid = fork();
         if (pid == -1)
         {
             perror("Error forking");
             return -1;
         }
         else if (pid > 0)
         {
             // parent process
             waitpid(-1, NULL, 0); //might want to look at man page for this
                                   // it will wait until the child process is done
         }
         else
         {
             // do whatever each process needs to do;
             // then exit()
             doProcess(i);
             exit(0);
         }
     }
     // do anything else the parent process needs to do
     return 0;
}
</code>```

Of course, isn't the best code, but it's just to illustrate the point. The big idea here is the waitpid call, which causes the parent process to wait until the child process it just forked to terminate. After the child prcoess completes, the parent continues after the waitpid call, starting another iteration of the for loop and forking another (the next) process. This continues until all child process have executed sequentially and execution finally returns to the parent.

Title: working of fork in c language

Body:
Now I have a problem in understanding the working of fork() system call.
I write a code which is following :

#include<stdio.h>
int main()
{
    int a, b;
    b=fork();

    printf("\n the value of b = %d",b);
}

The output of  this code is following :

Now I don't understand why the output is like this ?

After that i just add a line to my  code and output is completely different.
my code is following:

int main()
{
    int a, b;
    b=fork();

When i run the code the output is following
 2389my name is manish

 the value of b = 0

Now I'm totally confused about the working of fork() call.

My question are following:

How fork() works?

Where the control goes after the fork() call?

Can any body explain why the outputs of codes written in problem?

Why the output of b occurring at different places means in first code
the output of b = 2260 is just before the output b = 0 while the value of b = 2389 is not just before the b = 0?

Please explain me the working of fork in the code written in the problem so that I can learn it properly .

Body:
It might help to first understand why the word fork was used to name this function. Ever heard of a "fork on the road?" At a fork, the process has to split paths.

First there is a single process executing normally until you reach the fork call. When fork is called, a new process is created, which is identical in virtually every way as the original process, except for the return value of the fork function. The newly created process is called the child process, and hence the process that spawned it is referred to as the parent process.

Since you'd want to perform different tasks for each branch of the fork, it necessitates that you be able to distinguish the child process from the parent process. That's where the return value of fork comes in: fork returns the process id (pid) of the child (the newly created process) to the parent; it returns 0 to the child. Also, should the execution of fork go wrong, the return value is -1.

In your code, you don't distinguish between the child and parent process, so both processes run the entire code that follows after the fork call.

//what the child process looks like after fork is called
int main()
{
    int a, b;
    b=fork(); // <-- current line of execution: 0 is returned to b
    printf("\nmy name is manish\n");
    printf("\n my name is anil\n");
    printf("\n the value of b = %d",b);
}

// what the parent process looks like after fork is called
int main()
{
    int a, b;
    b=fork(); // <-- current line: child process id is returned
    printf("\nmy name is manish\n");
    printf("\n my name is anil\n");
    printf("\n the value of b = %d",b);
}

As you can see, both processes have the same code following the fork, hence the output is repeated. Perhaps if you want the parent process to output Manish and the child to output Anil, then you can do something like:

int main()
{
    pid_t b; // note that the actual return type of fork is
             // pid_t, though it's probably just an int typedef'd or macro'd

    b = fork();
    if (b == -1) perror("Fork failed");
    else if (b > 0) {
        printf("My name is Manish\n"); // parent process
    else
        printf("My name is Anil\n"); // child process

    printf("The value of b is %d\n", b);
    return 0;
}

Finally, the last comment that must be made is that in your code, the output appears to have been executed first by one process in its entirety and then the other process in its entirety. That may not always be the case. For example, the operating system might allow the parent to execute the 'manish' output, then make this process wait, and handing the cpu over to the child process, which then executes 'manish'. However, the child process may continue and execute 'anil' and 'b' outputs, completing execution of the child process and thus returning execution back to the parent process. Now the parent finishes its execution by outputting 'anil' and 'b' itself. The final output of running this program may look something like:

my name is manish     // executed by parent
my name is anil       // child
the value of b = 0    // child
my name is anil       // parent
the value of b = 2244 // parent
manish.yadav@ws40-man-lin:~$

Take a look at the man page for fork.
Also look at waitpid for proper handling of child processes by parent processes so you don't create zombies.

Edit: In response to your questions in the comments, I'll answer how you can simply run each process consecutively.

int main()
{
     pid_t pid;
     int i;

     for (i=0; i<NUM_PROCESSES; i++)
     {
         pid = fork();
         if (pid == -1)
         {
             perror("Error forking");
             return -1;
         }
         else if (pid > 0)
         {
             // parent process
             waitpid(-1, NULL, 0); //might want to look at man page for this
                                   // it will wait until the child process is done
         }
         else
         {
             // do whatever each process needs to do;
             // then exit()
             doProcess(i);
             exit(0);
         }
     }
     // do anything else the parent process needs to do
     return 0;
}

Of course, isn't the best code, but it's just to illustrate the point. The big idea here is the waitpid call, which causes the parent process to wait until the child process it just forked to terminate. After the child prcoess completes, the parent continues after the waitpid call, starting another iteration of the for loop and forking another (the next) process. This continues until all child process have executed sequentially and execution finally returns to the parent.