问:
Can not make subscription in interceptor
I'm making JWT interceptor to handle 401 error. My idea is collect all original requests after 401 to array, then refresh my token, then add a new header to to my request. Here is the code:

```<code>type CallerRequest = {
    subscriber: Subscriber<any>;
    failedRequest: HttpRequest<any>;
};

@Injectable()
export class RefreshTokenInterceptor implements HttpInterceptor {
  private refreshInProgress: boolean;
  private requests: CallerRequest[] = [];

  constructor(
    public authService: AuthService,
    public customersService: CustomersService,
    private http: HttpClient
    ) {
      this.refreshInProgress = false;
    }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (!req.url.includes('api/')) {
      return next.handle(req);
    }

  const observable = new Observable<HttpEvent<any>>((subscriber) => {
  const originalRequestSubscription = next.handle(req)
    .subscribe((response) => {
      subscriber.next(response);
    },
    (err) => {
      if (err.status === 401) {
        this.handleUnauthorizedError(subscriber, req);
      } else {
        subscriber.error(err);
      }
    },
    () => {
      subscriber.complete();
    });

    return () => {
      originalRequestSubscription.unsubscribe();
    };
  });
  return observable;
  }

  private addToken(request: HttpRequest<any>, token: string) {
    return request.clone({setHeaders: {'Authorization': `Bearer ${token}`}});
  }

  private handleUnauthorizedError(subscriber: Subscriber<any>, request: HttpRequest<any>) {
    this.requests.push({ subscriber, failedRequest: request });
    if (!this.refreshInProgress) {
      this.refreshInProgress = true;
      console.log('go refresh');
      this.authService.refreshToken()
        .pipe(
          finalize(() => {
            this.refreshInProgress = false;
          })
        )
        .subscribe(
          result => {
            console.log(result); // <-- I cannot get here
            this.repeatFailedRequests(this.authService.getAccessToken());

          },
        err => {
          console.log(err); // <-- And cannot get here
        }
      )

    }
  }

  private repeatFailedRequests(authHeader: string) {
    this.requests.forEach((c) => {
      const requestWithNewToken = this.addToken(c.failedRequest, authHeader);
      this.repeatRequest(requestWithNewToken, c.subscriber);
    });
    this.requests = [];
  }

  private repeatRequest(requestWithNewToken: HttpRequest<any>, subscriber: Subscriber<any>) {
    this.http.request(requestWithNewToken).subscribe((res) => {
      subscriber.next(res);
    },
      (err) => {
        if (err.status === 401) {
          this.authService.removeTokens();
        }
        subscriber.error(err);
      },
      () => {
        subscriber.complete();
      });
  }

}
</code>```

Look at my handleUnauthorizedError method. I can't get results there.

By the way here is my refreshToken:

```<code>  refreshToken() {
    return this.post('api/v0/jwt/refresh/', {refresh: this.getRefreshToken()})
    .pipe(tap((tokens: Tokens) => {
      this.storeTokens(tokens);
    }));
</code>```

}

What am I doing wrong and how would I solve this issue in a proper way? Thank you!

ADDED:

If I try JWT interceptor from this question Angular 4 Interceptor retry requests after token refresh (most popular answer) I get the same problem - my results from RefreshToken() are not handled.

答:
The problem was in proper handling JWT refresh requests while refreshInProgress. Here is the code which works just perfect:</p>

```<code>type CallerRequest = {
    subscriber: Subscriber<any>;
    failedRequest: HttpRequest<any>;
};

@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
  private refreshInProgress: boolean;
  private requests: CallerRequest[] = [];
  private refreshJWTReuest: Subscription;
  private straightRequests: string[];

  constructor(
    public authService: AuthService,
    public customersService: CustomersService,
    private http: HttpClient
    ) {
        this.refreshInProgress = false;
        this.straightRequests = ['currency/'];
      }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (this.straightRequests.some(v => req.url.includes(v))) {
      return next.handle(req);
    }

    if (req.url.includes('api/v0/jwt/create/')) {
      this.refreshInProgress = false;
    }

  const observable = new Observable<HttpEvent<any>>((subscriber) => {
  const originalRequestSubscription = next.handle(this.addToken(req, this.authService.getAccessToken()))
    .subscribe((response) => {
      subscriber.next(response);
    },
    (err) => {
      if (err.status === 401) {
        if (req.url.includes('api/v0/jwt/refresh/')) {
          this.refreshJWTReuest.unsubscribe();
          this.requests = [];
          this.authService.logout();
        }
        this.handleUnauthorizedError(subscriber, req);
      } else {
        // notification!!!
        subscriber.error(err);
      }
    },
    () => {
      subscriber.complete();
    });

    return () => {
      originalRequestSubscription.unsubscribe();
    };
  });
  return observable;
  }

  private addToken(request: HttpRequest<any>, token: string) {
    return request.clone({setHeaders: {'Authorization': `Bearer ${token}`}});
  }

  private handleUnauthorizedError(subscriber: Subscriber<any>, request: HttpRequest<any>) {
    if (!this.refreshInProgress) {
      this.refreshInProgress = true;
      this.refreshJWTReuest = this.authService.refreshToken()
        .subscribe(
          result => {
            this.refreshInProgress = false;
            this.repeatFailedRequests(result.access);
          },
        err => {
          this.authService.logout();
          console.log(err);
        }
      );

    }
    if (!request.url.includes('api/v0/jwt/refresh/')) {
      // avoid refresh requests while refreshInProgress
      // this solves a small bug after logout()
      this.requests.push({ subscriber, failedRequest: request });
    }

  }

  private repeatFailedRequests(authHeader: string) {
    this.requests.forEach((c) => {
      const requestWithNewToken = this.addToken(c.failedRequest, authHeader);
      this.repeatRequest(requestWithNewToken, c.subscriber);
    });
    this.refreshJWTReuest.unsubscribe();
    this.requests = [];
  }

  private repeatRequest(requestWithNewToken: HttpRequest<any>, subscriber: Subscriber<any>) {
    this.http.request(requestWithNewToken).subscribe((res) => {
      subscriber.next(res);
    },
      (err) => {
        if (err.status === 401) {
          this.authService.logout();
        }
        subscriber.error(err);
      },
      () => {
        subscriber.complete();
      });
  }

}
</code>```

Body:
I'm making JWT interceptor to handle 401 error. My idea is collect all original requests after 401 to array, then refresh my token, then add a new header to to my request. Here is the code:

type CallerRequest = {
    subscriber: Subscriber<any>;
    failedRequest: HttpRequest<any>;
};

@Injectable()
export class RefreshTokenInterceptor implements HttpInterceptor {
  private refreshInProgress: boolean;
  private requests: CallerRequest[] = [];

  constructor(
    public authService: AuthService,
    public customersService: CustomersService,
    private http: HttpClient
    ) {
      this.refreshInProgress = false;
    }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (!req.url.includes('api/')) {
      return next.handle(req);
    }

  const observable = new Observable<HttpEvent<any>>((subscriber) => {
  const originalRequestSubscription = next.handle(req)
    .subscribe((response) => {
      subscriber.next(response);
    },
    (err) => {
      if (err.status === 401) {
        this.handleUnauthorizedError(subscriber, req);
      } else {
        subscriber.error(err);
      }
    },
    () => {
      subscriber.complete();
    });

    return () => {
      originalRequestSubscription.unsubscribe();
    };
  });
  return observable;
  }

  private addToken(request: HttpRequest<any>, token: string) {
    return request.clone({setHeaders: {'Authorization': `Bearer ${token}`}});
  }

  private handleUnauthorizedError(subscriber: Subscriber<any>, request: HttpRequest<any>) {
    this.requests.push({ subscriber, failedRequest: request });
    if (!this.refreshInProgress) {
      this.refreshInProgress = true;
      console.log('go refresh');
      this.authService.refreshToken()
        .pipe(
          finalize(() => {
            this.refreshInProgress = false;
          })
        )
        .subscribe(
          result => {
            console.log(result); // <-- I cannot get here
            this.repeatFailedRequests(this.authService.getAccessToken());

          },
        err => {
          console.log(err); // <-- And cannot get here
        }
      )

    }
  }

  private repeatFailedRequests(authHeader: string) {
    this.requests.forEach((c) => {
      const requestWithNewToken = this.addToken(c.failedRequest, authHeader);
      this.repeatRequest(requestWithNewToken, c.subscriber);
    });
    this.requests = [];
  }

  private repeatRequest(requestWithNewToken: HttpRequest<any>, subscriber: Subscriber<any>) {
    this.http.request(requestWithNewToken).subscribe((res) => {
      subscriber.next(res);
    },
      (err) => {
        if (err.status === 401) {
          this.authService.removeTokens();
        }
        subscriber.error(err);
      },
      () => {
        subscriber.complete();
      });
  }

}

Look at my handleUnauthorizedError method. I can't get results there.

By the way here is my refreshToken:

  refreshToken() {
    return this.post('api/v0/jwt/refresh/', {refresh: this.getRefreshToken()})
    .pipe(tap((tokens: Tokens) => {
      this.storeTokens(tokens);
    }));

}

What am I doing wrong and how would I solve this issue in a proper way? Thank you!

ADDED:

If I try JWT interceptor from this question Angular 4 Interceptor retry requests after token refresh (most popular answer) I get the same problem - my results from RefreshToken() are not handled.

