问:
Should a mvc model in php just be a PDO wrapper?
I have been trying to learn about MVC pattern (without frameworks), however no matter material I read on the Internet, it just seems to be contradicting itself all the time.

My project right now consists of a form that can be submitted in order to add an element to the database. Another page just lists all the elements that are on the database.

So as I understand, my model should connect to the database (or just take the connection as a parameter, something else that was not very clear to me) and have functions like "saveItem" (which takes the $_POST variable as an input and parses it) and "listItems" (which just returns all entries to the page).

However, where does the controller come in? Now I parse my data in the model. But, if that should be rather done in the controller, what does the model actually do? I came across this page. Here, the model only has methods like "select" whose input is just a sql query. But this seems essentially just a PDO wrapper. (Contradicting information in this page about PDO already being a kind-of wrapper and there isn't really any need to do it.)

I guess it kind of makes sense, if the model was written as just a wrapper, it wouldn't actually have anything to do with the specifics of my website. (My understanding now is that each part of mvc is highly specific for each project.)

But then, it seems that either the model or the controller is just unnecessary. Either model parses the data leaving nothing for the controller to do or vice-versa.

I would be deeply grateful for any clarification.

答:
I'd take this question rather as a genuine inquiry than a request to review some SEO spam article from Internet. So it goes:

What you need to understand in the first place is that the term "model" is ambiguous. It can represent either the whole application's business logic, or just what you meant - some piece of code that interacts with the database. To avoid this ambiguity, let's stick with the former. It will help you to settle with the Controller. Whereas we will call a "lesser model" a storage. A cover term for a code which actually interacts with the database.

I have a very concise writeup, MVC in simpler terms or the structure of a modern web-application. It will help you to wrap your head around MVC at whole.

Now closer to your question.

A database wrapper cannot be considered a model, in either meaning. A database wrapper is a service used by the storage class. So, you can have at least 3 layers in your application:

a controller. Just an interface to convey an HTTP client's request to the business model

a service or a helper. the code which is usually (and wrongly) written in the controller. For example, if you need to register a user, in the controller you are calling a method from a user service, providing the data came from the client.

a storage class. The actual code to interact with a database. For example it could be a User class that contain methods such as register and such. This class would use PDO (or some more advanced wrapper, or an ORM instance) as a class variable.

Where the latter two should actually encapsulate your whole application's business logic.

The most tricky part here is the instantiation of the Storage  class. Given the connection must be done only once, there should be means to instantiate the UserStorage object providing it with the database connection. That is slightly different issue which is solved by means of the Dependency Injection Container

To illustrate the above with a bit of code

```<code>class UserController extends Controller
{
    public function create($request)
    {
        $userService = $this->serviceContainer->get('user_service');
        $userService->create(
            $request->email;
            $request->password;
        );
    }
}
class UserService
{
    public function create($username, $password)
    {
        // here, userStorage instance was already injected
        // in the UserService in the controller by DI container
        $this->userStorage->create(
            $request->email;
            $request->password;
        );
    }
}
class UserStorage
{
    public function create($username, $password)
    {
        $sql = "INSERT INTO user VALUES (null, ?, ?)";
        // here, db instance was already injected
        // in the UserStorage in the controller by DI container
        $this->db->prepare($sql)->execute([$username, $password]);
    }
}
</code>```

It could be considered unnecessarily verbose, with all these seeming repetitions, but there are reasons for that:

in the real code there are other parts in the each stage, For example,

Controller would validate the form submitted (like whether the form was actually submitted, whether passwords are equal, etc.) and call View to render the form.

UserService could perform additional validations, like whether such email already exists

Different calling points

UserService could be called from many differnt places: from the above controller or a command line utility, or a REST controller.

UserStorage could be called from even more places. For example there is a TaskService that lists tasks belong to users, and it will naturally make a good use of the UserStorage class. And so on.

So it makes a perfect sense to separate your layers this way.

Of course it's just an oversimplified draft model, it doesn't implement an ORM which is usually here, and many other things. But the simpler the sketch is, the less details it have, the simpler to get the main idea.

Body:
I'd take this question rather as a genuine inquiry than a request to review some SEO spam article from Internet. So it goes:

What you need to understand in the first place is that the term "model" is ambiguous. It can represent either the whole application's business logic, or just what you meant - some piece of code that interacts with the database. To avoid this ambiguity, let's stick with the former. It will help you to settle with the Controller. Whereas we will call a "lesser model" a storage. A cover term for a code which actually interacts with the database.

I have a very concise writeup, MVC in simpler terms or the structure of a modern web-application. It will help you to wrap your head around MVC at whole.

Now closer to your question.

A database wrapper cannot be considered a model, in either meaning. A database wrapper is a service used by the storage class. So, you can have at least 3 layers in your application:

a controller. Just an interface to convey an HTTP client's request to the business model

a service or a helper. the code which is usually (and wrongly) written in the controller. For example, if you need to register a user, in the controller you are calling a method from a user service, providing the data came from the client.

a storage class. The actual code to interact with a database. For example it could be a User class that contain methods such as register and such. This class would use PDO (or some more advanced wrapper, or an ORM instance) as a class variable.

Where the latter two should actually encapsulate your whole application's business logic.

The most tricky part here is the instantiation of the Storage  class. Given the connection must be done only once, there should be means to instantiate the UserStorage object providing it with the database connection. That is slightly different issue which is solved by means of the Dependency Injection Container

To illustrate the above with a bit of code

class UserController extends Controller
{
    public function create($request)
    {
        $userService = $this->serviceContainer->get('user_service');
        $userService->create(
            $request->email;
            $request->password;
        );
    }
}
class UserService
{
    public function create($username, $password)
    {
        // here, userStorage instance was already injected
        // in the UserService in the controller by DI container
        $this->userStorage->create(
            $request->email;
            $request->password;
        );
    }
}
class UserStorage
{
    public function create($username, $password)
    {
        $sql = "INSERT INTO user VALUES (null, ?, ?)";
        // here, db instance was already injected
        // in the UserStorage in the controller by DI container
        $this->db->prepare($sql)->execute([$username, $password]);
    }
}

It could be considered unnecessarily verbose, with all these seeming repetitions, but there are reasons for that:

in the real code there are other parts in the each stage, For example,

Controller would validate the form submitted (like whether the form was actually submitted, whether passwords are equal, etc.) and call View to render the form.

UserService could perform additional validations, like whether such email already exists

Different calling points

UserService could be called from many differnt places: from the above controller or a command line utility, or a REST controller.

UserStorage could be called from even more places. For example there is a TaskService that lists tasks belong to users, and it will naturally make a good use of the UserStorage class. And so on.

So it makes a perfect sense to separate your layers this way.

Of course it's just an oversimplified draft model, it doesn't implement an ORM which is usually here, and many other things. But the simpler the sketch is, the less details it have, the simpler to get the main idea.


来源: stackexchange

问:
Python library for job scheduling, ssh
I'd like to find a user-space tool (preferably in Python - barring that, in anything I could easily modify if it doesn't already do what I need it to) to replace a short script I've been using that does the two things below:

polls less than 100 computers (Fedora 13, it so happens) for load, available memory, and if it looks like someone is using them

selects good hosts for jobs, runs these jobs over ssh.  These jobs are the execution of arbitrary command line programs which read and write to a shared filesystem - typically image processing scripts or similar - cpu, sometimes memory intensive tasks.

For example, using my current script, I can in a python prompt

```<code>>>> import hosts
>>> hosts.run_commands(['users']*5)
</code>```

or from the command line

```<code>% hosts.py "users" "users" "users" "users" "users"
</code>```

to run the command users 5 times (after finding 5 computers on which the command could be run by checking the cpu load and available memory on at least 5 computers from a config file).  There should be no job server other than the script I just ran, and no worker daemons or processes on the computers that will run these commands.

I'd additionally like to be able to track the jobs, run jobs again on failure, etc., but these are extra features (very standard in a real job scheduler) that I don't actually need.

I've found good ssh libraries for Python, things like classh and PuSSH, which don't have the (very simple) load balancing features I'd like.  On the other side of what I want is Condor or Slurm, as suggested by crispamares before I clarified I want something lighter.  Those would be doing things the proper way, but from reading about them, they sounds like spinning them up in user space only when I need them would be annoying to impossible.  This isn't a dedicated cluster, and I don't have root access on these hosts.