Body:
The problem was in proper handling JWT refresh requests while refreshInProgress. Here is the code which works just perfect:

type CallerRequest = {
    subscriber: Subscriber<any>;
    failedRequest: HttpRequest<any>;
};

@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
  private refreshInProgress: boolean;
  private requests: CallerRequest[] = [];
  private refreshJWTReuest: Subscription;
  private straightRequests: string[];

  constructor(
    public authService: AuthService,
    public customersService: CustomersService,
    private http: HttpClient
    ) {
        this.refreshInProgress = false;
        this.straightRequests = ['currency/'];
      }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (this.straightRequests.some(v => req.url.includes(v))) {
      return next.handle(req);
    }

    if (req.url.includes('api/v0/jwt/create/')) {
      this.refreshInProgress = false;
    }

  const observable = new Observable<HttpEvent<any>>((subscriber) => {
  const originalRequestSubscription = next.handle(this.addToken(req, this.authService.getAccessToken()))
    .subscribe((response) => {
      subscriber.next(response);
    },
    (err) => {
      if (err.status === 401) {
        if (req.url.includes('api/v0/jwt/refresh/')) {
          this.refreshJWTReuest.unsubscribe();
          this.requests = [];
          this.authService.logout();
        }
        this.handleUnauthorizedError(subscriber, req);
      } else {
        // notification!!!
        subscriber.error(err);
      }
    },
    () => {
      subscriber.complete();
    });

    return () => {
      originalRequestSubscription.unsubscribe();
    };
  });
  return observable;
  }

  private addToken(request: HttpRequest<any>, token: string) {
    return request.clone({setHeaders: {'Authorization': `Bearer ${token}`}});
  }

  private handleUnauthorizedError(subscriber: Subscriber<any>, request: HttpRequest<any>) {
    if (!this.refreshInProgress) {
      this.refreshInProgress = true;
      this.refreshJWTReuest = this.authService.refreshToken()
        .subscribe(
          result => {
            this.refreshInProgress = false;
            this.repeatFailedRequests(result.access);
          },
        err => {
          this.authService.logout();
          console.log(err);
        }
      );

    }
    if (!request.url.includes('api/v0/jwt/refresh/')) {
      // avoid refresh requests while refreshInProgress
      // this solves a small bug after logout()
      this.requests.push({ subscriber, failedRequest: request });
    }

  }

  private repeatFailedRequests(authHeader: string) {
    this.requests.forEach((c) => {
      const requestWithNewToken = this.addToken(c.failedRequest, authHeader);
      this.repeatRequest(requestWithNewToken, c.subscriber);
    });
    this.refreshJWTReuest.unsubscribe();
    this.requests = [];
  }

  private repeatRequest(requestWithNewToken: HttpRequest<any>, subscriber: Subscriber<any>) {
    this.http.request(requestWithNewToken).subscribe((res) => {
      subscriber.next(res);
    },
      (err) => {
        if (err.status === 401) {
          this.authService.logout();
        }
        subscriber.error(err);
      },
      () => {
        subscriber.complete();
      });
  }

}


来源: stackexchange

问:
ReactJS chrome extension installed but not showing up
Anyone know why the ReactJS Chrome browser extension isn't showing for mein dev tools? It's installed, at one point it was working.

I'm using chrome Version 39.0.2171.65 (64-bit) on Mac OS X v 10.7.5

I read the reviews on this extension, some people said need to expose React as a global. I'm using React NPM with:
var React = require('react');

答:
Restarting Chrome after installation seems to help, apart from the other answers.

I couldn't find any info on that step in the Chrome Web Store or when clicking on the plugin, so just leaving it here.

ContentLicense: CC BY-SA 3.0

ContentLicense: CC BY-SA 4.0


问:
How to solve the error: Not allowed to start service Intent : app is in background uid?
I have a service which started by on booted completed event it, but the app crashes with the error message as in above. Please help on how can I start my Service on BroadCast receiver event of Boot_Completed.

MyService.kt

```<code>class MyService : Service() {

    override fun onCreate() {
        Log.d(TAG, "onCreate")
    }
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    override fun onDestroy() {
        Log.d(TAG, "DO SOME STAFF")
    }
}
</code>```

MyBroadCaster.kt

```<code>class StartRelayServiceAtBootReceiver : BroadcastReceiver() {
     override fun onReceive(context: Context, intent: Intent) {

        if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
            val serviceIntent = Intent(context, MyService::class.java)
            context.startService(serviceIntent)
        }
    }
}
</code>```

答:
Upon some searching I got the answer that I had to check the SDK version that I can then start it as foreground service or just with starteService;</p>

```<code>class StartRelayServiceAtBootReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {

        if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
            val intent = Intent(context, MyService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
            Log.i("Autostart", "started")
        }
    }
}
</code>```

Body:
I have a service which started by on booted completed event it, but the app crashes with the error message as in above. Please help on how can I start my Service on BroadCast receiver event of Boot_Completed.

MyService.kt

class MyService : Service() {

    override fun onCreate() {
        Log.d(TAG, "onCreate")
    }
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    override fun onDestroy() {
        Log.d(TAG, "DO SOME STAFF")
    }
}

MyBroadCaster.kt

class StartRelayServiceAtBootReceiver : BroadcastReceiver() {
     override fun onReceive(context: Context, intent: Intent) {

        if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
            val serviceIntent = Intent(context, MyService::class.java)
            context.startService(serviceIntent)
        }
    }
}

Body:
Upon some searching I got the answer that I had to check the SDK version that I can then start it as foreground service or just with starteService;

class StartRelayServiceAtBootReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {

        if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
            val intent = Intent(context, MyService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
            Log.i("Autostart", "started")
        }
    }
}


问:
How to copy an event listener in plain Javascript
So I am making some overrides on a Wordpress plugin. I need to copy the event listener on an element and then replace the element and add it back. The event listener is generated by the plugin.

I thought getEventListeners() would work but I have read that it only works in console. If that is this case I'm really astounded. We're in freaking 2020 and I am not finding an obvious solution to this.

What is the solution here people?

Below is the code I was trying to implement having assumed getEventListeners wasn't just a console function.

```<code>  // Edit Affirm
  (function replaceAffirm() {
    if (document.querySelector(".affirm-modal-trigger")) {
      const learnMore = document.querySelector("#learn-more");
      const modalTrigger = document.querySelector(".affirm-modal-trigger");
      const clickHandler = getEventListeners(modalTrigger).click[0].listener;
      const substr = learnMore.innerHTML
        .toString()
        .substring(
          learnMore.innerHTML.indexOf("h") + 2,
          learnMore.innerHTML.length
        );
      learnMore.innerHTML = "Easy Financing with " + substr;
      modalTrigger.addEventListener("click", clickHandler);
    } else {
      setTimeout(function () {
        replaceAffirm();
      }, 250);
    }
  })();
</code>```

HTML

```<code><p id="learn-more" class="affirm-as-low-as" data-amount="20000" data-affirm-color="white" data-learnmore-show="true" data-page-type="product">
   Starting at
   <span class="affirm-ala-price">$68</span>
   /mo with
   <span class="__affirm-logo __affirm-logo-white __ligature__affirm_full_logo__ __processed">Affirm</span>.
   <a class="affirm-modal-trigger" aria-label="Prequalify Now (opens in modal)" href="javascript:void(0)">Prequalify now</a>
</p>
</code>```

答:
Yes waiting for the Html element to be loaded and checking until it gets loaded is okay and this is one of the correct ways to wait for it.

As per my understanding of your issue, you just have to change the text of the learn-more element.
for that, it is not necessary to copy event listener and then again binding it.

Instead of replacing the whole element just change the text keeping the same element.
So it gets binded with the event listener by default.

Body:
So I am making some overrides on a Wordpress plugin. I need to copy the event listener on an element and then replace the element and add it back. The event listener is generated by the plugin.

I thought getEventListeners() would work but I have read that it only works in console. If that is this case I'm really astounded. We're in freaking 2020 and I am not finding an obvious solution to this.

What is the solution here people?

Below is the code I was trying to implement having assumed getEventListeners wasn't just a console function.

  // Edit Affirm
  (function replaceAffirm() {
    if (document.querySelector(".affirm-modal-trigger")) {
      const learnMore = document.querySelector("#learn-more");
      const modalTrigger = document.querySelector(".affirm-modal-trigger");
      const clickHandler = getEventListeners(modalTrigger).click[0].listener;
      const substr = learnMore.innerHTML
        .toString()
        .substring(
          learnMore.innerHTML.indexOf("h") + 2,
          learnMore.innerHTML.length
        );
      learnMore.innerHTML = "Easy Financing with " + substr;
      modalTrigger.addEventListener("click", clickHandler);
    } else {
      setTimeout(function () {
        replaceAffirm();
      }, 250);
    }
  })();

HTML

   Starting at
   $68
   /mo with
   Affirm.
   Prequalify now


问:
Is it possible to restrict TypeScript object to contain only properties defined by its class?
Here is my code

```<code>async getAll(): Promise<GetAllUserData[]> {
    return await dbQuery(); // dbQuery returns User[]
}

class User {
    id: number;
    name: string;
}

class GetAllUserData{
    id: number;
}
</code>```

getAll function returns User[], and each element of array has the name property, even if its return type is GetAllUserData[].

I want to know if it is possible "out of the box" in TypeScript to restrict an object only to properties specified by its type.

答:
Typescript can't restrict extra properties

Unfortunately this isn't currently possible in Typescript, and somewhat contradicts the shape nature of TS type checking.

Answers in this thread that relay on the generic NoExtraProperties are very elegant, but unfortunately they are unreliable, and can result in difficult to detect bugs.

I'll demonstrate with GregL's answer.

```<code>// From GregL's answer

type Impossible<K extends keyof any> = {
    [P in K]: never;
 };

 type NoExtraProperties<T, U extends T = T> = U & Impossible<Exclude<keyof U, keyof T>>;

 interface Animal {
    name: string;
    noise: string;
 }

 function thisWorks<T extends Animal>(animal: T & Impossible<Exclude<keyof T, keyof Animal>>): void {
    console.log(`The noise that ${animal.name.toLowerCase()}s make is ${animal.noise}.`);
 }

 function thisIsAsGoodAsICanGetIt<T extends Animal>(animal: NoExtraProperties<Animal, T>): void {
    console.log(`The noise that ${animal.name.toLowerCase()}s make is ${animal.noise}.`);
 }

 const wrong2 = {
    name: 'Rat',
    noise: 'squeak',
    idealScenarios: ['labs', 'storehouses'],
    invalid: true,
 };

 thisWorks(wrong2); // yay, an error!

 thisIsAsGoodAsICanGetIt(wrong2); // yay, an error!
</code>```

This works if at the time of passing an object to thisWorks/thisIsAsGoodAsICanGet TS recognizes that the object has extra properties. But in TS if it's not an object literal, a value can always have extra properties:

```<code>const fun = (animal:Animal) =>{
    thisWorks(animal) // No Error
    thisIsAsGoodAsICanGetIt(animal) // No Error
}

fun(wrong2) // No Error
</code>```

So, inside thisWorks/thisIsAsGoodAsICanGetIt you can't trust that the animal param doesn't have extra properties.

Solution

Simply use pick (Lodash, Ramda, Underscore).

```<code>interface Narrow {
   a: "alpha"
}

interface Wide extends Narrow{
   b: "beta"
}

const fun = (obj: Narrow) => {
   const narrowKeys = ["a"]
   const narrow = pick(obj, narrowKeys)
   // Even if obj has extra properties, we know for sure that narrow doesn't
   ...
}
</code>```

Body:
Here is my code

async getAll(): Promise<GetAllUserData[]> {
    return await dbQuery(); // dbQuery returns User[]
}

class User {
    id: number;
    name: string;
}

class GetAllUserData{
    id: number;
}

getAll function returns User[], and each element of array has the name property, even if its return type is GetAllUserData[].

I want to know if it is possible "out of the box" in TypeScript to restrict an object only to properties specified by its type.

Body:
Typescript can't restrict extra properties

Unfortunately this isn't currently possible in Typescript, and somewhat contradicts the shape nature of TS type checking.

Answers in this thread that relay on the generic NoExtraProperties are very elegant, but unfortunately they are unreliable, and can result in difficult to detect bugs.

I'll demonstrate with GregL's answer.

// From GregL's answer

type Impossible<K extends keyof any> = {
    [P in K]: never;
 };

 type NoExtraProperties<T, U extends T = T> = U & Impossible<Exclude<keyof U, keyof T>>;

 interface Animal {
    name: string;
    noise: string;
 }

 function thisWorks<T extends Animal>(animal: T & Impossible<Exclude<keyof T, keyof Animal>>): void {
    console.log(`The noise that ${animal.name.toLowerCase()}s make is ${animal.noise}.`);
 }

 function thisIsAsGoodAsICanGetIt<T extends Animal>(animal: NoExtraProperties<Animal, T>): void {
    console.log(`The noise that ${animal.name.toLowerCase()}s make is ${animal.noise}.`);
 }

 const wrong2 = {
    name: 'Rat',
    noise: 'squeak',
    idealScenarios: ['labs', 'storehouses'],
    invalid: true,
 };

 thisWorks(wrong2); // yay, an error!

 thisIsAsGoodAsICanGetIt(wrong2); // yay, an error!

This works if at the time of passing an object to thisWorks/thisIsAsGoodAsICanGet TS recognizes that the object has extra properties. But in TS if it's not an object literal, a value can always have extra properties:

const fun = (animal:Animal) =>{
    thisWorks(animal) // No Error
    thisIsAsGoodAsICanGetIt(animal) // No Error
}

fun(wrong2) // No Error

So, inside thisWorks/thisIsAsGoodAsICanGetIt you can't trust that the animal param doesn't have extra properties.

Solution

Simply use pick (Lodash, Ramda, Underscore).

interface Narrow {
   a: "alpha"
}

interface Wide extends Narrow{
   b: "beta"
}

const fun = (obj: Narrow) => {
   const narrowKeys = ["a"]
   const narrow = pick(obj, narrowKeys)
   // Even if obj has extra properties, we know for sure that narrow doesn't
   ...
}


问:
Selenium IDE - Format button greyed out
For some reason, when I go to export the sequence of actions I take with the Selenium IDE by going to Options -> Format, I see that Format is greyed out. I've restarted Firefox and looked online but have yet to find any explanations for what I'm seeing. A picture of what I've just described is linked below (can't yet post images- sorry).
https://lh3.googleusercontent.com/-xDzN9b8bPqs/TeblRvpeJ6I/AAAAAAAAAA4/McL3nJVcRTo/s512/selenium-ide-greyed.png</p>

答:
Format option has been turned OFF in the latest release. As per the release notes, Format changing is now marked as experimental due to possible issues, you can turn it on from the options dialog.

To turn it on, go to options->options and select 'enable experimental features'

Title: Selenium IDE - Format button greyed out


问:
How to store result of simple python calculator in variable
I am a beginner to Python and have just started learning recently.

After learning about if, elif and else statements I decided to try and make a simple calculator.

Now, a few hours later I was wondering how I could improve it and make it more complex.

I am trying to store the result of the addition, subtraction, divison or multiplication of the first two numbers in a variable. After doing this I want to Re-create the calculator only I already have the first number.

I am also running into problems with my continue1 if statement, for some reason even if the user inputs "no" the script continues instead of displaying a message.

I'd really appreciate any help at all, Thank you!

Python code:

```<code>num1 = float(input("Please enter your first number: "))
num2 = float(input("Please enter your second number: "))
operator = input("Please enter operator: ")

if operator == "/":
    print(num1 / num2)
elif operator == "+":
    print(num1 + num2)
elif operator == "-":
    print(num1 - num2)
elif operator == "*":
    print(num1 * num2)
else:
    print("FATAL ERROR")

num3 = num1 / num2
num3 = num1 - num2
num3 = num1 + num2
num3 = num1 * num2

continue1 =  input ("Would you like too continue? [Yes/No]")

if continue1 == "yes" or "Yes":
    operator1 = num4 = float(input("Please enter second number: "))
else:
    print("Fatal error")

input("please enter operator")

if operator == "/":
    print(num3 / num4)
elif operator == "+":
    print(num3 + num4)
elif operator == "-":
    print(num3 - num4)
elif operator == "*":
    print(num3 * num4)
else:
    print("Please press enter to close.")

input("Press Enter to Exit")
</code>```

答:
```<code>num1 = float(input("Please enter your first number: "))
num2 = float(input("Please enter your second number: "))
keepCalculate=True
while keepCalculate:
    operator = input("Please enter operator: ")
    if operator == "/":
        print(num1 / num2)
    elif operator == "+":
        print(num1 + num2)
    elif operator == "-":
        print(num1 - num2)
    elif operator == "*":
        print(num1 * num2)
    else:
        print("FATAL ERROR")

    continue1 =  input ("Would you like too continue? [Yes/No]")
    if continue1== "yes" or "Yes":
       keepCalculate=True
    else:
        keepCalculate=False
</code>```

The most simple way todo what you want

Body:
I am a beginner to Python and have just started learning recently.

After learning about if, elif and else statements I decided to try and make a simple calculator.

Now, a few hours later I was wondering how I could improve it and make it more complex.

I am trying to store the result of the addition, subtraction, divison or multiplication of the first two numbers in a variable. After doing this I want to Re-create the calculator only I already have the first number.

I am also running into problems with my continue1 if statement, for some reason even if the user inputs "no" the script continues instead of displaying a message.

I'd really appreciate any help at all, Thank you!

Python code:

num1 = float(input("Please enter your first number: "))
num2 = float(input("Please enter your second number: "))
operator = input("Please enter operator: ")

if operator == "/":
    print(num1 / num2)
elif operator == "+":
    print(num1 + num2)
elif operator == "-":
    print(num1 - num2)
elif operator == "*":
    print(num1 * num2)
else:
    print("FATAL ERROR")

num3 = num1 / num2
num3 = num1 - num2
num3 = num1 + num2
num3 = num1 * num2

continue1 =  input ("Would you like too continue? [Yes/No]")

if continue1 == "yes" or "Yes":
    operator1 = num4 = float(input("Please enter second number: "))
else:
    print("Fatal error")

input("please enter operator")

if operator == "/":
    print(num3 / num4)
elif operator == "+":
    print(num3 + num4)
elif operator == "-":
    print(num3 - num4)
elif operator == "*":
    print(num3 * num4)