I'm currently planning to use a wrapper around classh with some basic polling of computers whenever I need to know how busy they are if I can't find something else.

答:
Slurm is a powerful job scheduler that can be programmable in Python using PySlurm.

I don't know if it is harder than Condor to deploy. Also I don't know if it fits all your needs, but just in case, I write it down.

ContentLicense: CC BY-SA 3.0

Title: Python library for job scheduling, ssh

Body:
I'd like to find a user-space tool (preferably in Python - barring that, in anything I could easily modify if it doesn't already do what I need it to) to replace a short script I've been using that does the two things below:

polls less than 100 computers (Fedora 13, it so happens) for load, available memory, and if it looks like someone is using them

selects good hosts for jobs, runs these jobs over ssh.  These jobs are the execution of arbitrary command line programs which read and write to a shared filesystem - typically image processing scripts or similar - cpu, sometimes memory intensive tasks.

For example, using my current script, I can in a python prompt

>>> import hosts
>>> hosts.run_commands(['users']*5)

or from the command line

% hosts.py "users" "users" "users" "users" "users"

to run the command users 5 times (after finding 5 computers on which the command could be run by checking the cpu load and available memory on at least 5 computers from a config file).  There should be no job server other than the script I just ran, and no worker daemons or processes on the computers that will run these commands.

I'd additionally like to be able to track the jobs, run jobs again on failure, etc., but these are extra features (very standard in a real job scheduler) that I don't actually need.

I've found good ssh libraries for Python, things like classh and PuSSH, which don't have the (very simple) load balancing features I'd like.  On the other side of what I want is Condor or Slurm, as suggested by crispamares before I clarified I want something lighter.  Those would be doing things the proper way, but from reading about them, they sounds like spinning them up in user space only when I need them would be annoying to impossible.  This isn't a dedicated cluster, and I don't have root access on these hosts.

I'm currently planning to use a wrapper around classh with some basic polling of computers whenever I need to know how busy they are if I can't find something else.


问:
Toggle and Modals are not working on Angular app
I am new to Angular and having some issues with getting Bootstrap toggle and Modal to work. BootStrap CSS files are working because the form is picking up the styling; however, I reckon JS files are not being linked properly. Please let me know what am I doing working.

I did an NPM install of BootStrap and jQuery using the Angular CLI.
Once installed, I linked the BootStrap and jQuery files to the angular.json file for the application to be able to use the libraries.

```<code>"build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/LyndaChapter1",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            **"styles": [
              **"node_modules/bootstrap/dist/css/bootstrap.css",
              "src/styles.css"**
            ],
            "scripts": [
              "node_modules/bootstrap/dist/js/bootstrap.js",
              "node_modules/jquery/dist/jquery.js"
            ],**
            "es5BrowserSupport": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            }
          }
        },
</code>```

Expected result: Toggle and Modals should work
Actual result: Neither are working

答:
jQuery is a bad choice to run on Angular... what you may need is ngBootstrap

There is excellent boilerplate code there which you can use just like i did here

relevant HTML:

```<code><ng-template #content let-modal>
  <div class="modal-header">
    <h4 class="modal-title" id="modal-basic-title">Profile update</h4>
    <button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
      <span aria-hidden="true">×</span>
    </button>
  </div>
  <div class="modal-body">
    <form>
      <div class="form-group">
        <label for="dateOfBirth">Date of birth</label>
        <div class="input-group">
          <input id="dateOfBirth" class="form-control" placeholder="yyyy-mm-dd" name="dp" ngbDatepicker #dp="ngbDatepicker">
          <div class="input-group-append">
            <button class="btn btn-outline-secondary calendar" (click)="dp.toggle()" type="button"></button>
          </div>
        </div>
      </div>
    </form>
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-outline-dark" (click)="modal.close('Save click')">Save</button>
  </div>
</ng-template>

<button class="btn btn-lg btn-outline-primary" (click)="open(content)">Launch demo modal</button>

<hr>

```{{closeResult}}```

<hr/>

<p>
  <button type="button" class="btn btn-outline-primary" (click)="isCollapsed = !isCollapsed"
          [attr.aria-expanded]="!isCollapsed" aria-controls="collapseExample">
    Toggle
  </button>
</p>
<div id="collapseExample" [ngbCollapse]="isCollapsed">
  <div class="card">
    <div class="card-body">
      You can collapse this card by clicking Toggle
    </div>
  </div>
</div>
</code>```

relevant TS:

```<code>import {Component} from '@angular/core';
import {NgbModal, ModalDismissReasons} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-basic',
  templateUrl: './modal-basic.html'
})
export class NgbdModalBasic {
  closeResult: string;
  public isCollapsed = false;

  constructor(private modalService: NgbModal) {}

  open(content) {
    this.modalService.open(content, {ariaLabelledBy: 'modal-basic-title'}).result.then((result) => {
      this.closeResult = `Closed with: ${result}`;
    }, (reason) => {
      this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });
  }

  private getDismissReason(reason: any): string {
    if (reason === ModalDismissReasons.ESC) {
      return 'by pressing ESC';
    } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
      return 'by clicking on a backdrop';
    } else {
      return  `with: ${reason}`;
    }
  }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am new to Angular and having some issues with getting Bootstrap toggle and Modal to work. BootStrap CSS files are working because the form is picking up the styling; however, I reckon JS files are not being linked properly. Please let me know what am I doing working.

I did an NPM install of BootStrap and jQuery using the Angular CLI.
Once installed, I linked the BootStrap and jQuery files to the angular.json file for the application to be able to use the libraries.

"build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/LyndaChapter1",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            **"styles": [
              **"node_modules/bootstrap/dist/css/bootstrap.css",
              "src/styles.css"**
            ],
            "scripts": [
              "node_modules/bootstrap/dist/js/bootstrap.js",
              "node_modules/jquery/dist/jquery.js"
            ],**
            "es5BrowserSupport": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            }
          }
        },

Expected result: Toggle and Modals should work
Actual result: Neither are working

Body:
jQuery is a bad choice to run on Angular... what you may need is ngBootstrap

There is excellent boilerplate code there which you can use just like i did here

relevant HTML:

<ng-template #content let-modal>
  <div class="modal-header">
    <h4 class="modal-title" id="modal-basic-title">Profile update</h4>
    <button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <form>
      <div class="form-group">
        <label for="dateOfBirth">Date of birth</label>
        <div class="input-group">
          <input id="dateOfBirth" class="form-control" placeholder="yyyy-mm-dd" name="dp" ngbDatepicker #dp="ngbDatepicker">
          <div class="input-group-append">
            <button class="btn btn-outline-secondary calendar" (click)="dp.toggle()" type="button"></button>
          </div>
        </div>
      </div>
    </form>
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-outline-dark" (click)="modal.close('Save click')">Save</button>
  </div>
</ng-template>

<button class="btn btn-lg btn-outline-primary" (click)="open(content)">Launch demo modal</button>

<hr>

<pre>{{closeResult}}</pre>

<hr/>

<p>
  <button type="button" class="btn btn-outline-primary" (click)="isCollapsed = !isCollapsed"
          [attr.aria-expanded]="!isCollapsed" aria-controls="collapseExample">
    Toggle
  </button>
</p>
<div id="collapseExample" [ngbCollapse]="isCollapsed">
  <div class="card">
    <div class="card-body">
      You can collapse this card by clicking Toggle
    </div>
  </div>
</div>

relevant TS:

import {Component} from '@angular/core';
import {NgbModal, ModalDismissReasons} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-basic',
  templateUrl: './modal-basic.html'
})
export class NgbdModalBasic {
  closeResult: string;
  public isCollapsed = false;

  constructor(private modalService: NgbModal) {}

  open(content) {
    this.modalService.open(content, {ariaLabelledBy: 'modal-basic-title'}).result.then((result) => {
      this.closeResult = `Closed with: ${result}`;
    }, (reason) => {
      this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });
  }

  private getDismissReason(reason: any): string {
    if (reason === ModalDismissReasons.ESC) {
      return 'by pressing ESC';
    } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
      return 'by clicking on a backdrop';
    } else {
      return  `with: ${reason}`;
    }
  }
}


问:
Basename does not seem to be taken into account with matchPath in react router
I am looking into a bug we have with react-router-dom version 5.0.0 and the active class not being applied to the active link.

It works in development when we have a basename of / but in our dev environment, the basename is set to `/some/basename/'.

If I call this matchPath directly like this:

```<code>matchPath("/some/basename/business", {
  exact: true,
  location: undefined,
  path: "\/business",
  strict: undefined
})
</code>```

Then it returns null, if I call matchpath like this, it gets a match:

```<code>matchPath("/business", {
  exact: true,
  location: undefined,
  path: "\/business",
  strict: undefined
})
</code>```

So it looks like matchPath is not using the basename because after trying to debug the code I see that matchPath calls pathToRegexp which creates this regex:

```<code>/^\/business\/?$/i
</code>```

The code only appears to be using the path property and not the location.pathname.

I tried to implement my own isActive method to log what was going on:

```<code>const isActive = (match: Match<any>, historyLocation: Location) =>  {
  const basename = (window.env.REACT_APP_BASE_URI || "/") === "/" ? "" : window.env.REACT_APP_BASE_URI;
  const fullUrl = `${basename.replace(/^(.+?)\/*?$/, "$1")}${historyLocation.pathname}`;

  console.log("----------------------");
  console.log({
    basename,
    fullUrl,
    historyLocation,
    historyLocationPathName: historyLocation.pathname,
    location: window.location.pathname,
    match,
  });
  console.log("----------------------");

  if (!match) {
    return;
  }

  return window.location.pathname.startsWith(`${fullUrl}`);
};
</code>```

match is always null in the environment but works fine in development.

Why would this be?

答:
Based on this github issue comment

basename comes from the <base href="/foo"> HTML element, which
  applies a basename to all links on the page. In that case, the rest
  of the HTML doesn't "know" about that base URL; it's just
  automatically prepended to any href.

Similarly, the basename in Router is something the application doesn't
  know about. It just <Link>'s to various routes and is unaware of the
  basename being attached.

When you are using using mathPath, instead of using window.location.pathname if you use location.pathname provided by Router, you will receive the pathname that matches your route instead of the entire pathname which includes basename.

```<code>matchPath(location.pathname, {
  exact: true,
  location: undefined,
  path: "\/business",
  strict: undefined
})
</code>```

and the above will return true if the path is /some/basename/busines

Body:
I am looking into a bug we have with react-router-dom version 5.0.0 and the active class not being applied to the active link.

It works in development when we have a basename of / but in our dev environment, the basename is set to `/some/basename/'.

If I call this matchPath directly like this:

matchPath("/some/basename/business", {
  exact: true,
  location: undefined,
  path: "\/business",
  strict: undefined
})

Then it returns null, if I call matchpath like this, it gets a match:

matchPath("/business", {
  exact: true,
  location: undefined,
  path: "\/business",
  strict: undefined
})

So it looks like matchPath is not using the basename because after trying to debug the code I see that matchPath calls pathToRegexp which creates this regex:

/^\/business\/?$/i

The code only appears to be using the path property and not the location.pathname.

I tried to implement my own isActive method to log what was going on:

const isActive = (match: Match<any>, historyLocation: Location) =>  {
  const basename = (window.env.REACT_APP_BASE_URI || "/") === "/" ? "" : window.env.REACT_APP_BASE_URI;
  const fullUrl = `${basename.replace(/^(.+?)\/*?$/, "$1")}${historyLocation.pathname}`;

  console.log("----------------------");
  console.log({
    basename,
    fullUrl,
    historyLocation,
    historyLocationPathName: historyLocation.pathname,
    location: window.location.pathname,
    match,
  });
  console.log("----------------------");

  if (!match) {
    return;
  }

  return window.location.pathname.startsWith(`${fullUrl}`);
};

match is always null in the environment but works fine in development.

Why would this be?

Body:
Based on this github issue comment

basename comes from the <base href="/foo"> HTML element, which
  applies a basename to all links on the page. In that case, the rest
  of the HTML doesn't "know" about that base URL; it's just
  automatically prepended to any href.

Similarly, the basename in Router is something the application doesn't
  know about. It just <Link>'s to various routes and is unaware of the
  basename being attached.

When you are using using mathPath, instead of using window.location.pathname if you use location.pathname provided by Router, you will receive the pathname that matches your route instead of the entire pathname which includes basename.

matchPath(location.pathname, {
  exact: true,
  location: undefined,
  path: "\/business",
  strict: undefined
})

and the above will return true if the path is /some/basename/busines


问:
Time difference between row and its previous/next row for the same customer in pandas dataframe
I have a dataframe:

```<code>In [1]: import pandas as pd;import numpy as np

In [2]: df = pd.DataFrame(
   ...: [
   ...:     ['A', '2019-05-10 23:59:59', 'NOT_WORKING'],
   ...:     ['A', '2019-05-11 00:05:00', 'WORKING'],
   ...:     ['B', '2019-05-13 07:55:00', 'NOT_WORKING'],
   ...:     ['B', '2019-05-15 07:57:00', 'WORKING'],
   ...:     ['B', '2019-05-16 08:03:00', 'NOT_WORKING'],
   ...: ], columns=['cust', 'event_date', 'status'])
   ...: df.event_date = pd.to_datetime(df.event_date)

In [3]: df.loc[1, 'test'] = 'Y'
   ...: df.loc[3, 'test'] = 'Y'

In [4]: df
Out[4]:
  cust          event_date       status test
0    A 2019-05-10 23:59:59  NOT_WORKING  NaN
1    A 2019-05-11 00:05:00      WORKING    Y
2    B 2019-05-13 07:55:00  NOT_WORKING  NaN
3    B 2019-05-15 07:57:00      WORKING    Y
4    B 2019-05-16 08:03:00  NOT_WORKING  NaN
</code>```

I need to find out time difference between test rows and their prvious/next rows for the same customer.

I have done it like this:

```<code>In [5]: df.loc[:, 'prev_time'] = df.event_date.shift(1)
   ...: df.loc[:, 'prev_cust'] = df.cust.shift(1)
   ...: df.loc[:, 'next_time'] = df.event_date.shift(-1)
   ...: df.loc[:, 'next_cust'] = df.cust.shift(-1)
   ...: df
Out[5]:
  cust          event_date  ...           next_time next_cust
0    A 2019-05-10 23:59:59  ... 2019-05-11 00:05:00         A
1    A 2019-05-11 00:05:00  ... 2019-05-13 07:55:00         B
2    B 2019-05-13 07:55:00  ... 2019-05-15 07:57:00         B
3    B 2019-05-15 07:57:00  ... 2019-05-16 08:03:00         B
4    B 2019-05-16 08:03:00  ...                 NaT       NaN

[5 rows x 8 columns]

In [9]: df = df.loc[df.test=='Y', :].assign(time_to_prev=lambda row: row.
   ...: event_date - row.prev_time ).assign(time_to_next=lambda row: row.
   ...: next_time - row.event_date)
   ...: df.loc[df.cust != df.prev_cust, 'time_to_prev'] = np.nan
   ...: df.loc[df.cust != df.next_cust, 'time_to_next'] = np.nan
   ...: df = df.drop(columns=['prev_time', 'prev_cust', 'next_time', 'nex
   ...: t_cust'])
   ...: df
Out[9]:
  cust          event_date   status test    time_to_prev    time_to_next
1    A 2019-05-11 00:05:00  WORKING    Y 0 days 00:05:01             NaT
3    B 2019-05-15 07:57:00  WORKING    Y 2 days 00:02:00 1 days 00:06:00
</code>```

It works, but I am looking for the more elegant solution that will incorporate groupby, diff...
How to do that?

答:
First just make sure the sorting is correct for 'cust' and 'event_date', and then groupby customer, then take the difference for each row. </p>

```<code>df = df.sort_values(['cust', 'event_date'])
df.groupby('cust')['event_date'].diff()

       event_date
0             NaT
1 0 days 00:05:01
2             NaT
3 2 days 00:02:00
4 1 days 00:06:00
</code>```

Body:
I have a dataframe:

In [1]: import pandas as pd;import numpy as np

In [2]: df = pd.DataFrame(
   ...: [
   ...:     ['A', '2019-05-10 23:59:59', 'NOT_WORKING'],
   ...:     ['A', '2019-05-11 00:05:00', 'WORKING'],
   ...:     ['B', '2019-05-13 07:55:00', 'NOT_WORKING'],
   ...:     ['B', '2019-05-15 07:57:00', 'WORKING'],
   ...:     ['B', '2019-05-16 08:03:00', 'NOT_WORKING'],
   ...: ], columns=['cust', 'event_date', 'status'])
   ...: df.event_date = pd.to_datetime(df.event_date)

In [3]: df.loc[1, 'test'] = 'Y'
   ...: df.loc[3, 'test'] = 'Y'

In [4]: df
Out[4]:
  cust          event_date       status test
0    A 2019-05-10 23:59:59  NOT_WORKING  NaN
1    A 2019-05-11 00:05:00      WORKING    Y
2    B 2019-05-13 07:55:00  NOT_WORKING  NaN
3    B 2019-05-15 07:57:00      WORKING    Y
4    B 2019-05-16 08:03:00  NOT_WORKING  NaN

I need to find out time difference between test rows and their prvious/next rows for the same customer.

I have done it like this:

In [5]: df.loc[:, 'prev_time'] = df.event_date.shift(1)
   ...: df.loc[:, 'prev_cust'] = df.cust.shift(1)
   ...: df.loc[:, 'next_time'] = df.event_date.shift(-1)
   ...: df.loc[:, 'next_cust'] = df.cust.shift(-1)
   ...: df
Out[5]:
  cust          event_date  ...           next_time next_cust
0    A 2019-05-10 23:59:59  ... 2019-05-11 00:05:00         A
1    A 2019-05-11 00:05:00  ... 2019-05-13 07:55:00         B
2    B 2019-05-13 07:55:00  ... 2019-05-15 07:57:00         B
3    B 2019-05-15 07:57:00  ... 2019-05-16 08:03:00         B
4    B 2019-05-16 08:03:00  ...                 NaT       NaN

[5 rows x 8 columns]

In [9]: df = df.loc[df.test=='Y', :].assign(time_to_prev=lambda row: row.
   ...: event_date - row.prev_time ).assign(time_to_next=lambda row: row.
   ...: next_time - row.event_date)
   ...: df.loc[df.cust != df.prev_cust, 'time_to_prev'] = np.nan
   ...: df.loc[df.cust != df.next_cust, 'time_to_next'] = np.nan
   ...: df = df.drop(columns=['prev_time', 'prev_cust', 'next_time', 'nex
   ...: t_cust'])
   ...: df
Out[9]:
  cust          event_date   status test    time_to_prev    time_to_next
1    A 2019-05-11 00:05:00  WORKING    Y 0 days 00:05:01             NaT
3    B 2019-05-15 07:57:00  WORKING    Y 2 days 00:02:00 1 days 00:06:00

It works, but I am looking for the more elegant solution that will incorporate groupby, diff...
How to do that?

Body:
First just make sure the sorting is correct for 'cust' and 'event_date', and then groupby customer, then take the difference for each row.

df = df.sort_values(['cust', 'event_date'])
df.groupby('cust')['event_date'].diff()

       event_date
0             NaT
1 0 days 00:05:01
2             NaT
3 2 days 00:02:00
4 1 days 00:06:00


问:
Python `nx.maximum_flow_value`
I'm using the following code sample in Python to calculate the flow between every pair of nodes in the graph below to identify whether the graph is 2 connected. It returns that the graph is 2 connected and all pairs of nodes have flow >=2, which is false because the marked area has a cut node. I can't identify what I'm doing wrong. Can someone please help me with that?

```<code>for edge in list(T.edges()):
    T[edge[0]][edge[1]]['capacity']=1
    T[edge[1]][edge[0]]['capacity']=1

flow3 =[]

for d in V:
    tempvert =[]
    tempvert = set(V) - set([d])
    for a in tempvert:
        flow_value = nx.maximum_flow_value(T, a, d,capacity = '1')
</code>```

答: Try using nx.node_connectivity(G).  Here is the documentation.

Title: Python `nx.maximum_flow_value`

Body:
I'm using the following code sample in Python to calculate the flow between every pair of nodes in the graph below to identify whether the graph is 2 connected. It returns that the graph is 2 connected and all pairs of nodes have flow >=2, which is false because the marked area has a cut node. I can't identify what I'm doing wrong. Can someone please help me with that?

for edge in list(T.edges()):
    T[edge[0]][edge[1]]['capacity']=1
    T[edge[1]][edge[0]]['capacity']=1

flow3 =[]

for d in V:
    tempvert =[]
    tempvert = set(V) - set([d])
    for a in tempvert:
        flow_value = nx.maximum_flow_value(T, a, d,capacity = '1')


问:
new Date('yyyy-mm-dd') sets timezone to local timezone but new Date('yyyyy-mm-dd') sets timezone to GMT
new Date('yyyy-mm-dd') sets timezone to local timezone but
new Date('yyyyy-mm-dd') sets timezone to GMT

```<code>new Date("2019-05-29")
Wed May 29 2019 05:30:00 GMT+0530 (India Standard Time)

new Date("11111-05-29")
Mon May 29 11111 00:00:00 GMT+0530 (India Standard Time)

</code>```

Why does this behavior occur

答:
Your first one is creating a UTC date but you're displaying it in your local timezone. From the documentation...

Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local

Your second date is being created in your local timezone. The reason for this is because the ISO 8601 standard only supports a 4-digit year (by default), therefore it does not qualify for the above condition.

Body:
new Date('yyyy-mm-dd') sets timezone to local timezone but
new Date('yyyyy-mm-dd') sets timezone to GMT

new Date("2019-05-29")
Wed May 29 2019 05:30:00 GMT+0530 (India Standard Time)

new Date("11111-05-29")
Mon May 29 11111 00:00:00 GMT+0530 (India Standard Time)

Why does this behavior occur


问:
When is shouldRepaint method from custom painter class in flutter called?
I'm trying to understand how shouldRepaint works.  I found a tutorial that paints a dial around a circle button to show its value.  The example had shouldRepaint always return true.  Basically it just paints a partial circle around the button to show the % value.  If the value is 50, the circle would go half way around.

I set shouldRepaint to always return false to see what would happen.  It still painted the button circle correctly.

My theory is that it will always paint when the stateful widget is redrawn.  So when the button value goes from 40% to 50%, the widget redraws and the painting is done no matter what.

So if my widget is painted anyway when the state changes, when would I use shouldRepaint?

Here is the relevant code from the tutorial:

```<code>class HomeContent extends StatefulWidget {
  @override
  _HomeContentState createState() => _HomeContentState();
}

class _HomeContentState extends State<HomeContent> {
  int percentage;

  @override
  void initState() {
    super.initState();
    setState(() {
      percentage = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new Container(
        height: 200.0,
        width: 200.0,
        child: new CustomPaint(
          foregroundPainter: new MyPainter(
              lineColor: Colors.amber,
          completeColor: Colors.blueAccent,
          completePercent: percentage,
          width: 8.0),
          child: new Padding(
          padding: const EdgeInsets.all(8.0),
        child: new RaisedButton(
            color: Colors.purple,
            splashColor: Colors.blueAccent,
            shape: new CircleBorder(),
            child: new Text("$percentage%"),
            onPressed: () {
              setState(() {
                percentage += 10;
                if (percentage > 100) {
                  percentage = 0;
                }
              });
            }),
          ),
        ),
      ),
    );
  }
}

class MyPainter extends CustomPainter {
  Color lineColor;
  Color completeColor;
  int completePercent;
  double width;

  MyPainter(
  {this.lineColor, this.completeColor, this.completePercent, this.width});

  @override
  void paint(Canvas canvas, Size size) {
    Paint line = new Paint()
      ..color = lineColor
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = width;
    Paint complete = new Paint()
      ..color = completeColor
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = width;
    Offset center = new Offset(size.width / 2, size.height / 2);
    double radius = min(size.width / 2, size.height / 2);
    canvas.drawCircle(center, radius, line);
    double arcAngle = 2 * pi * (completePercent / 100.0);
    if (arcAngle >= 2 * pi) arcAngle = 2 * pi - 0.001;  // cannot draw a complete circle arc
    canvas.drawArc(new Rect.fromCircle(center: center, radius: radius), -pi / 2,
    arcAngle, false, complete);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}
</code>```

答:
From Docs, shouldRepaint():

If the new instance represents different information than the old instance, then the method should return true, otherwise it should return false

Also,

It's possible that the paint method will get called even if shouldRepaint returns false (e.g. if an ancestor or descendant needed to be repainted). It's also possible that the paint method will get called without shouldRepaint being called at all (e.g. if the box changes size)

So, a good way would be to use

```<code>@override
bool shouldRepaint(MyPainter oldDelegate) =>
    oldDelegate.completePercent != completePercent;
</code>```

Body:
I'm trying to understand how shouldRepaint works.  I found a tutorial that paints a dial around a circle button to show its value.  The example had shouldRepaint always return true.  Basically it just paints a partial circle around the button to show the % value.  If the value is 50, the circle would go half way around.

I set shouldRepaint to always return false to see what would happen.  It still painted the button circle correctly.

My theory is that it will always paint when the stateful widget is redrawn.  So when the button value goes from 40% to 50%, the widget redraws and the painting is done no matter what.

So if my widget is painted anyway when the state changes, when would I use shouldRepaint?

Here is the relevant code from the tutorial:

class HomeContent extends StatefulWidget {
  @override
  _HomeContentState createState() => _HomeContentState();
}

class _HomeContentState extends State<HomeContent> {
  int percentage;

  @override
  void initState() {
    super.initState();
    setState(() {
      percentage = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new Container(
        height: 200.0,
        width: 200.0,
        child: new CustomPaint(
          foregroundPainter: new MyPainter(
              lineColor: Colors.amber,
          completeColor: Colors.blueAccent,
          completePercent: percentage,
          width: 8.0),
          child: new Padding(
          padding: const EdgeInsets.all(8.0),
        child: new RaisedButton(
            color: Colors.purple,
            splashColor: Colors.blueAccent,
            shape: new CircleBorder(),
            child: new Text("$percentage%"),
            onPressed: () {
              setState(() {
                percentage += 10;
                if (percentage > 100) {
                  percentage = 0;
                }
              });
            }),
          ),
        ),
      ),
    );
  }
}

class MyPainter extends CustomPainter {
  Color lineColor;
  Color completeColor;
  int completePercent;
  double width;

  MyPainter(
  {this.lineColor, this.completeColor, this.completePercent, this.width});

  @override
  void paint(Canvas canvas, Size size) {
    Paint line = new Paint()
      ..color = lineColor
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = width;
    Paint complete = new Paint()
      ..color = completeColor
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = width;
    Offset center = new Offset(size.width / 2, size.height / 2);
    double radius = min(size.width / 2, size.height / 2);
    canvas.drawCircle(center, radius, line);
    double arcAngle = 2 * pi * (completePercent / 100.0);
    if (arcAngle >= 2 * pi) arcAngle = 2 * pi - 0.001;  // cannot draw a complete circle arc
    canvas.drawArc(new Rect.fromCircle(center: center, radius: radius), -pi / 2,
    arcAngle, false, complete);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

Body:
From Docs, shouldRepaint():

If the new instance represents different information than the old instance, then the method should return true, otherwise it should return false

Also,

It's possible that the paint method will get called even if shouldRepaint returns false (e.g. if an ancestor or descendant needed to be repainted). It's also possible that the paint method will get called without shouldRepaint being called at all (e.g. if the box changes size)

So, a good way would be to use

@override
bool shouldRepaint(MyPainter oldDelegate) =>
    oldDelegate.completePercent != completePercent;


问:
DART - can I cast a string to an enum?
Is there a way to convert a string to an enum?

```<code>enum eCommand{fred, joe, harry}

eCommand theCommand= cast(eCommand, 'joe');??
</code>```

I think I just have to search for the enum (eg loop).

cheers

Steve

答:
I got annoyed with the state of enums and built a library to handle this:

https://pub.dev/packages/enum_to_string

Basic usage:

import 'package:enum_to_string:enum_to_string.dart';

enum TestEnum { testValue1 };

main(){
    final result = EnumToString.fromString(TestEnum.values, "testValue1");
    // TestEnum.testValue1
}
```

Still more verbose than I would like, but gets the job done.

Title: DART - can I cast a string to an enum?

Body:
Is there a way to convert a string to an enum?

enum eCommand{fred, joe, harry}

eCommand theCommand= cast(eCommand, 'joe');??

I think I just have to search for the enum (eg loop).

cheers

Steve

Body:
I got annoyed with the state of enums and built a library to handle this:

https://pub.dev/packages/enum_to_string

Basic usage:

import 'package:enum_to_string:enum_to_string.dart';

enum TestEnum { testValue1 };

main(){
    final result = EnumToString.fromString(TestEnum.values, "testValue1");
    // TestEnum.testValue1
}

Still more verbose than I would like, but gets the job done.


问:
Regular expression for dataframe column
I would like to take out only the date part of my dataframe column which has data like

```<code>$83,00010/7/2016       10/7/2016  # is the date here
$721,0002/7/2015       2/7/2015  # is the date here
$3,00012/12/2015       12/12/2015  # is the date here
</code>```

I tried patterns like

```<code>^(?!,\d{3}) and (\$[,\d{3}]*\,\d{3})
</code>```

but I am not able to exactly pick just the date part.

答:
The following regex will return you the date:</p>

```<code>',\d{3}(\d{1,2}/\d{1,2}/\d{4})$'
</code>```

Title: Regular expression for dataframe column

Body:
I would like to take out only the date part of my dataframe column which has data like

$83,00010/7/2016       10/7/2016  # is the date here
$721,0002/7/2015       2/7/2015  # is the date here
$3,00012/12/2015       12/12/2015  # is the date here

I tried patterns like

^(?!,\d{3}) and (\$[,\d{3}]*\,\d{3})

but I am not able to exactly pick just the date part.

Body:
The following regex will return you the date:

',\d{3}(\d{1,2}/\d{1,2}/\d{4})$'


问:
Waypoint mission is not Pausing
in onExecutionUpdate, I was checking isWaypointReached status. if the status is false the execution gets stopped and it's not giving any updates after that from the onExecutionUpdate callback.

```<code>@Override

public void onExecutionUpdate(final WaypointMissionExecutionEvent executionEvent) {

    int waypoint_size = executionEvent.getProgress().totalWaypointCount;
    int target_waypoint_index = executionEvent.getProgress().targetWaypointIndex;

    if (waypoint_size - 1 == target_waypoint_index) {
        if (executionEvent.getProgress().isWaypointReached == true) {
            if (executionEvent.getProgress().executeState.toString().equals("FINISHED_ACTION")) {
                setResultToToast("Aircraft reached at waypoint location");
                stopWaypointMission();
            }
        }

    } else {
        if (executionEvent.getProgress().isWaypointReached == true) {
            if (executionEvent.getProgress().executeState.toString().equals("BEGIN_ACTION")) {
                setResultToToast("aircraft reached at location " + "" + target_waypoint_index);
                pauseWaypointMission();
            }
        }

    }

}
</code>```

2019-05-29 12:03:28.442 12792-12834/? E/exe event: cur state=EXECUTING
  pre state=EXECUTING progress=total count=2 target index=0 is reached=
  false state=INITIALIZING error=null

2019-05-29 12:03:28.443 12792-12834/? E/waypoint_reached: false

答:
which dji sdk you are working on?  MSDK OSDK?

For DJI mission planning there are plenty of bugs. So you have to show the error message that you are receving, E.g

```<code>0xE9    Point data not enough
0xEA    WayPoint mission data not enough
0xEB    WayPoints not enough
</code>```

For mine case, I ask the drone to stop by calling mission::stop. it reply me with Point not enough. High chance is the ACK inside get stuck. I`m currently liaising with DJI for solving this issue.

If you can provide me with an accurate description and your error code, I can help you get the solution.

Title: Waypoint mission is not Pausing

Body:
in onExecutionUpdate, I was checking isWaypointReached status. if the status is false the execution gets stopped and it's not giving any updates after that from the onExecutionUpdate callback.

@Override

public void onExecutionUpdate(final WaypointMissionExecutionEvent executionEvent) {

    int waypoint_size = executionEvent.getProgress().totalWaypointCount;
    int target_waypoint_index = executionEvent.getProgress().targetWaypointIndex;

    if (waypoint_size - 1 == target_waypoint_index) {
        if (executionEvent.getProgress().isWaypointReached == true) {
            if (executionEvent.getProgress().executeState.toString().equals("FINISHED_ACTION")) {
                setResultToToast("Aircraft reached at waypoint location");
                stopWaypointMission();
            }
        }

    } else {
        if (executionEvent.getProgress().isWaypointReached == true) {
            if (executionEvent.getProgress().executeState.toString().equals("BEGIN_ACTION")) {
                setResultToToast("aircraft reached at location " + "" + target_waypoint_index);
                pauseWaypointMission();
            }
        }

    }

}

2019-05-29 12:03:28.442 12792-12834/? E/exe event: cur state=EXECUTING
  pre state=EXECUTING progress=total count=2 target index=0 is reached=
  false state=INITIALIZING error=null

2019-05-29 12:03:28.443 12792-12834/? E/waypoint_reached: false

Body:
which dji sdk you are working on?  MSDK OSDK?

For DJI mission planning there are plenty of bugs. So you have to show the error message that you are receving, E.g

0xE9    Point data not enough
0xEA    WayPoint mission data not enough
0xEB    WayPoints not enough

For mine case, I ask the drone to stop by calling mission::stop. it reply me with Point not enough. High chance is the ACK inside get stuck. I`m currently liaising with DJI for solving this issue.

If you can provide me with an accurate description and your error code, I can help you get the solution.


问:
How to use getenv() in php and SetEnv in a .htaccess with a compiled php-cgi on a shared host
Just putting in context to clarify the main question:

On my development machine, PHP5.3.1 is installed on Apache as a module, I use SetEnv APPLICATION_ENVIRONMENT development in my application's root .htaccess file. It is then easily retrievable from any php script with getenv('APPLICATION_ENVIRONMENT').

On the production server, on a sharedhost (dreamhost), I compiled myself php5.3.1 since it was not directly supported. Everything works fine except that getenv('APPLICATION_ENVIRONMENT') returns false.

In the sharedhost root .htaccess for my domain, I use this .htaccess file

```<code>Options +ExecCGI
AddHandler php-cgi .php
Action php-cgi /cgi-bin/php.cgi

<FilesMatch "^php5?\.(ini|cgi)$">
    Order Deny,Allow
    Deny from All
    Allow from env=REDIRECT_STATUS
</FilesMatch>

Options -indexes
</code>```

php5.cgi resides in /cgi-bin and works very well.
Of course in my application's root folder I have another .htaccess defining:

```<code>SetEnv APPLICATION_ENVIRONMENT production
</code>```

But when using getenv('APPLICATION_ENVIRONMENT') it returns false, any idea how to resolve this?

答:
In order for $_ENV to work, I had to reconfigure variables_order = "GPCSE" in php.ini. By default, it did not include E for $_ENV, it was originally variables_order = "GPCS"

This directive determines which super global arrays are registered when PHP starts up. G,P,C,E & S are abbreviations for the following respective super
  globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty
  paid for the registration of these arrays and because ENV is not as commonly
  used as the others, ENV is not recommended on productions servers. You
  can still get access to the environment variables through getenv() should you
  need to.

Default Value: "EGPCS"

Development Value: "GPCS"

Production Value: "GPCS";

http://php.net/variables-order

ContentLicense: CC BY-SA 2.5

Body:
Just putting in context to clarify the main question:

On my development machine, PHP5.3.1 is installed on Apache as a module, I use SetEnv APPLICATION_ENVIRONMENT development in my application's root .htaccess file. It is then easily retrievable from any php script with getenv('APPLICATION_ENVIRONMENT').

On the production server, on a sharedhost (dreamhost), I compiled myself php5.3.1 since it was not directly supported. Everything works fine except that getenv('APPLICATION_ENVIRONMENT') returns false.

In the sharedhost root .htaccess for my domain, I use this .htaccess file

Options +ExecCGI
AddHandler php-cgi .php
Action php-cgi /cgi-bin/php.cgi

<FilesMatch "^php5?\.(ini|cgi)$">
    Order Deny,Allow
    Deny from All
    Allow from env=REDIRECT_STATUS
</FilesMatch>

Options -indexes

php5.cgi resides in /cgi-bin and works very well.
Of course in my application's root folder I have another .htaccess defining:

SetEnv APPLICATION_ENVIRONMENT production

But when using getenv('APPLICATION_ENVIRONMENT') it returns false, any idea how to resolve this?


问:
How to find iOS elements with a Appium Java Client?
Can't seem to either find the right element or I am trying to coerce the returned element into the wrong type. Looking for the correct syntax to find a button to tap it. I am working with an iOS simulator build, Appium, running test with a Java Client.

AppTest.Java

  @Test (enabled=true) public void myFirstTest() throws InterruptedException {
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

**IOSElement button = driver.findElement(MobileBy.AccessibilityId("UIA_upsellPage_third_button"));**
```

<h1>Output</h1>

```org.openqa.selenium.WebDriverException: Returned value cannot be converted to WebElement: {element-6066-11e4-a52e-4f735466cecf=28000000-0000-0000-61D4-000000000000, ELEMENT=28000000-0000-0000-61D4-000000000000}
Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T15:28:36.4Z'
System info: host: 'C02R91M5G8WLMBP', ip: '2601:645:8002:1391:0:0:0:5d42%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '12.0.1'
Driver info: driver.version: IOSDriver
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:378)
    at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:62)
    at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
    at io.appium.java_client.ios.IOSDriver.findElement(IOSDriver.java:1)
    at io.appium.java_client.FindsByAccessibilityId.findElementByAccessibilityId(FindsByAccessibilityId.java:31)
    at io.appium.java_client.MobileBy$ByAccessibilityId.findElement(MobileBy.java:288)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:363)
    at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:58)
    at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
    at io.appium.java_client.ios.IOSDriver.findElement(IOSDriver.java:1)
    at com.media.automation.iphone_automation_1.AppTest.myFirstTest(AppTest.java:70)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
    at org.testng.SuiteRunner.run(SuiteRunner.java:364)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
    at org.testng.TestNG.runSuites(TestNG.java:1049)
    at org.testng.TestNG.run(TestNG.java:1017)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Caused by: java.lang.ClassCastException: class java.util.HashMap cannot be cast to class org.openqa.selenium.WebElement (java.util.HashMap is in module java.base of loader 'bootstrap'; org.openqa.selenium.WebElement is in unnamed module of loader 'app')
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:376)
    ... 35 more
```

Expected Result:
Should return an element that can be tapped with a method to mimic a button press.

Actual Result: org.openqa.selenium.WebDriverException: Returned value cannot be converted to WebElement: {element-6066-11e4-a52e-4f735466cecf=28000000-0000-0000-61D4-000000000000, ELEMENT=28000000-0000-0000-61D4-000000000000}

答: You can integrate simulator with safari browser for web view app or you can use appium studio for native app</p>

Body:
Can't seem to either find the right element or I am trying to coerce the returned element into the wrong type. Looking for the correct syntax to find a button to tap it. I am working with an iOS simulator build, Appium, running test with a Java Client.

AppTest.Java

  @Test (enabled=true) public void myFirstTest() throws InterruptedException {
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

**IOSElement button = driver.findElement(MobileBy.AccessibilityId("UIA_upsellPage_third_button"));**

Output

org.openqa.selenium.WebDriverException: Returned value cannot be converted to WebElement: {element-6066-11e4-a52e-4f735466cecf=28000000-0000-0000-61D4-000000000000, ELEMENT=28000000-0000-0000-61D4-000000000000}
Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T15:28:36.4Z'
System info: host: 'C02R91M5G8WLMBP', ip: '2601:645:8002:1391:0:0:0:5d42%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '12.0.1'
Driver info: driver.version: IOSDriver
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:378)
    at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:62)
    at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
    at io.appium.java_client.ios.IOSDriver.findElement(IOSDriver.java:1)
    at io.appium.java_client.FindsByAccessibilityId.findElementByAccessibilityId(FindsByAccessibilityId.java:31)
    at io.appium.java_client.MobileBy$ByAccessibilityId.findElement(MobileBy.java:288)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:363)
    at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:58)
    at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
    at io.appium.java_client.ios.IOSDriver.findElement(IOSDriver.java:1)
    at com.media.automation.iphone_automation_1.AppTest.myFirstTest(AppTest.java:70)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
    at org.testng.SuiteRunner.run(SuiteRunner.java:364)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
    at org.testng.TestNG.runSuites(TestNG.java:1049)
    at org.testng.TestNG.run(TestNG.java:1017)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Caused by: java.lang.ClassCastException: class java.util.HashMap cannot be cast to class org.openqa.selenium.WebElement (java.util.HashMap is in module java.base of loader 'bootstrap'; org.openqa.selenium.WebElement is in unnamed module of loader 'app')
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:376)
    ... 35 more

Expected Result:
Should return an element that can be tapped with a method to mimic a button press.

Actual Result: org.openqa.selenium.WebDriverException: Returned value cannot be converted to WebElement: {element-6066-11e4-a52e-4f735466cecf=28000000-0000-0000-61D4-000000000000, ELEMENT=28000000-0000-0000-61D4-000000000000}


问:
Front-end/Back-end design: how to absolutely dissociate the back-end from the front-end?
My question is: (is the above|what is) the right way to create a non intrusive front-end?

I am explaining my problem with a simplified example.

I have a back-end implementing a binary tree:

```<code>// Back-end
struct Node
{
  Label label;
  Node* r, l;
};
</code>```

I would like now to implement the front-end to print the tree graphically. So my idea is to extend the back-end with graphical properties by wrapping it :

```<code>// Front-end
struct Drawable
{
  uint x, y;
};

class Visitor;
template <class T> struct GNode : public Drawable
{
  T* wrapped;
  template <class V> void accept(V& v); // v.visit(*this);
}
</code>```

There is a problem now to create a visitor printing the binary tree:

```<code>struct Visitor
{
    void visit(GNode<Node>& n)
    {
      // print the label and a circle around it: ok.

      if (n.wrapped.l) // l is a Node, not a GNode, I can't use the visitor on it
        // Problem: how to call this visitor on the node's left child?

      // the same with n.wrapped.r
    };
};
</code>```

As explained in comments, the back-end does not use my extended class.

Writing GNode "is-a" Node is not a solution neither since I would have to put the accept() method in the Node class as virtual and override it in GNode but I can't modify the back-end. Then, someone could say too that there is no need to declare accept() in the back-end, downcasting Node* to GNode* would work. Yes it works, but it downcasts...

In my case, I have ~10 kinds of nodes (it is a graph), so I am looking for something elegant, flexible, with as few lines of code as possible (hence the wrapper template idea) :)

Thank you very much.

答: Personally, I would make a drawing class with overloaded functions (one for each node type) rather than trying to hook into the existing structure with some sort of complicated inheritance solution.</p>

Body:
My question is: (is the above|what is) the right way to create a non intrusive front-end?

I am explaining my problem with a simplified example.

I have a back-end implementing a binary tree:

// Back-end
struct Node
{
  Label label;
  Node* r, l;
};

I would like now to implement the front-end to print the tree graphically. So my idea is to extend the back-end with graphical properties by wrapping it :

// Front-end
struct Drawable
{
  uint x, y;
};

class Visitor;
template <class T> struct GNode : public Drawable
{
  T* wrapped;
  template <class V> void accept(V& v); // v.visit(*this);
}

There is a problem now to create a visitor printing the binary tree:

struct Visitor
{
    void visit(GNode<Node>& n)
    {
      // print the label and a circle around it: ok.

      if (n.wrapped.l) // l is a Node, not a GNode, I can't use the visitor on it
        // Problem: how to call this visitor on the node's left child?

      // the same with n.wrapped.r
    };
};

As explained in comments, the back-end does not use my extended class.

Writing GNode "is-a" Node is not a solution neither since I would have to put the accept() method in the Node class as virtual and override it in GNode but I can't modify the back-end. Then, someone could say too that there is no need to declare accept() in the back-end, downcasting Node* to GNode* would work. Yes it works, but it downcasts...

In my case, I have ~10 kinds of nodes (it is a graph), so I am looking for something elegant, flexible, with as few lines of code as possible (hence the wrapper template idea) :)

Thank you very much.


问:
Firebase Path Specified Exceeds Maximum Depth that Can Be Written
I am trying to write to Firebase via the code below:

```<code>  mSubmitPollCreation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            //TODO: Need to determine if this is proper epoch - i.e. does it account for time zones
            Calendar c = Calendar.getInstance();
            final String epochTime = String.valueOf(c.getTimeInMillis());
            mEpochRef = mBaseRef.child("Polls").child(epochTime);

            //TODO: Need to check if poll requirements are added, i.e. Question, Answer, ......
            //check if image has been loaded first
            if (resultImageURL != null){
                Map<String, Object> imageURL = new HashMap<String, Object>();
                imageURL.put("Image_URL", imageURL);
                mEpochRef.setValue(imageURL);
            } else {
                Toast.makeText(getApplicationContext(),getResources().getString(R.string.no_image_selected),Toast.LENGTH_LONG).show();
                return;
            }
     });
</code>```

And I unsure why I am receiving the following error:

```<code>   Process: com.troychuinard.fanpolls, PID: 6409
                                                               com.google.firebase.database.DatabaseException: Path specified exceeds the maximum depth that can be written (32) or object contains a cycle in path 'Polls/1481160966268/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL'
                                                                             at com.google.android.gms.internal.zzajo.zzcms(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzsx(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zza(Unknown Source)
                                                                             at com.google.firebase.database.DatabaseReference.zza(Unknown Source)
                                                                             at com.google.firebase.database.DatabaseReference.setValue(Unknown Source)
                                                                             at com.troychuinard.fanpolls.CreateActivity$2.onClick(CreateActivity.java:103)
                                                                             at android.view.View.performClick(View.java:5210)
                                                                             at android.view.View$PerformClick.run(View.java:21294)
                                                                             at android.os.Handler.handleCallback(Handler.java:739)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                             at android.os.Looper.loop(Looper.java:148)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:5527)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
</code>```

It looks like for some reason my code is looping through creating the database point, however I am unsure why it is doing this.

答: instead of this task.getResult() use this task.getResult().toString() for storing locally.

Body:
I am trying to write to Firebase via the code below:

  mSubmitPollCreation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            //TODO: Need to determine if this is proper epoch - i.e. does it account for time zones
            Calendar c = Calendar.getInstance();
            final String epochTime = String.valueOf(c.getTimeInMillis());
            mEpochRef = mBaseRef.child("Polls").child(epochTime);

            //TODO: Need to check if poll requirements are added, i.e. Question, Answer, ......
            //check if image has been loaded first
            if (resultImageURL != null){
                Map<String, Object> imageURL = new HashMap<String, Object>();
                imageURL.put("Image_URL", imageURL);
                mEpochRef.setValue(imageURL);
            } else {
                Toast.makeText(getApplicationContext(),getResources().getString(R.string.no_image_selected),Toast.LENGTH_LONG).show();
                return;
            }
     });

And I unsure why I am receiving the following error:

   Process: com.troychuinard.fanpolls, PID: 6409
                                                               com.google.firebase.database.DatabaseException: Path specified exceeds the maximum depth that can be written (32) or object contains a cycle in path 'Polls/1481160966268/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL/Image_URL'
                                                                             at com.google.android.gms.internal.zzajo.zzcms(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzsx(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zzbs(Unknown Source)
                                                                             at com.google.android.gms.internal.zzajo.zza(Unknown Source)
                                                                             at com.google.firebase.database.DatabaseReference.zza(Unknown Source)
                                                                             at com.google.firebase.database.DatabaseReference.setValue(Unknown Source)
                                                                             at com.troychuinard.fanpolls.CreateActivity$2.onClick(CreateActivity.java:103)
                                                                             at android.view.View.performClick(View.java:5210)
                                                                             at android.view.View$PerformClick.run(View.java:21294)
                                                                             at android.os.Handler.handleCallback(Handler.java:739)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                             at android.os.Looper.loop(Looper.java:148)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:5527)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

It looks like for some reason my code is looping through creating the database point, however I am unsure why it is doing this.


问:
Unable to show the elements in a single line in a layout
My Android layout is as follows:

```<code><LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/notification_content"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="left|bottom"
                android:layout_marginEnd="1dp"
                android:ellipsize="end"
                android:fadingEdge="horizontal"
                android:maxLines="4"
                android:singleLine="false"
                android:textAppearance="@style/Ds6"
                android:textColor="@color/notification_ds6_secondary_text"
                tools:text="Watched item ends in 6 minutes in "
                android:visibility="visible"
                tools:ignore="Deprecated"/>

            <Chronometer
                android:id="@+id/notification_countdown"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:gravity="left|bottom"
                android:maxLines="1"
                android:textAppearance="@style/Ds6"
                android:textColor="@color/notification_ds6_secondary_text"
                android:textSize="@dimen/TextSizeSmall"
                android:visibility="visible"
                tools:text="10:02 AM" />

            <Chronometer
                android:id="@+id/notification_countdown_60s"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="left|bottom"
                android:gravity="left"
                android:maxLines="1"
                android:textColor="@color/alert_color"
                android:textAppearance="@style/Ds6"
                android:textSize="@dimen/TextSizeSmall"
                android:visibility="visible"
                tools:text="10:02 AM" />
            <TextView
                android:id="@+id/notification_time_expired"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="left|bottom"
                android:text="00:00"
                android:textColor="@color/notification_ds6_disabled_text"
                android:textAppearance="@style/Ds6"
                android:textSize="@dimen/TextSizeSmall"
                android:visibility="visible" />
            </LinearLayout>
</code>```

I want the text view content to wrap correctly to accommodate the Chronometer # 1, Chrometer # 2 and Chronometer # 3 to be displayed on a single line. This does not happen for longer text strings.

But if I reduce the text string length as shown below, and I can see all the elements in a single line. How do I display all the elements in a single line? I want the text to wrap but the two chronometers, and text view # 2 have to be on the same line as the first text view.

This is going to be shown in a notification remote view, so I can't use ConstraintLayout. I can only use FrameLayout, RelativeLayout, and LinearLayout.

答:
try to set android:layout_width="0dp" and android:layout_weight="1" in your notification_content TextView

Try this way

```<code><LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="2dp"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/notification_content"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_gravity="left|bottom"
        android:layout_marginEnd="1dp"
        android:ellipsize="end"
        android:fadingEdge="horizontal"
        android:maxLines="4"
        android:singleLine="false"
        android:textColor="@color/colorPrimary"
        tools:text="Watched item ends in 6 minutes in "
        android:visibility="visible"
        tools:ignore="Deprecated"/>

    <Chronometer
        android:id="@+id/notification_countdown"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:gravity="left|bottom"
        android:maxLines="1"
        android:textColor="@color/colorPrimary"
        android:visibility="visible"
        tools:text="10:02 AM" />

    <Chronometer
        android:id="@+id/notification_countdown_60s"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="left|bottom"
        android:gravity="left"
        android:maxLines="1"
        android:textColor="@color/colorAccent"
        android:visibility="visible"
        tools:text="10:02 AM" />
    <TextView
        android:id="@+id/notification_time_expired"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="left|bottom"
        android:text="00:00"
        android:textColor="@color/colorPrimary"
        android:visibility="visible" />
</LinearLayout>
</code>```

Body:
My Android layout is as follows:

<LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/notification_content"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="left|bottom"
                android:layout_marginEnd="1dp"
                android:ellipsize="end"
                android:fadingEdge="horizontal"
                android:maxLines="4"
                android:singleLine="false"
                android:textAppearance="@style/Ds6"
                android:textColor="@color/notification_ds6_secondary_text"
                tools:text="Watched item ends in 6 minutes in "
                android:visibility="visible"
                tools:ignore="Deprecated"/>

            <Chronometer
                android:id="@+id/notification_countdown"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:gravity="left|bottom"
                android:maxLines="1"
                android:textAppearance="@style/Ds6"
                android:textColor="@color/notification_ds6_secondary_text"
                android:textSize="@dimen/TextSizeSmall"
                android:visibility="visible"
                tools:text="10:02 AM" />

            <Chronometer
                android:id="@+id/notification_countdown_60s"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="left|bottom"
                android:gravity="left"
                android:maxLines="1"
                android:textColor="@color/alert_color"
                android:textAppearance="@style/Ds6"
                android:textSize="@dimen/TextSizeSmall"
                android:visibility="visible"
                tools:text="10:02 AM" />
            <TextView
                android:id="@+id/notification_time_expired"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="left|bottom"
                android:text="00:00"
                android:textColor="@color/notification_ds6_disabled_text"
                android:textAppearance="@style/Ds6"
                android:textSize="@dimen/TextSizeSmall"
                android:visibility="visible" />
            </LinearLayout>

I want the text view content to wrap correctly to accommodate the Chronometer # 1, Chrometer # 2 and Chronometer # 3 to be displayed on a single line. This does not happen for longer text strings.

But if I reduce the text string length as shown below, and I can see all the elements in a single line. How do I display all the elements in a single line? I want the text to wrap but the two chronometers, and text view # 2 have to be on the same line as the first text view.

This is going to be shown in a notification remote view, so I can't use ConstraintLayout. I can only use FrameLayout, RelativeLayout, and LinearLayout.

Body:
try to set android:layout_width="0dp" and android:layout_weight="1" in your notification_content TextView

Try this way

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="2dp"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/notification_content"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_gravity="left|bottom"
        android:layout_marginEnd="1dp"
        android:ellipsize="end"
        android:fadingEdge="horizontal"
        android:maxLines="4"
        android:singleLine="false"
        android:textColor="@color/colorPrimary"
        tools:text="Watched item ends in 6 minutes in "
        android:visibility="visible"
        tools:ignore="Deprecated"/>

    <Chronometer
        android:id="@+id/notification_countdown"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:gravity="left|bottom"
        android:maxLines="1"
        android:textColor="@color/colorPrimary"
        android:visibility="visible"
        tools:text="10:02 AM" />

    <Chronometer
        android:id="@+id/notification_countdown_60s"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="left|bottom"
        android:gravity="left"
        android:maxLines="1"
        android:textColor="@color/colorAccent"
        android:visibility="visible"
        tools:text="10:02 AM" />
    <TextView
        android:id="@+id/notification_time_expired"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="left|bottom"
        android:text="00:00"
        android:textColor="@color/colorPrimary"
        android:visibility="visible" />
</LinearLayout>


问:
Insert Greek Character to a MySQL table column without using PHP
We have a MySQL table as below:

```<code>CREATE TABLE Test
(
ID INT(11),
Value VARCHAR(100)
);
</code>```

I want to use INSERT query and load Greek data into Value column. I would like to reiterate that I do not want any involvement of PHP or any 3rd party vendor tool.

I have already tried with INSERT query as below. The query gets executed. When you perform a SELECT to the table we see ????? marks instead of the data.

Additionally, I have also tried changing the character set but does not help.

NOTE : The issue seems to seen in MySQL version 5.5 where as in v8.0 we see the Greek data

```<code>INSERT INTO TEST VALUES (1,'ΜΑΣΟΥΤΗΣ Δ. Α.Ε');

SELECT * FROM TEST;
</code>```

The Expected result is to see the Greek data into the Table, but actually we see ?????.

答:
5.5 defaulted to CHARACTER SET latin1 for any table using the default.

8.0's default is CHARACTER SET utf8mb4.

To get 5.5 to work correctly, specify the character set on the table definition.  For Greek, either utf8 or utf8mb4 will work.

See "question mark" in Trouble with UTF-8 characters; what I see is not what I stored

Note:  In 5.5 or 5.6, if you index a column that is VARCHAR(255) CHARACTER SET utf8mb4, you will get an error.  This can be worked around in several ways.

See http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes

Body:
We have a MySQL table as below:

CREATE TABLE Test
(
ID INT(11),
Value VARCHAR(100)
);

I want to use INSERT query and load Greek data into Value column. I would like to reiterate that I do not want any involvement of PHP or any 3rd party vendor tool.

I have already tried with INSERT query as below. The query gets executed. When you perform a SELECT to the table we see ????? marks instead of the data.

Additionally, I have also tried changing the character set but does not help.

NOTE : The issue seems to seen in MySQL version 5.5 where as in v8.0 we see the Greek data

INSERT INTO TEST VALUES (1,'ΜΑΣΟΥΤΗΣ Δ. Α.Ε');

SELECT * FROM TEST;

The Expected result is to see the Greek data into the Table, but actually we see ?????.


问:
The compiler compliance specified is 1.6 but a JRE 1.8 is used
My eclipse reported the warning that "The compiler compliance specified is 1.6 but a JRE 1.8 is used".

I have built my HelloWorld Android application using Java1.8, however, I got that warning and I cannot build up my project. I have tried to set the compiler compliance to java1.8. But I got another error that

"Android requires compiler compliance level 5.0 or 6.0. Found '1.8'"

.I don't know how to fix this problem?

答:
Possible solution:

Right-click on your project and select "Android Tools -> Fix Project Properties". (if this doesn't work, try the following option)

Right-click on your project and select "Properties -> Java Compiler", check "Enable project specific settings" and select
    1.5 or 1.6 from the "Compiler compliance settings" select box.

Under Window -> Preferences -> Java -> Compiler, set Compiler
compliance level to 1.5 or 1.6.