else:
    print("Please press enter to close.")

input("Press Enter to Exit")

Body:
num1 = float(input("Please enter your first number: "))
num2 = float(input("Please enter your second number: "))
keepCalculate=True
while keepCalculate:
    operator = input("Please enter operator: ")
    if operator == "/":
        print(num1 / num2)
    elif operator == "+":
        print(num1 + num2)
    elif operator == "-":
        print(num1 - num2)
    elif operator == "*":
        print(num1 * num2)
    else:
        print("FATAL ERROR")

    continue1 =  input ("Would you like too continue? [Yes/No]")
    if continue1== "yes" or "Yes":
       keepCalculate=True
    else:
        keepCalculate=False

The most simple way todo what you want


问:
Executing a .env file in Windows python environment
I would like to create a .env file in my project root that I could execute to initialize env vars inside a virtualenv when running.

Bonus points if I can do this automatically when I cd into the project root, like autoenv on linux.

This seems like such a simple thing to do but I have not found an answer anywhere on here as of yet. Please point me in the direction if there is one.
Thanks for your time.

答:
For now, I have added the vars to the env/scripts/activate.ps1 script, meaning they will be created with environment. If you want to do this, create your virtualenv:

```<code>virtualenv env
</code>```

Then add your env vars next to the default vars in the env/scripts/activate.ps1 script in the form:

```<code>$env:some_key="someValue"
</code>```

Now anytime you create the env, it will run those lines and create your vars.

This is not a clean solution and I don't like it, but for lack of anything better am going to use it for now.

Body:
For now, I have added the vars to the env/scripts/activate.ps1 script, meaning they will be created with environment. If you want to do this, create your virtualenv:

virtualenv env

Then add your env vars next to the default vars in the env/scripts/activate.ps1 script in the form:

$env:some_key="someValue"

Now anytime you create the env, it will run those lines and create your vars.

This is not a clean solution and I don't like it, but for lack of anything better am going to use it for now.


问:
N+1 in javascript not working as intended
I got this img gallery from another question in Stack Overflow, and I added some buttons to be able to change the current img by +1 and -1.

However it's not quite working, What am I doing wrong?

Here is a fiddle as well if you want to try it for yourself:

https://jsfiddle.net/k5r98foh/1/

```<code><div class="container3 wrapper">
  <div class="mySlides">
    <div class="bb" style="background-image:url(https://lh3.googleusercontent.com/-NREkKmTtXX0/AAAAAAAAAAI/AAAAAAAAADg/w2IRnCo5AwQ/photo.jpg?sz=328);"></div>
    <!-- The above div is the problem -->
  </div>

  <div class="mySlides">
    <img src="https://i.stack.imgur.com/FyV3d.gif" style="width:100%">
  </div>

  <div class="row">
    <div class="column">
      <!-- pass this to handler -->
      <img class="demo cursor" src="https://lh3.googleusercontent.com/-NREkKmTtXX0/AAAAAAAAAAI/AAAAAAAAADg/w2IRnCo5AwQ/photo.jpg?sz=328" onclick="currentSlide(this,1)" width="100%" alt="text">
    </div>
    <div class="column">
      <!-- pass this to handler -->
      <img class="demo cursor" src="https://i.stack.imgur.com/FyV3d.gif" width="100%" onclick="currentSlide(this, 2)" alt="text">
    </div>
  </div>
    <a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
</code>```

-Javascript

```<code>var slideIndex = 1;
let wrappers = document.querySelectorAll(".wrapper");
wrappers.forEach(function(el) {
  showSlides(slideIndex, el);
});

// Next/previous controls
function plusSlides(n) {
  showSlides(slideIndex += n);
}

// Thumbnail image controls
function currentSlide(el, n) {
  // Get the wrapper element and pass it as a variable to showSlides
  let wrapper = el.closest(".wrapper");
  showSlides(slideIndex = n, wrapper);
}

function showSlides(n, wrapper) {
  var i;
  // find only the slides and dot that are decedents of current wrapper
  var slides = wrapper.querySelectorAll(".mySlides");
  var dots = wrapper.querySelectorAll(".demo");
  if (n > slides.length) {
    slideIndex = 1
  }

  if (n < 1) {
    slideIndex = slides.length
  }

  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }

  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace("active", "");
  }

  slides[slideIndex - 1].style.display = "block";
  dots[slideIndex - 1].className += " active";
}
</code>```

答:
The showSlides() function call in plusSlides() is missing the wrapper context. Change it to:

```<code>function plusSlides(el,n) {
  showSlides(slideIndex += n, el.closest('.wrapper'));
}
</code>```

and add the reference to the element itself (this) into the function call in your  tags:

```<code><a class="prev" onclick="plusSlides(this,-1)">❮</a>
<a class="prev" onclick="plusSlides(this,1)">❯</a>
</code>```

var slideIndex = 1;
let wrappers = document.querySelectorAll(".wrapper");
wrappers.forEach(function(el) {
  showSlides(slideIndex, el);
});

// Next/previous controls
function plusSlides(el,n) {
  showSlides(slideIndex += n,el.closest('.wrapper'));
}

// Thumbnail image controls
function currentSlide(el, n) {
  // Get the wrapper element and pass it as a variable to showSlides
  let wrapper = el.closest(".wrapper");
  showSlides(slideIndex = n, wrapper);
}

function showSlides(n, wrapper) {
  var i;
  // find only the slides and dot that are decedents of current wrapper
  var slides = wrapper.querySelectorAll(".mySlides");
  var dots = wrapper.querySelectorAll(".demo");
  if (n > slides.length) {
    slideIndex = 1
  }

  if (n < 1) {
    slideIndex = slides.length
  }

  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }

  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace("active", "");
  }

  slides[slideIndex - 1].style.display = "block";
  dots[slideIndex - 1].className += " active";
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.container3 {
position:absolute;
height:100px;
width:20%;
margin:auto;
right:0;
left:0;
}
.bb{
  height:100px;
    background: center center no-repeat;
    background-size: cover;
}

.mySlides {
  display: none;
}

.cursor {
  cursor: pointer;
}

.row {
  width:100%;
  display:flex;
}
.demo {
  opacity: 0.6;
}

.active,
.demo:hover {
  opacity: 1;
}
/* Next & previous buttons */
.prev,
.next {
  cursor: pointer;
  position: absolute;
  top: 40%;
  width: auto;
  padding: 16px;
  margin-top: -50px;
  color: white;
  font-weight: bold;
  font-size: 20px;
  border-radius: 0 3px 3px 0;
  user-select: none;
  -webkit-user-select: none;
}

/* Position the "next button" to the right */
.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
  background-color: rgba(0, 0, 0, 0.8);
}</code>```

    ❮
❯

```

Body:
I got this img gallery from another question in Stack Overflow, and I added some buttons to be able to change the current img by +1 and -1.

However it's not quite working, What am I doing wrong?

Here is a fiddle as well if you want to try it for yourself:

https://jsfiddle.net/k5r98foh/1/

    ❮
❯

-Javascript

var slideIndex = 1;
let wrappers = document.querySelectorAll(".wrapper");
wrappers.forEach(function(el) {
  showSlides(slideIndex, el);
});

// Next/previous controls
function plusSlides(n) {
  showSlides(slideIndex += n);
}

// Thumbnail image controls
function currentSlide(el, n) {
  // Get the wrapper element and pass it as a variable to showSlides
  let wrapper = el.closest(".wrapper");
  showSlides(slideIndex = n, wrapper);
}

function showSlides(n, wrapper) {
  var i;
  // find only the slides and dot that are decedents of current wrapper
  var slides = wrapper.querySelectorAll(".mySlides");
  var dots = wrapper.querySelectorAll(".demo");
  if (n > slides.length) {
    slideIndex = 1
  }

  if (n < 1) {
    slideIndex = slides.length
  }

  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }

  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace("active", "");
  }

  slides[slideIndex - 1].style.display = "block";
  dots[slideIndex - 1].className += " active";
}

Body:
The showSlides() function call in plusSlides() is missing the wrapper context. Change it to:

function plusSlides(el,n) {
  showSlides(slideIndex += n, el.closest('.wrapper'));
}

and add the reference to the element itself (this) into the function call in your <a> tags:

<a class="prev" onclick="plusSlides(this,-1)">❮</a>
<a class="prev" onclick="plusSlides(this,1)">❯</a>

var slideIndex = 1;
let wrappers = document.querySelectorAll(".wrapper");
wrappers.forEach(function(el) {
  showSlides(slideIndex, el);
});

// Next/previous controls
function plusSlides(el,n) {
  showSlides(slideIndex += n,el.closest('.wrapper'));
}

// Thumbnail image controls
function currentSlide(el, n) {
  // Get the wrapper element and pass it as a variable to showSlides
  let wrapper = el.closest(".wrapper");
  showSlides(slideIndex = n, wrapper);
}

function showSlides(n, wrapper) {
  var i;
  // find only the slides and dot that are decedents of current wrapper
  var slides = wrapper.querySelectorAll(".mySlides");
  var dots = wrapper.querySelectorAll(".demo");
  if (n > slides.length) {
    slideIndex = 1
  }

  if (n < 1) {
    slideIndex = slides.length
  }

  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }

  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace("active", "");
  }

  slides[slideIndex - 1].style.display = "block";
  dots[slideIndex - 1].className += " active";
}

.container3 {
position:absolute;
height:100px;
width:20%;
margin:auto;
right:0;
left:0;
}
.bb{
  height:100px;
    background: center center no-repeat;
    background-size: cover;
}

.mySlides {
  display: none;
}

.cursor {
  cursor: pointer;
}

.row {
  width:100%;
  display:flex;
}
.demo {
  opacity: 0.6;
}

.active,
.demo:hover {
  opacity: 1;
}
/* Next & previous buttons */
.prev,
.next {
  cursor: pointer;
  position: absolute;
  top: 40%;
  width: auto;
  padding: 16px;
  margin-top: -50px;
  color: white;
  font-weight: bold;
  font-size: 20px;
  border-radius: 0 3px 3px 0;
  user-select: none;
  -webkit-user-select: none;
}

/* Position the "next button" to the right */
.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
  background-color: rgba(0, 0, 0, 0.8);
}

<div class="container3 wrapper">
  <div class="mySlides">
    <div class="bb" style="background-image:url(https://lh3.googleusercontent.com/-NREkKmTtXX0/AAAAAAAAAAI/AAAAAAAAADg/w2IRnCo5AwQ/photo.jpg?sz=328);"></div>
    <!-- The above div is the problem -->
  </div>

  <div class="mySlides">
    <img src="https://i.stack.imgur.com/FyV3d.gif" style="width:100%">
  </div>

  <div class="row">
    <div class="column">
      <!-- pass this to handler -->
      <img class="demo cursor" src="https://lh3.googleusercontent.com/-NREkKmTtXX0/AAAAAAAAAAI/AAAAAAAAADg/w2IRnCo5AwQ/photo.jpg?sz=328" onclick="currentSlide(this,1)" width="100%" alt="text">
    </div>
    <div class="column">
      <!-- pass this to handler -->
      <img class="demo cursor" src="https://i.stack.imgur.com/FyV3d.gif" width="100%" onclick="currentSlide(this, 2)" alt="text">
    </div>
  </div>
    <a class="prev" onclick="plusSlides(this,-1)">❮</a>
<a class="next" onclick="plusSlides(this,1)">❯</a>
</div>


问:
How to repeat some action certain times on Vim?
In Vim, I usually want to repeat some series of commands some times. Say, I want to comment 5 lines, I would use

```<code>I//<Esc>j
.j.j.j.j
</code>```

Is there any way to repeat the last ".j" part several times?

答:
Try this:

Do something

Exit to normal mode

Type, for example, 22.

The last commands will repeats 22 times.

ContentLicense: CC BY-SA 2.5

Body:
In Vim, I usually want to repeat some series of commands some times. Say, I want to comment 5 lines, I would use

I//<Esc>j
.j.j.j.j

Is there any way to repeat the last ".j" part several times?


问:
In SwiftUI, is it possible to use a modifier only for a certain os target?
Good day! In SwiftUI, is it possible to use a modifier only for a certain os target?
In the following code I would like to use the modifier .listStyle(SidebarListStyle()) only for the MacOS target because it does not exist for the iOS target. Thanks for you help.</p>

```<code>import SwiftUI

struct ContentView: View {

  @State var selection: Int?

  var body: some View {

    HStack() {
      NavigationView {
        List () {
          NavigationLink(destination: FirstView(), tag: 0, selection: self.$selection) {
            Text("Click Me To Display The First View")
          } // End Navigation Link

          NavigationLink(destination: SecondView(), tag: 1, selection: self.$selection) {
            Text("Click Me To Display The Second View")
          } // End Navigation Link

        } // End list
        .frame(minWidth: 350, maxWidth: 350)
        .onAppear {
            self.selection = 0
        }

      } // End NavigationView
        .listStyle(SidebarListStyle())
        .frame(maxWidth: .infinity, maxHeight: .infinity)

    } // End HStack
  } // End some View
} // End ContentView

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}
</code>```

答:
You can create a View extension and use it like this:

List {
    // ...
}
.ifOS(.macOS) {
    $0.listStyle(SidebarListStyle())
}
```
<p>Here's the implementation:</p>
<pre class="lang-swift prettyprint-override"><code>enum OperatingSystem {
    case macOS
    case iOS
    case tvOS
    case watchOS

    #if os(macOS)
    static let current = macOS
    #elseif os(iOS)
    static let current = iOS
    #elseif os(tvOS)
    static let current = tvOS
    #elseif os(watchOS)
    static let current = watchOS
    #else
    #error("Unsupported platform")
    #endif
}

extension View {
    /**
    Conditionally apply modifiers depending on the target operating system.

    ```
    struct ContentView: View {
        var body: some View {
            Text("Unicorn")
                .font(.system(size: 10))
                .ifOS(.macOS, .tvOS) {
                    $0.font(.system(size: 20))
                }
        }
    }
    ```
    */
    @ViewBuilder
    func ifOS<Content: View>(
        _ operatingSystems: OperatingSystem...,
        modifier: (Self) -> Content
    ) -> some View {
        if operatingSystems.contains(OperatingSystem.current) {
            modifier(self)
        } else {
            self
        }
    }
}
</code>```

However, this will not work if you try to use a method that is not available for all the platforms you target. The only way to make that work is to use #if os(…) directly.

I have an extension that makes it easier to do that:

extension View {
    /**
    Modify the view in a closure. This can be useful when you need to conditionally apply a modifier that is unavailable on certain platforms.

    For example, imagine this code needing to run on macOS too where `View#actionSheet()` is not available:

    ```
    struct ContentView: View {
        var body: some View {
            Text("Unicorn")
                .modify {
                    #if os(iOS)
                    $0.actionSheet(…)
                    #else
                    $0
                    #endif
                }
        }
    }
    ```
    */
    func modify<T: View>(@ViewBuilder modifier: (Self) -> T) -> T {
        modifier(self)
    }
}
```

Body:
Good day! In SwiftUI, is it possible to use a modifier only for a certain os target?
In the following code I would like to use the modifier .listStyle(SidebarListStyle()) only for the MacOS target because it does not exist for the iOS target. Thanks for you help.

import SwiftUI

struct ContentView: View {

  @State var selection: Int?

  var body: some View {

    HStack() {
      NavigationView {
        List () {
          NavigationLink(destination: FirstView(), tag: 0, selection: self.$selection) {
            Text("Click Me To Display The First View")
          } // End Navigation Link

          NavigationLink(destination: SecondView(), tag: 1, selection: self.$selection) {
            Text("Click Me To Display The Second View")
          } // End Navigation Link

        } // End list
        .frame(minWidth: 350, maxWidth: 350)
        .onAppear {
            self.selection = 0
        }

      } // End NavigationView
        .listStyle(SidebarListStyle())
        .frame(maxWidth: .infinity, maxHeight: .infinity)

    } // End HStack
  } // End some View
} // End ContentView

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

Body:
You can create a View extension and use it like this:

List {
    // ...
}
.ifOS(.macOS) {
    $0.listStyle(SidebarListStyle())
}

Here's the implementation:

enum OperatingSystem {
    case macOS
    case iOS
    case tvOS
    case watchOS

    #if os(macOS)
    static let current = macOS
    #elseif os(iOS)
    static let current = iOS
    #elseif os(tvOS)
    static let current = tvOS
    #elseif os(watchOS)
    static let current = watchOS
    #else
    #error("Unsupported platform")
    #endif
}

extension View {
    /**
    Conditionally apply modifiers depending on the target operating system.

    ```
    struct ContentView: View {
        var body: some View {
            Text("Unicorn")
                .font(.system(size: 10))
                .ifOS(.macOS, .tvOS) {
                    $0.font(.system(size: 20))
                }
        }
    }
    ```
    */
    @ViewBuilder
    func ifOS<Content: View>(
        _ operatingSystems: OperatingSystem...,
        modifier: (Self) -> Content
    ) -> some View {
        if operatingSystems.contains(OperatingSystem.current) {
            modifier(self)
        } else {
            self
        }
    }
}

However, this will not work if you try to use a method that is not available for all the platforms you target. The only way to make that work is to use #if os(…) directly.

I have an extension that makes it easier to do that:

extension View {
    /**
    Modify the view in a closure. This can be useful when you need to conditionally apply a modifier that is unavailable on certain platforms.

    For example, imagine this code needing to run on macOS too where `View#actionSheet()` is not available:

    ```
    struct ContentView: View {
        var body: some View {
            Text("Unicorn")
                .modify {
                    #if os(iOS)
                    $0.actionSheet(…)
                    #else
                    $0
                    #endif
                }
        }
    }
    ```
    */
    func modify<T: View>(@ViewBuilder modifier: (Self) -> T) -> T {
        modifier(self)
    }
}


问:
.NET Standard + .NET Framework: could not load file or assembly 'Ninject'

SITUATION

I have the following solution structure:

```<code> - solution
     - "WPF Client" PROJECT[.NET Framework 4.6.1]
       (has ref to: "Core Logic" PROJECT, "Service Provider" PROJECT)

     - "Core Logic" PROJECT[.NET Framework 4.6.1]
       (has ref to: "Service Provider" PROJECT)

     - "Service Provider" PROJECT[.NET Standard 2.0]
       (has nuget: "Ninject")

</code>```

and I have following classes

IoC.cs in Service Provider PROJECT

```<code>public static class IoC
{
    private static readonly IKernel mKernel;

    static IoC()
    {
        mKernel = new StandardKernel();

        Setup();
    }

    private static void Setup()
    {
        mKernel.Bind<IInput>().To<Input>();
    }

    public static T Get<T>()
    {
        return mKernel.Get<T>();
    }
}
</code>```

MyViewModel.cs in Core Logic PROJECT

```<code>public sealed class MyViewModel
{
    ...
    public void MyViewModelMethod()
    {
        var a = IoC.Get<IInput>();
    }
    ...
}
</code>```

MyView.xaml.cs in WPF Client PROJECT

```<code>public partial class MyView : UserControl
{
    public MyView()
    {
        InitializeComponent();

        var viewModel = new MyViewModel();
        viewModel.MyViewModelMethod();
    }

}
</code>```

PROBLEM

whenever I try to run my project it throws following error:

could not load file or assembly 'Ninject'

Edit

I think this does NOT have to do anything with ninject... it's rather a .net standard + .net 4.6.1 issue.

the reason I'm thinking this way is: first of I tried other IoC containers and they threw the same error message. BUT it doesn't end there... whenever I install any NuGet package on my .NET Standard Project it seems to not be able to load its assemblies into my client project (.net 4.6.1)

the question is: is there any workaround to this problem?

答:
Found the solution!

You have to migrate Your packages.config into Your .csproj file.

for more details lookup here.

Body:
SITUATION

I have the following solution structure:

 - solution
     - "WPF Client" PROJECT[.NET Framework 4.6.1]
       (has ref to: "Core Logic" PROJECT, "Service Provider" PROJECT)

     - "Core Logic" PROJECT[.NET Framework 4.6.1]
       (has ref to: "Service Provider" PROJECT)

     - "Service Provider" PROJECT[.NET Standard 2.0]
       (has nuget: "Ninject")

and I have following classes

IoC.cs in Service Provider PROJECT

public static class IoC
{
    private static readonly IKernel mKernel;

    static IoC()
    {
        mKernel = new StandardKernel();

        Setup();
    }

    private static void Setup()
    {
        mKernel.Bind<IInput>().To<Input>();
    }

    public static T Get<T>()
    {
        return mKernel.Get<T>();
    }
}

MyViewModel.cs in Core Logic PROJECT

public sealed class MyViewModel
{
    ...
    public void MyViewModelMethod()
    {
        var a = IoC.Get<IInput>();
    }
    ...
}

MyView.xaml.cs in WPF Client PROJECT

public partial class MyView : UserControl
{
    public MyView()
    {
        InitializeComponent();

        var viewModel = new MyViewModel();
        viewModel.MyViewModelMethod();
    }

}

PROBLEM

whenever I try to run my project it throws following error:

could not load file or assembly 'Ninject'

Edit

I think this does NOT have to do anything with ninject... it's rather a .net standard + .net 4.6.1 issue.

the reason I'm thinking this way is: first of I tried other IoC containers and they threw the same error message. BUT it doesn't end there... whenever I install any NuGet package on my .NET Standard Project it seems to not be able to load its assemblies into my client project (.net 4.6.1)

the question is: is there any workaround to this problem?


问:
How do I determine the number of lines of text that will fit into a browser window
I want to display enough lines of text to fill the current size of the browser window.
Also, I'd like to update the value if the browser window changes size. Does javascript have the equivalent of SIGWINCH?

Thanks

答:
One strategy is keep adding text (say by word, scentence, paragraph) until scroll bars appear, then go back to the last compelete word, sentence, paragraph, whatever.

A lightly tested hasScrollBars function is:

```<code>function hasScrollBars(el) {
  var s = el.style;
  var borderW = parseInt(s.borderLeftWidth,10) +
                parseInt(s.borderRightWidth,10);
  var borderH = parseInt(s.borderTopWidth,10) +
                parseInt(s.borderBottomWidth,10);

  return el.offsetHeight > el.clientHeight + borderH ||
         el.offsetWidth > el.clientWidth + borderW;
}
</code>```

Body:
One strategy is keep adding text (say by word, scentence, paragraph) until scroll bars appear, then go back to the last compelete word, sentence, paragraph, whatever.

A lightly tested hasScrollBars function is:

function hasScrollBars(el) {
  var s = el.style;
  var borderW = parseInt(s.borderLeftWidth,10) +
                parseInt(s.borderRightWidth,10);
  var borderH = parseInt(s.borderTopWidth,10) +
                parseInt(s.borderBottomWidth,10);

  return el.offsetHeight > el.clientHeight + borderH ||
         el.offsetWidth > el.clientWidth + borderW;
}


问:
How to get a universal link to open the app instead of safari?
I've been trying for a while now to get universal links of iOS10 to work but it's not working till now.

I have an apple-app-site-association configured.
Have tried using the root domain, using a subfolder, on the same server or another. In all cases I am redirected to safari web page with a drop down to open my app as an option

What am I missing?

答:
In AppDelegate.m call this:

```<code>-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options;{
    NSLog(@"url recieved: %@", url);
    NSLog(@"query string: %@", [url query]);
    NSLog(@"host: %@", [url host]);
    NSLog(@"url path: %@", [url path]);
    NSDictionary *dict = [self parseQueryString:[url query]];
    NSLog(@"query dict: %@", dict);
    if ([[url host] isEqualToString:@"login"]) {
        [self setupHomeScreen:NO type:@"" entityId:@""];
        [self _endSession];
        return YES;
    } else if ([[url host] isEqualToString:@"smartoffice"]) {

        NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
        NSRange needle = [url.absoluteString rangeOfString:@"?" options:NSCaseInsensitiveSearch];
        NSString *data = nil;

        if(needle.location != NSNotFound) {
            NSUInteger start = needle.location + 1;
            NSUInteger end = [url.absoluteString length] - start;
            data = [url.absoluteString substringWithRange:NSMakeRange(start, end)];
        }

        for (NSString *param in [data componentsSeparatedByString:@"&"]) {
            NSArray *keyvalue = [param componentsSeparatedByString:@"="];
            if([keyvalue count] == 2){
                [result setObject:[keyvalue objectAtIndex:1] forKey:[keyvalue objectAtIndex:0]];
            }
        }
        NSString *entityID = ([result objectForKey:@"secondparameter"]);
        NSString *type = [result objectForKey:@"parameter"];
        [self setupHomeScreen:YES type:type entityId:entityID];
        //[self setupHomeScreen:YES type:@"TASK" entityId:@"160315"];
        return result;
    } else {
        NSLog(@"myApp is not installed");
        [self setupHomeScreen:NO type:@"0" entityId:@"0"];
    }
    return NO;
}
</code>```

Open Xcode, got to Project Settings -> Info, and add inside ‘The URL Types” section a new URL scheme.

That is the scheme ://resource. So we go ahead and type com.myApp://

Fo me its backofficeapp://

Now use this link on Safari

backofficeapp:// // This one only redirects you to a landing page.

OR

backofficeapp://smartoffice/1?parameter=TASK&secondparameter=157536

Where

parameter = “TASK”

secondparameter = “taskID”  // #iOS Mobile 2020 = 157536

This parameter is for landing on a specific screen.

Remember this URL won’t work if the app is not installed.

Body:
In AppDelegate.m call this:

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options;{
    NSLog(@"url recieved: %@", url);
    NSLog(@"query string: %@", [url query]);
    NSLog(@"host: %@", [url host]);
    NSLog(@"url path: %@", [url path]);
    NSDictionary *dict = [self parseQueryString:[url query]];
    NSLog(@"query dict: %@", dict);
    if ([[url host] isEqualToString:@"login"]) {
        [self setupHomeScreen:NO type:@"" entityId:@""];
        [self _endSession];
        return YES;
    } else if ([[url host] isEqualToString:@"smartoffice"]) {

        NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
        NSRange needle = [url.absoluteString rangeOfString:@"?" options:NSCaseInsensitiveSearch];
        NSString *data = nil;

        if(needle.location != NSNotFound) {
            NSUInteger start = needle.location + 1;
            NSUInteger end = [url.absoluteString length] - start;
            data = [url.absoluteString substringWithRange:NSMakeRange(start, end)];
        }

        for (NSString *param in [data componentsSeparatedByString:@"&"]) {
            NSArray *keyvalue = [param componentsSeparatedByString:@"="];
            if([keyvalue count] == 2){
                [result setObject:[keyvalue objectAtIndex:1] forKey:[keyvalue objectAtIndex:0]];
            }
        }
        NSString *entityID = ([result objectForKey:@"secondparameter"]);
        NSString *type = [result objectForKey:@"parameter"];
        [self setupHomeScreen:YES type:type entityId:entityID];
        //[self setupHomeScreen:YES type:@"TASK" entityId:@"160315"];
        return result;
    } else {
        NSLog(@"myApp is not installed");
        [self setupHomeScreen:NO type:@"0" entityId:@"0"];
    }
    return NO;
}

Open Xcode, got to Project Settings -> Info, and add inside ‘The URL Types” section a new URL scheme.

That is the scheme ://resource. So we go ahead and type com.myApp://

Fo me its backofficeapp://

Now use this link on Safari

backofficeapp:// // This one only redirects you to a landing page.

OR

backofficeapp://smartoffice/1?parameter=TASK&secondparameter=157536

Where

parameter = “TASK”

secondparameter = “taskID”  // #iOS Mobile 2020 = 157536

This parameter is for landing on a specific screen.

Remember this URL won’t work if the app is not installed.


问:
why doesn't my javascript function display my message?
So i connected a javascript file to my html file. When a button is clicked, it's supposed to display a message but for some reason it doesn't display anything. What am i doing wrong?
(p.s. i know very little about js)

function calc() {
  greeting = "hello"
  var usname = document.getElementById("name").innerHTML = greeting;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><header>
  <p> BMI Calculator</p>
</header>
<div class="grid">
  <div class=input>
    <form>
      <p> Fill in the form below</p>
      Name: <br>
      <input type="text" name="name" id="name"><br> Weight: <br>
      <input type="number" name="weight"><br> Height: <br>
      <input type="number" name="height"><br>
      <input type="radio" name="gender" value="female">Female
      <input type="radio" name="gender" value="male">Male
      <input type="radio" name="gender" value="other">Other<br>
      <br><input type="button" onclick="calc()" name="calculate" value="calculate">
    </form>
  </div>
  <div class="result">
    <p> Your Results</p>
  </div>
</div></code>```

答:
You have to change the value because you write in a input, or at least make a p

```<code>  <p name="name" id="name"><br> Weight: <br> </p>
</code>```

(an input has no innerHTML text, but a value)

Or you change JS:

```<code>document.getElementById("name").value = greeting;
</code>```

Body:
So i connected a javascript file to my html file. When a button is clicked, it's supposed to display a message but for some reason it doesn't display anything. What am i doing wrong?
(p.s. i know very little about js)

function calc() {
  greeting = "hello"
  var usname = document.getElementById("name").innerHTML = greeting;
}

 BMI Calculator

    <form>

 Fill in the form below

      Name:

      <input type="text" name="name" id="name">
 Weight:

      <input type="number" name="weight">
 Height:

      <input type="number" name="height">

      <input type="radio" name="gender" value="female">Female
      <input type="radio" name="gender" value="male">Male
      <input type="radio" name="gender" value="other">Other

<input type="button" onclick="calc()" name="calculate" value="calculate">
    </form>

 Your Results

Body:
You have to change the value because you write in a input, or at least make a p

  <p name="name" id="name"><br> Weight: <br> </p>

(an input has no innerHTML text, but a value)

Or you change JS:

document.getElementById("name").value = greeting;


答:
simply use

num3 = num1 + num2

to store the codes

"or" in programming doesn't work like or in rel life, it is ussed to separate 2 different conditions, hence use:

if continue1 == "yes" or continue1 == "Yes":

Title: How to store result of simple python calculator in variable


问:
How to get permalinks on a non-Wordpress site
Hello guys I have some websites I'm currently building but I have a problem...I have pages such as blogPosts.php?postID=7

I would love something like blogPosts.com/post title

Meaning I dont want people to see the variables I'm passing..

Same applies to a couple of other pages. I was told that permalinks is the key but everywhere I check, all I see is Wordpress but I am designing my site from scratch.

I'm running XAMPP from my pc.

I would really appreciate any help..

Thanks a lot

答: You need to look int into apache mod_rewrite for starters.</p>


问:
I am getting error Exception in thread "main" org.testng.TestNGException: Cannot load class from file while running a test
This is my testNG file for my project

```<code><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    <suite name="mobile-automation-framework">
        <parameter name="os" value="android" />

        <listeners>
            <listener class-name="UITestFramework.retryLogic.RetryListener" />
            <listener class-name="UITestFramework.retryLogic.TestListener" />
            <listener class-name="org.uncommons.reportng.HTMLReporter"/>
            <listener class-name="org.uncommons.reportng.JUnitXMLReporter"/>
        </listeners>

        <test name="LoginTest">
            <classes>
                <class name="tests.testngTests.e2e_Tests"/>
            </classes>
        </test>
    </suite>
</code>```

my test case file

```<code> package tests.testngTests;

    import org.testng.annotations.*;
    import IntegrationTests.coreLogic.base.*;
    import IntegrationTests.coreLogic.android.*;
    import UITestFramework.CreateSession;

    /**
     * automated test to verify login to android/iOS app.
     */
    public class e2e_Tests extends CreateSession {

        LoginCoreLogic loginCoreLogic;
        /**
         * this method instantiate required helpers depending on the platform(android or iOS)
         *
         * @param invokeDriver android or iOS
         */
        @Parameters({"os"})
        @BeforeClass
        public void instantiateHelpers(@Optional("android") String invokeDriver) {
            //Load Test Data

            if (invokeDriver.equalsIgnoreCase("android")) {
                loginCoreLogic = new AndroidLoginHelper(driver);

            } else if (invokeDriver.equalsIgnoreCase("iOS")) {
                //loginCoreLogic = new IOSLoginCoreLogic(driver);
            }
        }

        /**
         * method to verify login to android and iOS app
         *
         * @throws InterruptedException Thrown when a thread is waiting, sleeping,
         *                              or otherwise occupied, and the thread is interrupted, either
        before
         *                              or during the activity.
         */
        @Test(priority = 0)
        public void VerifyForgotPassword() throws InterruptedException {
            System.out.println("inside test 1");
        }

}
</code>```

Error logs

```<code>[RemoteTestNG] detected TestNG version 7.0.1
Exception in thread "main" org.testng.TestNGException:
Cannot load class from file:
    at org.testng.internal.ClassHelper.fileToClass(ClassHelper.java:340)
    at org.testng.TestNG.configure(TestNG.java:1422)
    at org.testng.remote.AbstractRemoteTestNG.configure(AbstractRemoteTestNG.java:75)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:235)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
</code>```

I installed testNG plugin and testng dependency in my pom file. I don't know what is reason behind this error. Please let me know what is possible solution to resolve this issue. I already reinstall testNG plugin and already done with run, build, clean project

pom.xml file

```<code>    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

<groupId>com.github</groupId>
<artifactId>mobile-automation-framework</artifactId>
<version>2.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MobileAutomationFramework</name>
<url>http://maven.apache.org</url>

<build>
    <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.19.1</version>
                    <configuration>
                        <argLine>-Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine>
                        <suiteXmlFiles>
                            <suiteXmlFile>"testng.xml"</suiteXmlFile>
                        </suiteXmlFiles>
                    </configuration>
                </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.5</version>
            <configuration>
                <suiteXmlFiles>-->
                    <suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
                </suiteXmlFiles>
                <properties>
                    <property>
                        <name>usedefaultlisteners</name>
                        <value>false</value>
                    </property>
                    <property>
                        <name>listener</name>
                        <value>org.uncommons.reportng.HTMLReporter, org.uncommons.reportng.JUnitXMLReporter</value>
                    </property>
                </properties>
                <workingDirectory>target/</workingDirectory>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <!--<systemPropertyVariables>
                    <property>
                        <invokeDriver>${invokeDriver}</invokeDriver>
                    </property>
                </systemPropertyVariables>-->
            </configuration>
        </plugin>

    </plugins>
</build>

<dependencies>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.16</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-report-plugin</artifactId>
        <version>2.19.1</version>
        <type>maven-plugin</type>
    </dependency>

    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-configuration2 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-configuration2</artifactId>
        <version>2.1.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.saucelabs/sauce_java_common -->
    <dependency>
        <groupId>com.saucelabs</groupId>
        <artifactId>sauce_java_common</artifactId>
        <version>2.1.23</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.saucelabs/sauce_testng -->
    <dependency>
        <groupId>com.saucelabs</groupId>
        <artifactId>sauce_testng</artifactId>
        <version>2.1.23</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.4</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.4</version>
    </dependency>
    <dependency>
        <groupId>io.appium</groupId>
        <artifactId>java-client</artifactId>
        <version>6.1.0</version>
    </dependency>

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>1.2.5</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-testng</artifactId>
        <version>1.2.5</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>1.2.5</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-picocontainer</artifactId>
        <version>1.2.5</version>
        <scope>compile</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.aventstack/extentreports -->
    <dependency>
        <groupId>com.aventstack</groupId>
        <artifactId>extentreports</artifactId>
        <version>3.1.5</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.1.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.141.59</version>
    </dependency>

    <dependency>
        <groupId>org.uncommons</groupId>
        <artifactId>reportng</artifactId>
        <version>1.1.4</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>
</code>```

答:
There are a couple of things you need to do.

Remove the scope parameter from the pom.xml file for all the dependencies

Try replacing the testng.xml file with the below format and add your classes there,

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
 <suite name="Test Automation" parallel="tests">
        <listeners>
            <listener class-name=""/>
        </listeners>
        <test thread-count="5" name="Test Cases">
            <classes>
               <class name="com.package.yourclassname"/>
            </classes>
        </test>
 </suite>```

Body:
This is my testNG file for my project

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    <suite name="mobile-automation-framework">
        <parameter name="os" value="android" />

        <listeners>
            <listener class-name="UITestFramework.retryLogic.RetryListener" />
            <listener class-name="UITestFramework.retryLogic.TestListener" />
            <listener class-name="org.uncommons.reportng.HTMLReporter"/>
            <listener class-name="org.uncommons.reportng.JUnitXMLReporter"/>
        </listeners>

        <test name="LoginTest">
            <classes>
                <class name="tests.testngTests.e2e_Tests"/>
            </classes>
        </test>
    </suite>

my test case file

 package tests.testngTests;

    import org.testng.annotations.*;
    import IntegrationTests.coreLogic.base.*;
    import IntegrationTests.coreLogic.android.*;
    import UITestFramework.CreateSession;

    /**
     * automated test to verify login to android/iOS app.
     */
    public class e2e_Tests extends CreateSession {

        LoginCoreLogic loginCoreLogic;
        /**
         * this method instantiate required helpers depending on the platform(android or iOS)
         *
         * @param invokeDriver android or iOS
         */
        @Parameters({"os"})
        @BeforeClass
        public void instantiateHelpers(@Optional("android") String invokeDriver) {
            //Load Test Data

            if (invokeDriver.equalsIgnoreCase("android")) {
                loginCoreLogic = new AndroidLoginHelper(driver);

            } else if (invokeDriver.equalsIgnoreCase("iOS")) {
                //loginCoreLogic = new IOSLoginCoreLogic(driver);
            }
        }

        /**
         * method to verify login to android and iOS app
         *
         * @throws InterruptedException Thrown when a thread is waiting, sleeping,
         *                              or otherwise occupied, and the thread is interrupted, either
        before
         *                              or during the activity.
         */
        @Test(priority = 0)
        public void VerifyForgotPassword() throws InterruptedException {
            System.out.println("inside test 1");
        }

}

Error logs

[RemoteTestNG] detected TestNG version 7.0.1
Exception in thread "main" org.testng.TestNGException:
Cannot load class from file:
    at org.testng.internal.ClassHelper.fileToClass(ClassHelper.java:340)
    at org.testng.TestNG.configure(TestNG.java:1422)
    at org.testng.remote.AbstractRemoteTestNG.configure(AbstractRemoteTestNG.java:75)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:235)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)

I installed testNG plugin and testng dependency in my pom file. I don't know what is reason behind this error. Please let me know what is possible solution to resolve this issue. I already reinstall testNG plugin and already done with run, build, clean project

pom.xml file

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

<groupId>com.github</groupId>
<artifactId>mobile-automation-framework</artifactId>
<version>2.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MobileAutomationFramework</name>
<url>http://maven.apache.org</url>

<build>
    <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.19.1</version>
                    <configuration>
                        <argLine>-Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine>
                        <suiteXmlFiles>
                            <suiteXmlFile>"testng.xml"</suiteXmlFile>
                        </suiteXmlFiles>
                    </configuration>
                </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.5</version>
            <configuration>
                <suiteXmlFiles>-->
                    <suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
                </suiteXmlFiles>
                <properties>
                    <property>
                        <name>usedefaultlisteners</name>
                        <value>false</value>
                    </property>
                    <property>
                        <name>listener</name>
                        <value>org.uncommons.reportng.HTMLReporter, org.uncommons.reportng.JUnitXMLReporter</value>
                    </property>
                </properties>
                <workingDirectory>target/</workingDirectory>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>

            </configuration>
        </plugin>

    </plugins>
</build>

<dependencies>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.16</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-report-plugin</artifactId>
        <version>2.19.1</version>
        <type>maven-plugin</type>
    </dependency>

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-configuration2</artifactId>
        <version>2.1.1</version>
    </dependency>

    <dependency>
        <groupId>com.saucelabs</groupId>
        <artifactId>sauce_java_common</artifactId>
        <version>2.1.23</version>
    </dependency>

    <dependency>
        <groupId>com.saucelabs</groupId>
        <artifactId>sauce_testng</artifactId>
        <version>2.1.23</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.4</version>
    </dependency>

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.4</version>
    </dependency>
    <dependency>
        <groupId>io.appium</groupId>
        <artifactId>java-client</artifactId>
        <version>6.1.0</version>
    </dependency>

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>1.2.5</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-testng</artifactId>
        <version>1.2.5</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>1.2.5</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-picocontainer</artifactId>
        <version>1.2.5</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>com.aventstack</groupId>
        <artifactId>extentreports</artifactId>
        <version>3.1.5</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.1.0</version>
    </dependency>

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.141.59</version>
    </dependency>

    <dependency>
        <groupId>org.uncommons</groupId>
        <artifactId>reportng</artifactId>
        <version>1.1.4</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>


问:
looping using while stop in first iteration
I made a bisection calculation using python with a loop condition.
the loop stops with 2 conditions, reaching a maximum iteration or maximum error.

but when I run, it always ends with 2 iterations.

when I delete the maximum error requirement, the iteration runs up to the maximum iteration
but when I delete the iteration requirement, iterates only 2 times.

Please help me. Thank you.

```<code>def bisection(f, Xl, Xu, max_eA, iteration):
    x_l = Xl
    x_u = Xu
    eA = 0
    Xr = (x_l + x_u)/2
    total_iter = 0

    if f(Xl)*f(Xu) >= 0:
        print("Bisection method fails.")
        return None

    while eA < max_eA and total_iter < iteration+1:
        print("iteration", total_iter+1)
        xr_old = Xr
        print("xr old",xr_old)
        Xr = (x_l + x_u)/2
        print("Xr now", Xr)
        f_xr = f(Xr)
        if     f_xr == 0:
            print("Found exact solution.")
            print("Xr fix", Xr)
            return Xr
        elif f(x_l)*f_xr < 0:
            x_l = x_l
            x_u = Xr
            print("x_l use",x_l)
            print("x_u use",x_u)
        elif f(x_l)*f_xr > 0:
            x_l = Xr
            x_u = x_u
        else:
            print("Bisection method fails.")
            return None
        xr_new = Xr
        print("xr new",xr_new)
        print("xr old 2", xr_old)
        print("ea use",eA)
        eA = abs((xr_new-xr_old)/xr_new)
        print("max ea",max_eA)
        print("eA after calculate", eA)
        total_iter=total_iter+1
    return (x_l + x_u)/2

f = lambda x:  ((10000000 * (1.2 ** x)) / ((1.2 ** x) - 1))\
           +\
           ((-10000000*x) / ((1.2 ** x) - 1))\
           +\
           10000000
bisection(f,5,10,0.0001,20)
</code>```

答:
The code iterates only two times because in the second iteration the value of eA becomes greater than max_eA, and that is obvious.
After removing the condition of eA from the while loop you will get the desired output for 21 iterations.

The output of your code is

```<code>iteration 1
xr old 7.5
Xr now 7.5
xr new 7.5
xr old 2 7.5
ea use 0
max ea 0.0001
eA after calculate 0.0
iteration 2
xr old 7.5
Xr now 8.75
x_l use 7.5
x_u use 8.75
xr new 8.75
xr old 2 7.5
ea use 0.0
max ea 0.0001
eA after calculate 0.14285714285714285
</code>```

As you can see from the output, in the second iteration the value of eA is 0.14285714285714285 and the value of max_ea is 0.0001. So, the while loop fails.

Body:
I made a bisection calculation using python with a loop condition.
the loop stops with 2 conditions, reaching a maximum iteration or maximum error.

but when I run, it always ends with 2 iterations.

when I delete the maximum error requirement, the iteration runs up to the maximum iteration
but when I delete the iteration requirement, iterates only 2 times.

Please help me. Thank you.

def bisection(f, Xl, Xu, max_eA, iteration):
    x_l = Xl
    x_u = Xu
    eA = 0
    Xr = (x_l + x_u)/2
    total_iter = 0

    if f(Xl)*f(Xu) >= 0:
        print("Bisection method fails.")
        return None

    while eA < max_eA and total_iter < iteration+1:
        print("iteration", total_iter+1)
        xr_old = Xr
        print("xr old",xr_old)
        Xr = (x_l + x_u)/2
        print("Xr now", Xr)
        f_xr = f(Xr)
        if     f_xr == 0:
            print("Found exact solution.")
            print("Xr fix", Xr)
            return Xr
        elif f(x_l)*f_xr < 0:
            x_l = x_l
            x_u = Xr
            print("x_l use",x_l)
            print("x_u use",x_u)
        elif f(x_l)*f_xr > 0:
            x_l = Xr
            x_u = x_u
        else:
            print("Bisection method fails.")
            return None
        xr_new = Xr
        print("xr new",xr_new)
        print("xr old 2", xr_old)
        print("ea use",eA)
        eA = abs((xr_new-xr_old)/xr_new)
        print("max ea",max_eA)
        print("eA after calculate", eA)
        total_iter=total_iter+1
    return (x_l + x_u)/2

f = lambda x:  ((10000000 * (1.2 ** x)) / ((1.2 ** x) - 1))\
           +\
           ((-10000000*x) / ((1.2 ** x) - 1))\
           +\
           10000000
bisection(f,5,10,0.0001,20)

Body:
The code iterates only two times because in the second iteration the value of eA becomes greater than max_eA, and that is obvious.
After removing the condition of eA from the while loop you will get the desired output for 21 iterations.

The output of your code is

iteration 1
xr old 7.5
Xr now 7.5
xr new 7.5
xr old 2 7.5
ea use 0
max ea 0.0001
eA after calculate 0.0
iteration 2
xr old 7.5
Xr now 8.75
x_l use 7.5
x_u use 8.75
xr new 8.75
xr old 2 7.5
ea use 0.0
max ea 0.0001
eA after calculate 0.14285714285714285

As you can see from the output, in the second iteration the value of eA is 0.14285714285714285 and the value of max_ea is 0.0001. So, the while loop fails.