问:
In a Chrome extension, how to ensure previous promise resolves before the next one using chrome-promise?
I've been using the chrome-promise library to wrap the Chrome extension API with a facade that returns promises instead of using callbacks.  This has generally worked quite well, but I seem to be running into an issue with chrome.storage.local APIs.

My extension's event page listens for the chrome.tabs.onActivated and chrome.tabs.onRemoved events.  When it gets the onActivated event, it adds the tab info to an array and calls chrome.storage.local.set(data) to store the updated array in local storage.

When it gets the onRemoved event, it calls chromepromise.storage.local.get(null).then(...) to get the list of tabs via a promise, removes the tab info from the array, and then calls chrome.storage.local.set() again to save the updated array.

The issue is that the onActivated event seems to trigger before the promise flow from the onRemoved event resolves.  So the onActivated handler retrieves the old stored array, with the closed tab still in it, and then pushes the newly activated tab.  So the stored tab data now includes a tab that's already been closed.

I'm assuming this is an issue with using promises instead of callbacks, but I'm wondering if anyone else has run into this problem with this library and worked around it.

Update

As wOxxOm points out, this is a generic problem with "arbitrating unpredictable asynchronous access to a single resource such as chrome.storage" and not unique to the chrome-promise library.

After researching a bit, I came up with a couple solutions, added as answers below.  One uses a mutex to ensure (I think) that one promise chain's getting and setting data in chrome.storage completes before the next one starts.  The other queues the whole promise chain that's created from an event and doesn't start the next one until the current one has fully completed.  I'm not sure which is better, though I suppose locking for a shorter period of time is better.

Any suggestions or better answers are welcome.

答:
Mutex

Update: I ended up using the approach below to create a module that uses a mutex to ensure gets and sets of the Chrome extension storage maintain their order.  It seems to be working well so far.

This solution uses the mutex implementation from this article.  addTab() and removeTab() call storageMutex.synchronize() with a function that does all the storage getting and setting.  This should prevent later events from affecting the storage of earlier events.

The code below is a very simplified version of the extension, but it does run.  The playNextEvent() calls at the bottom simulate opening 4 tabs, switching back to tab 2 and closing it, which then causes tab 3 to activate.  setTimeout()s are used so that everything doesn't run as one long call stack.

function Mutex() {
    this._busy  = false;
    this._queue = [];
}

Object.assign(Mutex.prototype, {
    synchronize: function(task) {
        var self = this;

        return new Promise(function(resolve, reject) {
            self._queue.push([task, resolve, reject]);
            if (!self._busy) {
                self._dequeue();
            }
        });
    },

    _dequeue: function() {
        var next = this._queue.shift();

        if (next) {
            this._busy = true;
            this._execute(next);
        } else {
            this._busy = false;
        }
    },

    _execute: function(record) {
        var task = record[0],
            resolve = record[1],
            reject = record[2],
            self = this;

        task().then(resolve, reject).then(function() {
            self._dequeue();
        });
    }
});

const storageMutex = new Mutex();

function onActivated(tabID) {
    console.log("EVENT onActivated", tabID);
    return Promise.resolve(tabID).then(tab => addTab(tab));
}

function onRemoved(tabID) {
    console.log("EVENT onRemoved", tabID);
    return removeTab(tabID);
}

var localData = {
        tabs: []
    };

function delay(time) {
   return new Promise(resolve => setTimeout(resolve, time));
}

function getData()
{
    return delay(0).then(() => JSON.parse(JSON.stringify(localData)));
}

function saveData(data, source)
{
    return delay(0)
        .then(() => {
            localData = data;
            console.log("save from:", source, "localData:", localData);
            return Promise.resolve(localData);
        });
}

function addTab(tabID)
{
    return storageMutex.synchronize(() => getData().then((data) => {
        console.log("addTab", tabID, "data:", data);
        data.tabs = data.tabs.filter(tab => tab != tabID);
        data.tabs.push(tabID);
        return saveData(data, "addTab");
    }));
}

function removeTab(tabID)
{
    return storageMutex.synchronize(() => getData().then((data) => {
        console.log("removeTab", tabID, "data:", data);
        data.tabs = data.tabs.filter(tab => tab != tabID);
        return saveData(data, "removeTab");
    }));
}

const events = [
    () => onActivated(1),
    () => onActivated(2),
    () => onActivated(3),
    () => onActivated(4),
    () => onActivated(2),
    () => { onRemoved(2); onActivated(3) }
];

function playNextEvent()
{
    var event = events.shift();

    if (event) {
        delay(0).then(() => { event(); delay(0).then(playNextEvent) });
    }
}

playNextEvent();```


来源: stackexchange

问:
Fading in and Fading Out in AngularsJs?
i am new in Angulars, i am using the 1.6.5 version ..

i want my element to fadeIn on click not just showing up, and fading out on click instead of just being hidden, here is my code HTML :

```<code><ul>
            <li class="try" ng-if="bool"><label>email</label> : taoufiq.benallah@gmail.com</li>
            <li ng-click="bool=false"><label>téléphone</label> : +2126-13-85-98-34 </li>
            <li ng-click="bool=true"><label>website</label> : oujda.ma.taoufiq.com</li>
</ul>
</code>```

And here is my CSS File :

```<code>.try.ng-enter {
transition: 2s all;
opacity: 1;
}

.try.ng-enter.ng-enter-active {
transition: 2s all;
opacity: 1;
 }

.try.ng-leave {
transition: 2s all;
opacity : 1;
 }
.try.ng-leave.ng-leave-active {
transition: 2s all;
opacity: 1;
 }
</code>```

The problem i am having is that my element doesnt appear in 2s but immediatly ..
Thank for any help.

答:
The reason it happens is because you're using ng-if. This makes your element disappear from DOM completely. Change it to ng-show and it will resolve your issue.

Complete code:

```<code><ul>
   <li class="try" ng-show="bool"><label>email</label> : taoufiq.benallah@gmail.com</li>
   <li ng-click="bool=false"><label>téléphone</label> : +2126-13-85-98-34 </li>
   <li ng-click="bool=true"><label>website</label> : oujda.ma.taoufiq.com</li>
</ul>
</code>```

ContentLicense: CC BY-SA 3.0

Title: Fading in and Fading Out in AngularsJs?

Body:
i am new in Angulars, i am using the 1.6.5 version ..

i want my element to fadeIn on click not just showing up, and fading out on click instead of just being hidden, here is my code HTML :

email : taoufiq.benallah@gmail.com

téléphone : +2126-13-85-98-34

website : oujda.ma.taoufiq.com

And here is my CSS File :

.try.ng-enter {
transition: 2s all;
opacity: 1;
}

.try.ng-enter.ng-enter-active {
transition: 2s all;
opacity: 1;
 }

.try.ng-leave {
transition: 2s all;
opacity : 1;
 }
.try.ng-leave.ng-leave-active {
transition: 2s all;
opacity: 1;
 }

The problem i am having is that my element doesnt appear in 2s but immediatly ..
Thank for any help.

Body:
The reason it happens is because you're using ng-if. This makes your element disappear from DOM completely. Change it to ng-show and it will resolve your issue.

Complete code:

<ul>
   <li class="try" ng-show="bool"><label>email</label> : taoufiq.benallah@gmail.com</li>
   <li ng-click="bool=false"><label>téléphone</label> : +2126-13-85-98-34 </li>
   <li ng-click="bool=true"><label>website</label> : oujda.ma.taoufiq.com</li>
</ul>


问:
WPF ProgressBar doesn't show progress
I am confused by WPF ProgressBar. Here is the code I have written to display it:

```<code><ProgressBar Height="31" Margin="15" Name="progressBar"
VerticalAlignment="Top" IsIndeterminate="True" />
</code>```

As I know this is enough to make it work. But it doesn't work in my project. I mean when I show window (Popup actually as it's xbap project) progressbar doesn't show any animation, however it is visible.

There are no background threads yet, UI thread is not blocked.

What is wrong?

答:
There are no background threads yet, UI thread is not blocked.

I think you have that exactly wrong, and that's your problem.  You have no background threads, and thus your UI thread is blocked.  If your method that updates the progress bar is running on the UI thread (which it is, if you're not running it on a background thread), updates to the progress bar won't appear until the method is done running and control is returned to the Dispatcher.

You need to run your long-running method on a background thread using a BackgroundWorker, and update the progress bar by raising and handling its ProgressChanged event.  The event handler runs on the UI thread, and can update UI objects.

ContentLicense: CC BY-SA 2.5

Title: WPF ProgressBar doesn't show progress

Body:
I am confused by WPF ProgressBar. Here is the code I have written to display it:

<ProgressBar Height="31" Margin="15" Name="progressBar"
VerticalAlignment="Top" IsIndeterminate="True" />

As I know this is enough to make it work. But it doesn't work in my project. I mean when I show window (Popup actually as it's xbap project) progressbar doesn't show any animation, however it is visible.

There are no background threads yet, UI thread is not blocked.

What is wrong?


问:
how to create custom list with sonata admin
I can't find (understand) how to add items and cathegories to Left Side Admin Menu.
There is no detailed tutorial how to do this.
I can add items to sonata.admin.block.admin_list but to aside Admin Menu
enter image description here</p>

答:
You need to add a route to your routing:

```<code>admin.blog_post:
    class: db306\CoreBundle\Admin\BlogPostAdmin
    arguments: [~, db306\CoreBundle\Entity\BlogPost, ~]
    tags:
        - { name: sonata.admin, manager_type: orm, group: Content, label: Blog post }
    public: true

admin.category:
    class: db306\CoreBundle\Admin\CategoryAdmin
    arguments: [~, db306\CoreBundle\Entity\Category, ~]
    tags:
        - { name: sonata.admin, manager_type: orm, group: Content, label: Category }
    public: true
</code>```

This will display a "Content" tab on that menu displayed on your screenshot with 2 options: 'Blog post' and 'Category'

Body:
You need to add a route to your routing:

admin.blog_post:
    class: db306\CoreBundle\Admin\BlogPostAdmin
    arguments: [~, db306\CoreBundle\Entity\BlogPost, ~]
    tags:
        - { name: sonata.admin, manager_type: orm, group: Content, label: Blog post }
    public: true

admin.category:
    class: db306\CoreBundle\Admin\CategoryAdmin
    arguments: [~, db306\CoreBundle\Entity\Category, ~]
    tags:
        - { name: sonata.admin, manager_type: orm, group: Content, label: Category }
    public: true

This will display a "Content" tab on that menu displayed on your screenshot with 2 options: 'Blog post' and 'Category'


问:
Write function in linux kernel module is called repeatedly
I am writing a character device driver in C for Linux and have run into a problem where my module_write function is being called repeatedly. What could be causing this?

Attached is a screenshot of the command used to write to the device file and the kernel log output

As you can see, it looks as though the module_write function is being called repeatedly. It doesn't matter how I write to the file (I tried using vim, echo and tee)

Source: https://gist.github.com/SamTebbs33/8ed6a1d165fae1ca27fff5b495d04797

答:
You keep saying that 0 bytes were successfully written, so the program keeps trying to write its three bytes.

You should instead be returning the number of bytes you processed successfully from the buffer.


问:
HTML5 Changing paragraphs background color with button js
I got small troubles with this one:

```<code><style>
p:empty {height:20px};
p:nth-child(4n+3) {background:black};
</style>
</head>

<body>

<button onclick="f()">white</button>
<script>
function f() {
var x = document.getElementsByTagName("p");
x.style.backgroundColor = "white";
}
</script>

<p></p>
<p></p>
<p></p>
....
</code>```

(there are 20paragraphs)
So every 4th paragraph got black background, and it all works well.
I want this button to switch black back to the white after clicking on it, but it's just not working, what am I doing wrong?

答:
So the problem here is that you are using getElementsByTagName which will return you an array of all the instances of the "p" element. There for when you say
x.style.backgroundColor = "white"

you need to specify which "p" in your array you want to change, like I have below
x[3].style.backgroundColor = "white"

... you can probably do something like this

```<code>function f() {
var x = document.getElementsByTagName("p");

for(var i=0; i<x.length; i=i+4) {

 x[i].style.backgroundColor = "white";

 }
}
</code>```

Body:
I got small troubles with this one:

<button onclick="f()">white</button>

....

(there are 20paragraphs)
So every 4th paragraph got black background, and it all works well.
I want this button to switch black back to the white after clicking on it, but it's just not working, what am I doing wrong?

Body:
So the problem here is that you are using getElementsByTagName which will return you an array of all the instances of the "p" element. There for when you say
x.style.backgroundColor = "white"

you need to specify which "p" in your array you want to change, like I have below
x[3].style.backgroundColor = "white"

... you can probably do something like this

function f() {
var x = document.getElementsByTagName("p");

for(var i=0; i<x.length; i=i+4) {

 x[i].style.backgroundColor = "white";

 }
}


问:
Using Kryo serialization with Gemfire or Geode
I am looking to use the Kryo serialization library (https://github.com/EsotericSoftware/kryo) with Pivotal Gemfire 8.x onwards. However, there is not much information available on how to do that. If anyone has a code/config snippet to show how to integrate Kryo serialization with Pivotal Gemfire or Apache Geode that will be very useful.

Thanks.

答:
One option is just to store serialized bytes in a geode region, eg

```<code> byte[] bytes = serializeWithKyro(myObject)
 region.put("key", bytes)
</code>```

Another option would be to register a DataSerializer that can serialize with Kyro:

```<code>DataSerializer.register(KyroSerializer.class)

public class KyroSerializer extends DataSerializer {
    public boolean toData(Object o, DataOutput out) {
        if(!(o instanceof MyClass)) {
            return false;
        }
        writeWithKyro(o, out);
    }
    ...

}
</code>```

You can check out the DataSerializer javadocs for more info.

Body:
One option is just to store serialized bytes in a geode region, eg

 byte[] bytes = serializeWithKyro(myObject)
 region.put("key", bytes)

Another option would be to register a DataSerializer that can serialize with Kyro:

DataSerializer.register(KyroSerializer.class)

public class KyroSerializer extends DataSerializer {
    public boolean toData(Object o, DataOutput out) {
        if(!(o instanceof MyClass)) {
            return false;
        }
        writeWithKyro(o, out);
    }
    ...

}

You can check out the DataSerializer javadocs for more info.


答:
Queue

This solution uses a very simple queuing mechanism.  The event handlers call queue() with a function that kicks off the promise chain to handle that event.  If there isn't already a promise in the queue, then the function is called immediately.  Otherwise, it's pushed on the queue and will be triggered when the current promise chain finishes.  This means only one event can be processed at a time, which might not be as efficient.

var taskQueue = [];

function queue(
    fn)
{
    taskQueue.push(fn);
    processQueue();
}

function processQueue()
{
    const nextTask = taskQueue[0];

    if (nextTask && !(nextTask instanceof Promise)) {
        taskQueue[0] = nextTask()
            .then((result) => {
                console.log("RESULT", result);
                taskQueue.shift();
                processQueue();
        });
    }
}

function onActivated(tabID) {
    console.log("EVENT onActivated", tabID);
    queue(() => Promise.resolve(tabID).then(tab => addTab(tab)));
}

function onRemoved(tabID) {
    console.log("EVENT onRemoved", tabID);
    queue(() => removeTab(tabID));
}

var localData = {
        tabs: []
    };

function delay(time) {
   return new Promise(resolve => setTimeout(resolve, time));
}

function getData()
{
    return delay(0).then(() => JSON.parse(JSON.stringify(localData)));
}

function saveData(data, source)
{
    return delay(0)
        .then(() => {
            localData = data;
            console.log("save from:", source, "localData:", localData);
            return Promise.resolve(localData);
        });
}

function addTab(tabID)
{
    return getData().then((data) => {
        console.log("addTab", tabID, "data:", data);
        data.tabs = data.tabs.filter(tab => tab != tabID);
        data.tabs.push(tabID);
        return saveData(data, "addTab");
    });
}

function removeTab(tabID)
{
    return getData().then((data) => {
        console.log("removeTab", tabID, "data:", data);
        data.tabs = data.tabs.filter(tab => tab != tabID);
        return saveData(data, "removeTab");
    });
}

const events = [
    () => onActivated(1),
    () => onActivated(2),
    () => onActivated(3),
    () => onActivated(4),
    () => onActivated(2),
    () => { onRemoved(2); onActivated(3) }
];

function playNextEvent()
{
    var event = events.shift();

    if (event) {
        delay(0).then(() => { event(); delay(0).then(playNextEvent) });
    }
}

playNextEvent();```

Title: In a Chrome extension, how to ensure previous promise resolves before the next one using chrome-promise?

Body:
I've been using the chrome-promise library to wrap the Chrome extension API with a facade that returns promises instead of using callbacks.  This has generally worked quite well, but I seem to be running into an issue with chrome.storage.local APIs.

My extension's event page listens for the chrome.tabs.onActivated and chrome.tabs.onRemoved events.  When it gets the onActivated event, it adds the tab info to an array and calls chrome.storage.local.set(data) to store the updated array in local storage.

When it gets the onRemoved event, it calls chromepromise.storage.local.get(null).then(...) to get the list of tabs via a promise, removes the tab info from the array, and then calls chrome.storage.local.set() again to save the updated array.

The issue is that the onActivated event seems to trigger before the promise flow from the onRemoved event resolves.  So the onActivated handler retrieves the old stored array, with the closed tab still in it, and then pushes the newly activated tab.  So the stored tab data now includes a tab that's already been closed.

I'm assuming this is an issue with using promises instead of callbacks, but I'm wondering if anyone else has run into this problem with this library and worked around it.

Update

As wOxxOm points out, this is a generic problem with "arbitrating unpredictable asynchronous access to a single resource such as chrome.storage" and not unique to the chrome-promise library.

After researching a bit, I came up with a couple solutions, added as answers below.  One uses a mutex to ensure (I think) that one promise chain's getting and setting data in chrome.storage completes before the next one starts.  The other queues the whole promise chain that's created from an event and doesn't start the next one until the current one has fully completed.  I'm not sure which is better, though I suppose locking for a shorter period of time is better.

Any suggestions or better answers are welcome.


问:
Analytics SDK for tvOS
I'm about to ship an app for tvOS and I would like to include some basic analytics in it, but I couldn't find any SDK available for this platform.

I already integrated the beta version of Fabric but only the Crashlytics SDK is working on tvOS. Answers is not available.

I've been looking at Google Analytics, Flury, Mixpanel but so far, it doesn't seem like anyone has a working SDK. Does anybody have some suggestions?

Thanks!

UPDATE:
Fabric started a beta for Answers on tvOS. http://answers.io/blog/introducing-answers-for-os-x-and-tvos-beta

答: We could use 'Flurry-iOS-SDK/FlurryTVOS', '8.3.0' for tvOS Analytics.</p>

Title: Analytics SDK for tvOS


问:
Angular Material MatTableDataSource with Firestore
I currently have a data table that is being populated with data coming from Firestore. I also used MatTableDataSource to implement pagination, sorting, and filtering.  All 3 work fine but for some reason my data only loads once when the page is refreshed.  If I go to another page and then back to the table the data is gone.  I'm at a loss as to why this is happening. Below is my code.

Service

```<code>import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Account } from './../models/account.model';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AccountService {
  accountsCollection: AngularFirestoreCollection<Account>;
  accounts: Observable<Account[]>;

  constructor(public afs: AngularFirestore) {
    this.accountsCollection = afs.collection('accounts');

    this.accounts = this.accountsCollection.snapshotChanges().map(changes => {
      return changes.map(a => {
        const data = a.payload.doc.data() as Account;
        data.id = a.payload.doc.id;
        return data;
      });
    });

  }

  getAccounts() {
    return this.accounts;
  }

}
</code>```

Component

```<code>import { Account } from './../../../models/account.model';
import { Component, ViewChild, OnInit } from '@angular/core';
import { MatPaginator, MatSort, MatTableDataSource } from '@angular/material';
import { AccountService } from '../../../services/account.service';
import { AfterViewInit } from '@angular/core/src/metadata/lifecycle_hooks';

@Component({
  selector: 'app-account-table',
  templateUrl: './account-table.component.html',
  styleUrls: ['./account-table.component.css']
})
export class AccountTableComponent implements AfterViewInit {
  dataSource = new MatTableDataSource<Account>();
  displayedColumns = [
    'salesStep',
    'status',
    'idn',
    'hospital',
    'state',
    'regionalManager',
    'accountExecutive',
    'clientLiaison',
    'gpo'
  ];

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;

  constructor(private accountService: AccountService) {}

  ngAfterViewInit() {
    this.accountService.getAccounts().subscribe(data => {
      this.dataSource.data = data;
      console.log(this.dataSource.data);
    });
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

  applyFilter(filterValue: string) {
    filterValue = filterValue.trim(); // Remove whitespace
    filterValue = filterValue.toLowerCase(); // Datasource defaults to lowercase matches
    this.dataSource.filter = filterValue;
  }

}
</code>```

HTML

```<code><div class="example-header">
  <mat-form-field>
    <input matInput #filter (keyup)="applyFilter($event.target.value)" placeholder="Search">
  </mat-form-field>
</div>

<mat-card class="example-container">

  <mat-table #table [dataSource]="dataSource" matSort>

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

    <!-- Sales Step Column -->
    <ng-container matColumnDef="salesStep">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Sales Step </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.salesStep}} </mat-cell>
    </ng-container>

    <!-- Status Column -->
    <ng-container matColumnDef="status">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Status </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.status}} </mat-cell>
    </ng-container>

    <!-- IDN Column -->
    <ng-container matColumnDef="idn">
      <mat-header-cell *matHeaderCellDef mat-sort-header> IDN </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.idn}} </mat-cell>
    </ng-container>

    <!-- Hospital Column -->
    <ng-container matColumnDef="hospital">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Hospital </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.hospital}} </mat-cell>
    </ng-container>

    <!-- State Column -->
    <ng-container matColumnDef="state">
      <mat-header-cell *matHeaderCellDef mat-sort-header> State </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.state}} </mat-cell>
    </ng-container>

    <!-- Regional Manager Column -->
    <ng-container matColumnDef="regionalManager">
      <mat-header-cell *matHeaderCellDef mat-sort-header> RM </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.regionalManager}} </mat-cell>
    </ng-container>

    <!-- Account Executive Column -->
    <ng-container matColumnDef="accountExecutive">
      <mat-header-cell *matHeaderCellDef mat-sort-header> AE </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.accountExecutive}} </mat-cell>
    </ng-container>

    <!-- Client Liaison Column -->
    <ng-container matColumnDef="clientLiaison">
      <mat-header-cell *matHeaderCellDef mat-sort-header> CL </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.clientLiaison}} </mat-cell>
    </ng-container>

    <!-- GPO Column -->
    <ng-container matColumnDef="gpo">
      <mat-header-cell *matHeaderCellDef mat-sort-header> GPO </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.gpo}} </mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;">
    </mat-row>
  </mat-table>

  <!-- <div class="example-no-results"
       [style.display]="(accountService.accounts | async)?.length">
    No accounts found matching filter.
  </div> -->

  <mat-paginator #paginator
                [pageSize]="10"
                [pageSizeOptions]="[5, 10, 20]">
  </mat-paginator>
</mat-card>
</code>```

答:
This may work better for the getAccounts method:

```<code>  getAccountsX() {
    return this.afs.collection<Account[]>('accounts').snapshotChanges().map((accounts) => {
      return accounts.map(a => {
        const data = a.payload.doc.data() as Account;
        const id = a.payload.doc.id;
        return { id, ...data }
      });
    });
  }
</code>```

I have never tried making a firestore call in the constructor of the service but always make the database calls in a method that gets called during the ngOnInit in my component.

So in the component you could have a object accounts: Observable<Account[]> that is of type Observable<Account[]> and set it to equal getAccountsX(). Then in your markup I would *ngIf the entire table like this: *ngIf="(accounts | async) as acts". Then the dataSource would actually be acts. I have never used the DataTable yet but this is just an approach I would take to try and keep the subscription to the data active. If you want I can EDIT your question with this.

EDIT:

Here is an explanation of two separate ways to handle that subscription:

So here in my Component I am fetching the Observable and then also subscribing to it to save the array of whatever data model you are fetching:

```<code>  accountsObservable: Observable<Account[]>;
  accountsArray: Account[];

  constructor(
    private ds: DatabaseService
  ) {}

  ngOnInit() {
    this.accountsObservable = this.ds.getAccountsX();

    this.accountsObservable.subscribe(accounts => {
      this.accountsArray = accounts;
    });
  }
</code>```

Then here in my markup you can create the subscription using *ngFor and the ASYNC pipe, or simply loop through the array after it has been acknowledged by the subscription:

```<code><!-- This div below is subscribing to the Observable in markup using the 'async' pipe to make sure it waits for data -->
<div id="markup-subscription" *ngFor="let act of (accountsObservable | async)">
  <p>{{ act?.id }}</p>
</div>

<!-- This div below is looping through the array that was pulled from the subscription of the Observable -->
<div id="component-subscription" *ngFor="let act of accountsArray">
  <p>{{ act?.id }}</p>
</div>
</code>```

One reason for waiting for the subscription in the Component code is if there is a need to manipulate the data before spitting it out on the UI. I believe if you are using the second option of subscribing in the Component code instead of your markup you would want to make sure the *ngFor isn't trying to loop through an empty Array as the subscription may not have set the array before the content wants to load on the DOM. So I would *ngIf the accountsArray to make sure it is set first like so:

```<code><div id="component-subscription" *ngIf="accountsArray" *ngFor="let act of accountsArray">
</code>```

Granted this is not using the MatDataTable as I wanted to show an example of how these subscriptions work and the goal is to use one subscription

In regards to unsubscribing, the reason that is not an option is because you must set the Observable subscription to a variable like so:

```<code>    const subscription = this.accountsObservable.subscribe(accounts => {
      this.accountsArray = accounts;
    });

    subscription.unsubscribe();
</code>```

I hope this can help explain the state of the subscription as you are looping through the collection or document in the UI.

Body:
I currently have a data table that is being populated with data coming from Firestore. I also used MatTableDataSource to implement pagination, sorting, and filtering.  All 3 work fine but for some reason my data only loads once when the page is refreshed.  If I go to another page and then back to the table the data is gone.  I'm at a loss as to why this is happening. Below is my code.

Service

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Account } from './../models/account.model';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AccountService {
  accountsCollection: AngularFirestoreCollection<Account>;
  accounts: Observable<Account[]>;

  constructor(public afs: AngularFirestore) {
    this.accountsCollection = afs.collection('accounts');

    this.accounts = this.accountsCollection.snapshotChanges().map(changes => {
      return changes.map(a => {
        const data = a.payload.doc.data() as Account;
        data.id = a.payload.doc.id;
        return data;
      });
    });

  }

  getAccounts() {
    return this.accounts;
  }

}

Component

import { Account } from './../../../models/account.model';
import { Component, ViewChild, OnInit } from '@angular/core';
import { MatPaginator, MatSort, MatTableDataSource } from '@angular/material';
import { AccountService } from '../../../services/account.service';
import { AfterViewInit } from '@angular/core/src/metadata/lifecycle_hooks';

@Component({
  selector: 'app-account-table',
  templateUrl: './account-table.component.html',
  styleUrls: ['./account-table.component.css']
})
export class AccountTableComponent implements AfterViewInit {
  dataSource = new MatTableDataSource<Account>();
  displayedColumns = [
    'salesStep',
    'status',
    'idn',
    'hospital',
    'state',
    'regionalManager',
    'accountExecutive',
    'clientLiaison',
    'gpo'
  ];

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;

  constructor(private accountService: AccountService) {}

  ngAfterViewInit() {
    this.accountService.getAccounts().subscribe(data => {
      this.dataSource.data = data;
      console.log(this.dataSource.data);
    });
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

  applyFilter(filterValue: string) {
    filterValue = filterValue.trim(); // Remove whitespace
    filterValue = filterValue.toLowerCase(); // Datasource defaults to lowercase matches
    this.dataSource.filter = filterValue;
  }

}

HTML

  <mat-form-field>
    <input matInput #filter (keyup)="applyFilter($event.target.value)" placeholder="Search">
  </mat-form-field>

<mat-card class="example-container">

  <mat-table #table [dataSource]="dataSource" matSort>

    <ng-container matColumnDef="salesStep">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Sales Step </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.salesStep}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="status">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Status </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.status}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="idn">
      <mat-header-cell *matHeaderCellDef mat-sort-header> IDN </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.idn}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="hospital">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Hospital </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.hospital}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="state">
      <mat-header-cell *matHeaderCellDef mat-sort-header> State </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.state}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="regionalManager">
      <mat-header-cell *matHeaderCellDef mat-sort-header> RM </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.regionalManager}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="accountExecutive">
      <mat-header-cell *matHeaderCellDef mat-sort-header> AE </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.accountExecutive}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="clientLiaison">
      <mat-header-cell *matHeaderCellDef mat-sort-header> CL </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.clientLiaison}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="gpo">
      <mat-header-cell *matHeaderCellDef mat-sort-header> GPO </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.gpo}} </mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;">
    </mat-row>
  </mat-table>

  <mat-paginator #paginator
                [pageSize]="10"
                [pageSizeOptions]="[5, 10, 20]">
  </mat-paginator>
</mat-card>

Body:
This may work better for the getAccounts method:

  getAccountsX() {
    return this.afs.collection<Account[]>('accounts').snapshotChanges().map((accounts) => {
      return accounts.map(a => {
        const data = a.payload.doc.data() as Account;
        const id = a.payload.doc.id;
        return { id, ...data }
      });
    });
  }

I have never tried making a firestore call in the constructor of the service but always make the database calls in a method that gets called during the ngOnInit in my component.

So in the component you could have a object accounts: Observable<Account[]> that is of type Observable<Account[]> and set it to equal getAccountsX(). Then in your markup I would *ngIf the entire table like this: *ngIf="(accounts | async) as acts". Then the dataSource would actually be acts. I have never used the DataTable yet but this is just an approach I would take to try and keep the subscription to the data active. If you want I can EDIT your question with this.

EDIT:

Here is an explanation of two separate ways to handle that subscription:

So here in my Component I am fetching the Observable and then also subscribing to it to save the array of whatever data model you are fetching:

  accountsObservable: Observable<Account[]>;
  accountsArray: Account[];

  constructor(
    private ds: DatabaseService
  ) {}

  ngOnInit() {
    this.accountsObservable = this.ds.getAccountsX();

    this.accountsObservable.subscribe(accounts => {
      this.accountsArray = accounts;
    });
  }

Then here in my markup you can create the subscription using *ngFor and the ASYNC pipe, or simply loop through the array after it has been acknowledged by the subscription:

<!-- This div below is subscribing to the Observable in markup using the 'async' pipe to make sure it waits for data -->
<div id="markup-subscription" *ngFor="let act of (accountsObservable | async)">
  <p>{{ act?.id }}</p>
</div>

<!-- This div below is looping through the array that was pulled from the subscription of the Observable -->
<div id="component-subscription" *ngFor="let act of accountsArray">
  <p>{{ act?.id }}</p>
</div>

One reason for waiting for the subscription in the Component code is if there is a need to manipulate the data before spitting it out on the UI. I believe if you are using the second option of subscribing in the Component code instead of your markup you would want to make sure the *ngFor isn't trying to loop through an empty Array as the subscription may not have set the array before the content wants to load on the DOM. So I would *ngIf the accountsArray to make sure it is set first like so:

<div id="component-subscription" *ngIf="accountsArray" *ngFor="let act of accountsArray">

Granted this is not using the MatDataTable as I wanted to show an example of how these subscriptions work and the goal is to use one subscription

In regards to unsubscribing, the reason that is not an option is because you must set the Observable subscription to a variable like so:

    const subscription = this.accountsObservable.subscribe(accounts => {
      this.accountsArray = accounts;
    });

    subscription.unsubscribe();

I hope this can help explain the state of the subscription as you are looping through the collection or document in the UI.


问:
NSNumber for MPMediaItemPropertyPersistentID to NSString and back again
I'm looping through all the songs from an iPhone's music library using the following code:

```<code>NSArray * songs = [[NSArray alloc] initWithArray:[[MPMediaQuery songsQuery] collections]];

for (MPMediaItemCollection * item in songs){

    NSString * persistentID = [[[item representativeItem] valueForProperty:MPMediaItemPropertyPersistentID] stringValue];
    // Do something with it.
}

[songs release];
</code>```

Pretty basic stuff.

I'm getting the PersistentID as an NSString because I need to write it to an XML file (for transmission over a network to another device). Hence the reason I can't just leave it as an NSNumber.

The other device will then ask for the iPhone to play a track by transmitting the PersistentID back again.

At this point, the iPhone has an NSString of the PersistentID of the track it should play.

It would be combersome to loop through every song again and compare PersistentIDs until I find the track I want, so I'm trying to use the MPMediaPropertyPredicate to have the iPhone search for me.

I'm using the following code for the search:

```<code>MPMediaPropertyPredicate * predicate = [MPMediaPropertyPredicate predicateWithValue:persistentID forProperty:MPMediaItemPropertyPersistentID];

MPMediaQuery * songsQuery = [[MPMediaQuery alloc] init];
[songsQuery addFilterPredicate:predicate];

if ([[songsQuery items] count]){

    MPMediaItem * item = [[songsQuery items] objectAtIndex:0];
    // Play item.
}

[songsQuery release];
</code>```

Where persistentID is the NSString from earlier.

Weirdly, this works for some songs, not for others. i.e, sometimes the items array is not empty, even though I'm passing an NSString, not an NSNumber.

I'm wondering if there's a way to convert my NSString back to the NSNumber it came from, and how I can do that.

UPDATE: I've tried the NSNumberFormatter, I've also tried something like:

```<code>[NSNumber numberWithFloat:[persID floatValue]];
</code>```

I've tried all the standard ways of doing it without prevail.

答:
If I understand you correctly, you're trying to convert an NSString to an NSNumber. To do this, you can use a NSNumberFormatter. Take a look at the numberFromString: method.

NSNumberFormatter Class Reference

Body:
I'm looping through all the songs from an iPhone's music library using the following code:

NSArray * songs = [[NSArray alloc] initWithArray:[[MPMediaQuery songsQuery] collections]];

for (MPMediaItemCollection * item in songs){

    NSString * persistentID = [[[item representativeItem] valueForProperty:MPMediaItemPropertyPersistentID] stringValue];
    // Do something with it.
}

[songs release];

Pretty basic stuff.

I'm getting the PersistentID as an NSString because I need to write it to an XML file (for transmission over a network to another device). Hence the reason I can't just leave it as an NSNumber.

The other device will then ask for the iPhone to play a track by transmitting the PersistentID back again.

At this point, the iPhone has an NSString of the PersistentID of the track it should play.

It would be combersome to loop through every song again and compare PersistentIDs until I find the track I want, so I'm trying to use the MPMediaPropertyPredicate to have the iPhone search for me.

I'm using the following code for the search:

MPMediaPropertyPredicate * predicate = [MPMediaPropertyPredicate predicateWithValue:persistentID forProperty:MPMediaItemPropertyPersistentID];

MPMediaQuery * songsQuery = [[MPMediaQuery alloc] init];
[songsQuery addFilterPredicate:predicate];

if ([[songsQuery items] count]){

    MPMediaItem * item = [[songsQuery items] objectAtIndex:0];
    // Play item.
}

[songsQuery release];

Where persistentID is the NSString from earlier.

Weirdly, this works for some songs, not for others. i.e, sometimes the items array is not empty, even though I'm passing an NSString, not an NSNumber.

I'm wondering if there's a way to convert my NSString back to the NSNumber it came from, and how I can do that.

UPDATE: I've tried the NSNumberFormatter, I've also tried something like:

[NSNumber numberWithFloat:[persID floatValue]];

I've tried all the standard ways of doing it without prevail.


问:
Pandas- create rows that show the sum of all items by date minus the specific item (creating ex-item rows for each item)
So I have panel data that shows metrics for each item over a course of time

```<code>date    item    value
1/1/2017    a   1
1/1/2017    b   2
1/1/2017    c   4
1/2/2017    a   6
1/2/2017    b   4
1/2/2017    c   3
1/3/2017    a   6
1/3/2017    b   4
1/3/2017    c   3
1/4/2017    a   2
1/4/2017    b   3
1/4/2017    c   4
</code>```

And what I want to do is create rows for each item for each date that takes the sum of all values for that date, subtracts it by the item, then divides by total number of items. Would look something like:

```<code>date    item    value
1/1/2017    a   1
1/1/2017    b   2
1/1/2017    c   4
1/1/2017    ex-a    2.5
1/1/2017    ex-b    1.5
1/1/2017    ex-c    0.25
1/2/2017    a   6
1/2/2017    b   4
1/2/2017    c   3
1/2/2017    ex-a    0.5
1/2/2017    ex-b    2.5
1/2/2017    ex-c    4.75
</code>```

how would I go about doing this? I'm assuming I'd have to group by date and create a variable that gets the sum of all values for each date, and then loop through each item. Appreciate the help

答:
Assuming you have the ability to change the shape of your data to something like:

```<code>           a   b   c
    date
1/1/2017   1   2   4
1/2/2017   6   4   3
</code>```

then we can iterate through each row, calculate the values, then add them.

```<code>df = pd.DataFrame({'date': ['1/1/2017', '1/2/2017'],
                   'a': [1, 6],
                   'b': [2, 4],
                   'c': [4, 3]})
df.set_index('date', inplace=True)

cols = df.columns.values
num_cols = len(cols)

for col in cols:
    df[f'ex-{col}'] = 0

i = 0
for date, row in df.iterrows():
    row_sum = row.values.sum()
    for col in cols:
        df[f'ex-{col}'].iloc[i] = (row_sum - row[col]) / num_cols

    i += 1

print(df)
</code>```

outputs:

```<code>          a  b  c      ex-a      ex-b      ex-c
date
1/1/2017  1  2  4  2.000000  1.666667  1.000000
1/2/2017  6  4  3  2.333333  3.000000  3.333333
</code>```

Body:
So I have panel data that shows metrics for each item over a course of time

date    item    value
1/1/2017    a   1
1/1/2017    b   2
1/1/2017    c   4
1/2/2017    a   6
1/2/2017    b   4
1/2/2017    c   3
1/3/2017    a   6
1/3/2017    b   4
1/3/2017    c   3
1/4/2017    a   2
1/4/2017    b   3
1/4/2017    c   4

And what I want to do is create rows for each item for each date that takes the sum of all values for that date, subtracts it by the item, then divides by total number of items. Would look something like:

date    item    value
1/1/2017    a   1
1/1/2017    b   2
1/1/2017    c   4
1/1/2017    ex-a    2.5
1/1/2017    ex-b    1.5
1/1/2017    ex-c    0.25
1/2/2017    a   6
1/2/2017    b   4
1/2/2017    c   3
1/2/2017    ex-a    0.5
1/2/2017    ex-b    2.5
1/2/2017    ex-c    4.75

how would I go about doing this? I'm assuming I'd have to group by date and create a variable that gets the sum of all values for each date, and then loop through each item. Appreciate the help

Body:
Assuming you have the ability to change the shape of your data to something like:

           a   b   c
    date
1/1/2017   1   2   4
1/2/2017   6   4   3

then we can iterate through each row, calculate the values, then add them.

df = pd.DataFrame({'date': ['1/1/2017', '1/2/2017'],
                   'a': [1, 6],
                   'b': [2, 4],
                   'c': [4, 3]})
df.set_index('date', inplace=True)

cols = df.columns.values
num_cols = len(cols)

for col in cols:
    df[f'ex-{col}'] = 0

i = 0
for date, row in df.iterrows():
    row_sum = row.values.sum()
    for col in cols:
        df[f'ex-{col}'].iloc[i] = (row_sum - row[col]) / num_cols

    i += 1

print(df)

outputs:

          a  b  c      ex-a      ex-b      ex-c
date
1/1/2017  1  2  4  2.000000  1.666667  1.000000
1/2/2017  6  4  3  2.333333  3.000000  3.333333


问:
Cannot get text form element
I cannot get text from the element in Selenium. I try to use the following code but get nothing. Xpath helper shows that only one such element.

Code I use:

```<code>protected const string ERROR_FORM = "//p[contains(@data-bind, 'invalid')]";

[FindsBy(How = How.XPath, Using = ERROR_FORM)]
 protected IWebElement ErrorForm { get; set; }

public string GetErrorText() {return ErrorForm.Text;}
</code>```

Html code:

```<code><p class="g-textfield__error" data-bind="if: tokenError() === 'invalid'">Invalid
code. Check the code you have entered and try again.</p>
<p class="g-textfield__error" data-bind="if: tokenError() === 'expired'"></p>
</code>```

The problem is found in the previous code. The code was:

```<code>public string GetErrorText()
    {
        CustomTestContext.WriteLine("Получить сообщение об ошибке.");

        if (!IsInvalidCodeErrorMessageAppeared())
        {
            throw new XPathLookupException("Произошла ошибка:\n не появилось сообщение об ошибке.");
        }

        return ErrorForm.Text;
    }

    public bool IsInvalidCodeErrorMessageAppeared()
    {
        CustomTestContext.WriteLine("Проверяем появилось ли сообщение об ошибке");
        return Driver.WaitUntilElementIsAppear(By.XPath(ERROR_FORM));
    }
</code>```

It appeared that I checked the element before it displayed. As soon as I changed Driver.WaitUntilElementIsAppear for Driver.WaitUntilElementIsDisplay the text was found correctly.
So the thing is that you could not help me as you did not see the full code. Sorry for that, my mistake, I'm too green. Next time I will provide the full code or a link to git rep. I'm greatfull to all of you for trying to help.

答:
Viktor - Here is what mine would look like.... </p>

```<code>    [FindsBy(How = How.XPath, Using = "//p[contains(@data-bind, 'invalid')]")]
    private readonly IWebElement _errorMsgAlert = null;

    public string GetAlertError()
    {
        string errmsg= MyFunctions.GetElementText(_errorMsgAlert);
        return errmsg;
    }

    public static string GetElementText(IWebElement element)
    {
        var text = "";
        while (true)
        {
            try { text = element.Text; }
            catch (StaleElementReferenceException) { }
            return text;
        }
    }
</code>```

Title: Cannot get text form element

Body:
I cannot get text from the element in Selenium. I try to use the following code but get nothing. Xpath helper shows that only one such element.

Code I use:

protected const string ERROR_FORM = "//p[contains(@data-bind, 'invalid')]";

[FindsBy(How = How.XPath, Using = ERROR_FORM)]
 protected IWebElement ErrorForm { get; set; }

public string GetErrorText() {return ErrorForm.Text;}

Html code:

Invalid
code. Check the code you have entered and try again.

The problem is found in the previous code. The code was:

public string GetErrorText()
    {
        CustomTestContext.WriteLine("Получить сообщение об ошибке.");

        if (!IsInvalidCodeErrorMessageAppeared())
        {
            throw new XPathLookupException("Произошла ошибка:\n не появилось сообщение об ошибке.");
        }

        return ErrorForm.Text;
    }

    public bool IsInvalidCodeErrorMessageAppeared()
    {
        CustomTestContext.WriteLine("Проверяем появилось ли сообщение об ошибке");
        return Driver.WaitUntilElementIsAppear(By.XPath(ERROR_FORM));
    }

It appeared that I checked the element before it displayed. As soon as I changed Driver.WaitUntilElementIsAppear for Driver.WaitUntilElementIsDisplay the text was found correctly.
So the thing is that you could not help me as you did not see the full code. Sorry for that, my mistake, I'm too green. Next time I will provide the full code or a link to git rep. I'm greatfull to all of you for trying to help.

Body:
Viktor - Here is what mine would look like....

    [FindsBy(How = How.XPath, Using = "//p[contains(@data-bind, 'invalid')]")]
    private readonly IWebElement _errorMsgAlert = null;

    public string GetAlertError()
    {
        string errmsg= MyFunctions.GetElementText(_errorMsgAlert);
        return errmsg;
    }

    public static string GetElementText(IWebElement element)
    {
        var text = "";
        while (true)
        {
            try { text = element.Text; }
            catch (StaleElementReferenceException) { }
            return text;
        }
    }


问:
How can I set the minSdk just for androidTest?
I'd like to increase the minSdk to 21 just for androidTest. Is this possible without introducing a product flavor?

Note: Using Android Gradle Plugin 3.0, and my app's minSdk needs to be 16.

答:
You can try as this post suggests creating a new Manifest in the folder where you run your test adding the attribute

uses-sdk

as per documentation

Also is indicated to play in gradle with some if statements in the gradle file, but they are ugly. Anyway you could use it as a plan B solution:

```<code>if (gradle.startParameter.taskNames.contains(":app:assembleDebug")) {
        minSdkVersion 21
    }else{
        minSdkVersion 14
    }
</code>```

Body:
You can try as this post suggests creating a new Manifest in the folder where you run your test adding the attribute

uses-sdk

as per documentation

Also is indicated to play in gradle with some if statements in the gradle file, but they are ugly. Anyway you could use it as a plan B solution:

if (gradle.startParameter.taskNames.contains(":app:assembleDebug")) {
        minSdkVersion 21
    }else{
        minSdkVersion 14
    }


问:
Android E/ExtMediaPlayer-JNI: env->IsInstanceOf fails E/MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
I am trying to play video song in my app with video-view. But I get nothing except a black screen, and display error 'can't play video'.It seems there are no errors as such in the code except log cat errors which I have never heard of.</p>

```<code>VideoView videoView =(VideoView)findViewById(R.id.video_view_ex);

    MediaController mediaController= new MediaController(this);
    mediaController.setAnchorView(videoView);

    Uri uri= Uri.parse(Environment.getExternalStorageDirectory().getPath()+"/Memory Card/Video/Na Na Na Na -DJ 9dip.mp4");
    videoView.setMediaController(mediaController);
    videoView.setVideoURI(uri);
    videoView.requestFocus();
    videoView.start();
</code>```

答:
I guess it was because
"/Memory Card/Video/Na Na Na Na -DJ 9dip.mp4"

Is already the path and, as you add Environment.getExternalStorageDirectory().getPath()

It creates a non-valid Uri, because the error you mention is reffered to a inexistent resource. Try leaving it instead:

Uri uri= Uri.parse("/Memory Card/Video/Na Na Na Na -DJ 9dip.mp4");

Body:
I am trying to play video song in my app with video-view. But I get nothing except a black screen, and display error 'can't play video'.It seems there are no errors as such in the code except log cat errors which I have never heard of.

VideoView videoView =(VideoView)findViewById(R.id.video_view_ex);

    MediaController mediaController= new MediaController(this);
    mediaController.setAnchorView(videoView);

    Uri uri= Uri.parse(Environment.getExternalStorageDirectory().getPath()+"/Memory Card/Video/Na Na Na Na -DJ 9dip.mp4");
    videoView.setMediaController(mediaController);
    videoView.setVideoURI(uri);
    videoView.requestFocus();
    videoView.start();


问:
Linking Error - No Write Permission
I have a problem with a project I am working on in Android Studio. The goal is to save a basic string into a .csv file then attach that file as an email attachment.

I cant write to the file, but I can share the file via FileProvider.getUriForFile.

I think the problem has something to do with these two linker error messages I get, the streamsavvy-1 is concerning bc my package name is com.team6.rifflegroup.streamsavvy

```<code>11-13 16:20:39.775 10286-10286/com.team6.rifflegroup.streamsavvy E/linker: readlink('') failed: No such file or directory [fd=31]
</code>```

11-13 16:20:39.775 10286-10286/com.team6.rifflegroup.streamsavvy E/linker: warning: unable to get realpath for the library "/data/app/com.team6.rifflegroup.streamsavvy-1/oat/arm64/base.odex". Will use given name.

I build the file like this

```<code>File dataPath = new File(this.getFilesDir(), "xml");
File newData = new File(dataPath, FILE_NAME);
</code>```

I have a paths.xml file within an xml directory under res that looks like this

```<code><?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="my_files"
        path="/"/>
</paths>
</code>```

my write function looks like this

```<code>try {
        FileWriter writer = new FileWriter(newData);
        writer.append(csv);
        writer.flush();
        writer.close();
        Toast.makeText(this, "SAVED", Toast.LENGTH_SHORT).show();

    }catch (IOException e){
        e.printStackTrace();
    }
</code>```

My Email intent looks like this

```<code>Uri contentUri = FileProvider.getUriForFile(this, "com.team6.rifflegroup.streamsavvy.FileProvider", newData);

    this.grantUriPermission(getPackageName(), contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

    Intent emailIntent = new Intent(Intent.ACTION_SEND);
    emailIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    emailIntent.setType("vnd.android.cursor.dir/email");
    emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"myEmail@gmail.com"});
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
    emailIntent.putExtra(Intent.EXTRA_TEXT, "File Attached");
    emailIntent.putExtra(Intent.EXTRA_STREAM, contentUri);

    startActivity(Intent.createChooser(emailIntent, "Send email..."));
</code>```

I give permission in my manifest here

```<code><?xml version="1.0" encoding="utf-8"?>
</code>```

```<code><uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".dataLayout">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.team6.rifflegroup.streamsavvy.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/paths"/>
    </provider>
</application>
</code>```

I feel like this is a problem with the way java builds its projects but I am not very familiar with the process. Any help or pointers would be greatly appreciated.

This is my first time posting here so I am so sorry if my post is out of context or improperly formatted.

答:
Apologize for the long post. Figured it out.

had to declare the .mkdirs() call (not .mkdir()) after specifying the file.

Title: Linking Error - No Write Permission

Body:
I have a problem with a project I am working on in Android Studio. The goal is to save a basic string into a .csv file then attach that file as an email attachment.

I cant write to the file, but I can share the file via FileProvider.getUriForFile.

I think the problem has something to do with these two linker error messages I get, the streamsavvy-1 is concerning bc my package name is com.team6.rifflegroup.streamsavvy

11-13 16:20:39.775 10286-10286/com.team6.rifflegroup.streamsavvy E/linker: readlink('') failed: No such file or directory [fd=31]

11-13 16:20:39.775 10286-10286/com.team6.rifflegroup.streamsavvy E/linker: warning: unable to get realpath for the library "/data/app/com.team6.rifflegroup.streamsavvy-1/oat/arm64/base.odex". Will use given name.

I build the file like this

File dataPath = new File(this.getFilesDir(), "xml");
File newData = new File(dataPath, FILE_NAME);

I have a paths.xml file within an xml directory under res that looks like this

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="my_files"
        path="/"/>
</paths>

my write function looks like this

try {
        FileWriter writer = new FileWriter(newData);
        writer.append(csv);
        writer.flush();
        writer.close();
        Toast.makeText(this, "SAVED", Toast.LENGTH_SHORT).show();

    }catch (IOException e){
        e.printStackTrace();
    }

My Email intent looks like this

Uri contentUri = FileProvider.getUriForFile(this, "com.team6.rifflegroup.streamsavvy.FileProvider", newData);

    this.grantUriPermission(getPackageName(), contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

    Intent emailIntent = new Intent(Intent.ACTION_SEND);
    emailIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    emailIntent.setType("vnd.android.cursor.dir/email");
    emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"myEmail@gmail.com"});
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
    emailIntent.putExtra(Intent.EXTRA_TEXT, "File Attached");
    emailIntent.putExtra(Intent.EXTRA_STREAM, contentUri);

    startActivity(Intent.createChooser(emailIntent, "Send email..."));

I give permission in my manifest here

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".dataLayout">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.team6.rifflegroup.streamsavvy.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/paths"/>
    </provider>
</application>

I feel like this is a problem with the way java builds its projects but I am not very familiar with the process. Any help or pointers would be greatly appreciated.

This is my first time posting here so I am so sorry if my post is out of context or improperly formatted.


问:
Entity manager get or create
How can I make sure if the object already exist its not created again.

```<code>@Component
public class ProductServiceImpl implements ProductService
{
    @PersistenceContext
    private EntityManager em;

    public Product getOrCreateProduct(String productName, String peoductDescr)
    {
        Product product =(new Product (productName, peoductDescr));
        em.merge(product);
        return product;
    }
}
</code>```

I did this way but as it is still keep creating new db entries instead of returning the new one.

答:
Since your approach should work if the product name, the product description, or the two together were the primary key for Product entities, I conclude that the PK is something else -- probably a surrogate key, since that's what JPA is tooled to use by default.  If you want to use the product name to decide whether to create a new persistent entity or use an existing one then you need to perform a search on the product name.  Something like this, for example:

```<code>    public Product getOrCreateProduct(String productName, String productDescr) {
        Product product;

        try {
            TypedQuery<Product> productForName = em.createQuery(
                    "select p from Product p where p.name = ?1", Product.class);
            EntityTransaction transaction;

            productForName.setParameter(1, productName);

            /*
             * The query and any persist() operation required should be
             * performed in the same transaction.  You might, however, want
             * to be a little more accommodating than this of any transaction
             * that is already in progress.
             */
            transaction = em.getTransaction();
            transaction.begin();
            try {
                product = productForName.getSingleResult();
            } catch (NoResultException nre) {
                product = new Product(productName, productDescr);
                em.persist(product);
            }
            transaction.commit();
        } catch (PersistenceException pe) {
            // ... handle error ...
        }

        return product;
    }
</code>```

Note well that that particular implementation returns a "managed" entity if it returns one at all.  This may or may not be what you want.  If you want a detached one instead, then you can certainly detach it manually before returning (but in that case, don't forget to flush it first if it is new).

You might also want to support this by setting a uniqueness constraint on the product name.

Title: Entity manager get or create

Body:
How can I make sure if the object already exist its not created again.

@Component
public class ProductServiceImpl implements ProductService
{
    @PersistenceContext
    private EntityManager em;

    public Product getOrCreateProduct(String productName, String peoductDescr)
    {
        Product product =(new Product (productName, peoductDescr));
        em.merge(product);
        return product;
    }
}

I did this way but as it is still keep creating new db entries instead of returning the new one.

Body:
Since your approach should work if the product name, the product description, or the two together were the primary key for Product entities, I conclude that the PK is something else -- probably a surrogate key, since that's what JPA is tooled to use by default.  If you want to use the product name to decide whether to create a new persistent entity or use an existing one then you need to perform a search on the product name.  Something like this, for example:

    public Product getOrCreateProduct(String productName, String productDescr) {
        Product product;

        try {
            TypedQuery<Product> productForName = em.createQuery(
                    "select p from Product p where p.name = ?1", Product.class);
            EntityTransaction transaction;

            productForName.setParameter(1, productName);

            /*
             * The query and any persist() operation required should be
             * performed in the same transaction.  You might, however, want
             * to be a little more accommodating than this of any transaction
             * that is already in progress.
             */
            transaction = em.getTransaction();
            transaction.begin();
            try {
                product = productForName.getSingleResult();
            } catch (NoResultException nre) {
                product = new Product(productName, productDescr);
                em.persist(product);
            }
            transaction.commit();
        } catch (PersistenceException pe) {
            // ... handle error ...
        }

        return product;
    }

Note well that that particular implementation returns a "managed" entity if it returns one at all.  This may or may not be what you want.  If you want a detached one instead, then you can certainly detach it manually before returning (but in that case, don't forget to flush it first if it is new).

You might also want to support this by setting a uniqueness constraint on the product name.


问:
Array printing results from data
I'm having trouble thinking of a JS function for the following idea. I want to have an array with 5 names. I also want to have a input box with a submit button. When I enter a number (1-5) I want to have it print the name that is assigned with that number from the array. Any ideas?

I have the button/input box setup but I'm not sure how the code would work.

答:
Are you looking for something like this? JSFiddle attached https://jsfiddle.net/kgLnc6nd/

HTML

```<code><input id='i1'/><br>
<button onclick='javascript:show()'>Click</button><br>
<div id='d1'></div>
</code>```

JAVASCRIPT

```<code>var names = ['michael','henry','james','rebecca','allison'];
function show() {
  var x = i1.value;
    d1.innerHTML = names[x];
}
</code>```

Title: Array printing results from data

Body:
Are you looking for something like this? JSFiddle attached https://jsfiddle.net/kgLnc6nd/

HTML

<input id='i1'/><br>
<button onclick='javascript:show()'>Click</button><br>
<div id='d1'></div>

JAVASCRIPT

var names = ['michael','henry','james','rebecca','allison'];
function show() {
  var x = i1.value;
    d1.innerHTML = names[x];
}


问:
On deploy I am hitting the 10k file limit, is there a way I can I test if files are being excluded?
I am hitting the 10k limit. I am trying to exclude files and folders from being uploaded and but It seems like they are not being excluded. I am testing by just trying to deploy a new version to app engine.

Is there a way to test the deploy without actually deploying to app engine?

(I am using java app engine standard (not maven))

Thanks

答: One usual culprit here is using git, and accidentally uploading the contents .git. If you are using git, adding .git to the skip_files: section in your app.yaml (or as in exlusion an the <resource-files> section of your appengine-web.xml) should cure the problem.


问:
removing duplicate log records
SO I have a query that searches my items table and returns all records with a prodstat <> NULL and it does some summed inventory fields.

I have tied this query to another table which is an audit log table and it returns the new prodstat, old prodstat, who changed it, and what date.

The problem is it is bringing in extra records if there have been multiple changes to the field.  I am trying to use max on the createdate of the log record to pull only the newest record.  Problem is when I add it to my other query, I only get the records which have been changed in the log file.

What I am looking for is all the item records with prodstat <> Null and the fields createdate,newvalue,oldvalue updated from the log table.

The data output should look like this

```<code>prodstat  item.num  item.desc  onhandinv  newprodstat   oldprodstat  changeddate
</code>```

This is what I have so far:

```<code>    Select
      item.Uf_ProdStat,
      item.item,
      item.description,
      a.UpdatedBy,
      (Select SUM(itemloc.qty_on_hand)
         from itemloc
           where itemloc.item = item.item and itemloc.loc = 'Main')as qty_onhand,
      a.createDate,
      a.OldValue,
      a.NewValue
    From item
      left join AuditLog a on item.item = a.KeyValue and MessageType = 10010
      inner join (select max(createdate)as maxdate, keyvalue
                from AuditLog
            where MessageType = 10010 and NewValue in
            ('EOL','DISC','WHL','NNO')
            group by KeyValue)
            tm on A.KeyValue = tm.KeyValue and A.CreateDate = tm.maxdate
    Where   Uf_ProdStat is Not Null
</code>```

This is returning only the 3 records, that match the changed records in the log file.  I should have 100, the log file part is just being add now.

答:
So I kept working on the inner joins and this one seems to give me everything I need...</p>

```<code>    From item
          --left join AuditLog a on item.item = a.KeyValue and MessageType = 10010
          left join (select a.messagetype,a.UserName as updatedby,a.CreateDate as recorddate,a.OldValue,a.keyvalue, a.NewValue
                    from AuditLog A
                        right join ( select max(createdate)as maxdate, keyvalue
                                        from AuditLog
                                        where MessageType = 10010 and NewValue in('EOL','NNO','DISC','WSL')
                                        group by KeyValue)
                    tm on A.KeyValue = tm.KeyValue and A.CreateDate = tm.maxdate) AL on AL.keyvalue = item.item
</code>```

Title: removing duplicate log records

Body:
SO I have a query that searches my items table and returns all records with a prodstat <> NULL and it does some summed inventory fields.

I have tied this query to another table which is an audit log table and it returns the new prodstat, old prodstat, who changed it, and what date.

The problem is it is bringing in extra records if there have been multiple changes to the field.  I am trying to use max on the createdate of the log record to pull only the newest record.  Problem is when I add it to my other query, I only get the records which have been changed in the log file.

What I am looking for is all the item records with prodstat <> Null and the fields createdate,newvalue,oldvalue updated from the log table.

The data output should look like this

prodstat  item.num  item.desc  onhandinv  newprodstat   oldprodstat  changeddate

This is what I have so far:

    Select
      item.Uf_ProdStat,
      item.item,
      item.description,
      a.UpdatedBy,
      (Select SUM(itemloc.qty_on_hand)
         from itemloc
           where itemloc.item = item.item and itemloc.loc = 'Main')as qty_onhand,
      a.createDate,
      a.OldValue,
      a.NewValue
    From item
      left join AuditLog a on item.item = a.KeyValue and MessageType = 10010
      inner join (select max(createdate)as maxdate, keyvalue
                from AuditLog
            where MessageType = 10010 and NewValue in
            ('EOL','DISC','WHL','NNO')
            group by KeyValue)
            tm on A.KeyValue = tm.KeyValue and A.CreateDate = tm.maxdate
    Where   Uf_ProdStat is Not Null

This is returning only the 3 records, that match the changed records in the log file.  I should have 100, the log file part is just being add now.

Body:
So I kept working on the inner joins and this one seems to give me everything I need...

    From item
          --left join AuditLog a on item.item = a.KeyValue and MessageType = 10010
          left join (select a.messagetype,a.UserName as updatedby,a.CreateDate as recorddate,a.OldValue,a.keyvalue, a.NewValue
                    from AuditLog A
                        right join ( select max(createdate)as maxdate, keyvalue
                                        from AuditLog
                                        where MessageType = 10010 and NewValue in('EOL','NNO','DISC','WSL')
                                        group by KeyValue)
                    tm on A.KeyValue = tm.KeyValue and A.CreateDate = tm.maxdate) AL on AL.keyvalue = item.item


问:
Save Elements of Mean() into two lists
When entered

```<code>mean(views ~ Month, data=dataset)
</code>```

results

[

How do I save Months into one list, and values into another? Eventually I will do a regressional analysis

答:
I believe the mean function OP's referring to comes from the mosaic package. If that is the case, there is a .format="table" argument to output the mean per group into a well-formatted data.frame:

```<code>library(mosaic)

mean(cyl ~ gear, data = mtcars, .format = "table")
</code>```

Result:

```<code>  gear     mean
1    3 7.466667
2    4 4.666667
3    5        6
</code>```

From ?mean (after loading mosaic):

wrap in data.frame() to auto-convert awkward variable names

So in OP's case, the safest would be to write:

```<code>means_E_T = data.frame(mean(U_E ~ E_T, data = etr, .format = "table"))
</code>```

Title: Save Elements of Mean() into two lists

Body:
When entered

mean(views ~ Month, data=dataset)

results

[

How do I save Months into one list, and values into another? Eventually I will do a regressional analysis

Body:
I believe the mean function OP's referring to comes from the mosaic package. If that is the case, there is a .format="table" argument to output the mean per group into a well-formatted data.frame:

library(mosaic)

mean(cyl ~ gear, data = mtcars, .format = "table")

Result:

  gear     mean
1    3 7.466667
2    4 4.666667
3    5        6

From ?mean (after loading mosaic):

wrap in data.frame() to auto-convert awkward variable names

So in OP's case, the safest would be to write:

means_E_T = data.frame(mean(U_E ~ E_T, data = etr, .format = "table"))


问:
Sum of specific values grouped by other values inside an array
I have this array structure in which at $arr[5]index I have a value that represents a number of occurrences for each object of my array $arr:

```<code>$arr=[
  [
    "some_value",
    "some_value",
    "cluster_0",
    "area_2",
    "some_value",
    "1"
  ],
  [
    "some_value",
    "some_value",
    "cluster_0",
    "area_2",
    "some_value",
    "2"
  ],
  [
    "some_value",
    "some_value",
    "cluster_0",
    "area_3",
    "some_value",
    "1"
  ],
  [
    "some_value",
    "some_value",
    "cluster_1",
    "area_3",
    "some_value",
    "3"
  ],
  [
    "some_value",
    "some_value",
    "cluster_1",
    "area_4",
    "some_value",
    "2"
  ],
  [
    "some_value",
    "some_value",
    "cluster_1",
    "area_4",
    "some_value",
    "2"
  ]
];
</code>```

What I'm trying to obtain is to sum each of those$arr[5] values grouping by $arr[2](the cluster) and the $arr[3](the area).

Here's the expected output

```<code>$res=[
  [
    "cluster_0",
    "area_2",
    3
  ],
  [
    "cluster_0",
    "area_3",
    1
  ],
  [
    "cluster_1",
    "area_3",
    3
  ],
  [
    "cluster_1",
    "area_4",
    4
  ]
];
</code>```

As you can see I have the sum of that specific value according to area and cluster matching. Is there any good approach in javascript for perform this kind of operation? I thought about a simple for loop and inside the loop an if condition for sum just the value that share the same $arr[2](the cluster) and the $arr[3](the area) values.

答:
You could take the indices for the groups and the value index and generate a new result set with using the group as hash key. Then add the value to the group.

function groupBy(array, groups, value) {
    var result = [],
        hash = Object.create(null);

    array.forEach(function (a) {
        var keys = groups.map(function (i) { return a[i] }),
            key = keys.join('|');
        if (!hash[key]) {
            hash[key] = keys.concat(0);
            result.push(hash[key]);
        }
        hash[key][hash[key].length - 1] += +a[value];
    });
    return result;
}

var array = [["some_value", "some_value", "cluster_0", "area_2", "some_value", "1"], ["some_value", "some_value", "cluster_0", "area_2", "some_value", "2"], ["some_value", "some_value", "cluster_0", "area_3", "some_value", "1"], ["some_value", "some_value", "cluster_1", "area_3", "some_value", "3"], ["some_value", "some_value", "cluster_1", "area_4", "some_value", "2"], ["some_value", "some_value", "cluster_1", "area_4", "some_value", "2"]],
    result = groupBy(array, [2, 3], 5);

console.log(result);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.as-console-wrapper { max-height: 100% !important; top: 0; }</code>```

Body:
I have this array structure in which at $arr[5]index I have a value that represents a number of occurrences for each object of my array $arr:

$arr=[
  [
    "some_value",
    "some_value",
    "cluster_0",
    "area_2",
    "some_value",
    "1"
  ],
  [
    "some_value",
    "some_value",
    "cluster_0",
    "area_2",
    "some_value",
    "2"
  ],
  [
    "some_value",
    "some_value",
    "cluster_0",
    "area_3",
    "some_value",
    "1"
  ],
  [
    "some_value",
    "some_value",
    "cluster_1",
    "area_3",
    "some_value",
    "3"
  ],
  [
    "some_value",
    "some_value",
    "cluster_1",
    "area_4",
    "some_value",
    "2"
  ],
  [
    "some_value",
    "some_value",
    "cluster_1",
    "area_4",
    "some_value",
    "2"
  ]
];

What I'm trying to obtain is to sum each of those$arr[5] values grouping by $arr[2](the cluster) and the $arr[3](the area).

Here's the expected output

$res=[
  [
    "cluster_0",
    "area_2",
    3
  ],
  [
    "cluster_0",
    "area_3",
    1
  ],
  [
    "cluster_1",
    "area_3",
    3
  ],
  [
    "cluster_1",
    "area_4",
    4
  ]
];

As you can see I have the sum of that specific value according to area and cluster matching. Is there any good approach in javascript for perform this kind of operation? I thought about a simple for loop and inside the loop an if condition for sum just the value that share the same $arr[2](the cluster) and the $arr[3](the area) values.

Body:
You could take the indices for the groups and the value index and generate a new result set with using the group as hash key. Then add the value to the group.

function groupBy(array, groups, value) {
    var result = [],
        hash = Object.create(null);

    array.forEach(function (a) {
        var keys = groups.map(function (i) { return a[i] }),
            key = keys.join('|');
        if (!hash[key]) {
            hash[key] = keys.concat(0);
            result.push(hash[key]);
        }
        hash[key][hash[key].length - 1] += +a[value];
    });
    return result;
}

var array = [["some_value", "some_value", "cluster_0", "area_2", "some_value", "1"], ["some_value", "some_value", "cluster_0", "area_2", "some_value", "2"], ["some_value", "some_value", "cluster_0", "area_3", "some_value", "1"], ["some_value", "some_value", "cluster_1", "area_3", "some_value", "3"], ["some_value", "some_value", "cluster_1", "area_4", "some_value", "2"], ["some_value", "some_value", "cluster_1", "area_4", "some_value", "2"]],
    result = groupBy(array, [2, 3], 5);

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }


问:
Unicode characters necessary for Japanese, Korean, and Chinese
I'm trying to answer these basic questions without getting a degree in linguistics and early human history, which seems to be where every google search has lead.

Which unicode characters are necessary to include in a font in order
to support rendering of Japanese language text?

Which unicode characters are necessary to include in a font in order
to support rendering of Chinese language text?

Which unicode characters are necessary to include in a font in order
to support rendering of Korean language text?

答:
It depend on how many coverage you want to give to each of those languages. Most commonly used characters in all these languages would only require a few thousands characters, but then once in a while you will encounter some characters outside the coverage. As you increase the number of characters supported by your system, you will be less likely to encounter these missing characters, until a point that you cover all the CJK characters.

A common approach used by modern font developers, in order to cut time and effort in making font and yet support enough amount of characters so that it would display most fonts, is to use ranges given in pre-Unicode era character set like Big5(-HKSCS), GB2312 or 18030, and such as mentioned in comment of others' answer, but then it would be rather common to encounter characters that are not supported.

In Unicode, something called IICore was made and defined about ten thousand characters that would be minimally essential to supporting these languages, and in Unicode database there are also info about whether they're essential to Chinese, Japanese, Korea or such, however nowadays barely anyone use them.

Google and Adobe is now making the Noto CJK or known as Source Han fonts, which is supposed to cover as much CJK characters as example. However, due to limitation in file format, they can only put in about 65535 glyphs into the font and thus would have to adding/dropping characters in the process of making them.

And at last, specifically for Korean, supporting only Hangul/Jamo is probably good enough in many cases because Hanja (the ideograph character) have been largely out of use other than in specialized area. Note that person names and some words in title could be part of these aspects that would still use Hanja so it depend if they're important to you or not


问:
Kivy - Error Unable permissions?
I need some help. I'm studying kivy and I use pycharm as IDE for development.
To work with kivy I created a virtualenvs with requeriments:

```<code>kivy = 1.10
Cython = 0.23
Python = 3.5
</code>```

As for setup I did not have too much trouble. It came later when I tried to generate a layout and it did not appear.
Is my code:

```<code># coding = utf-8

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.core.window import Window

def click():
    print (ed.text)

def build():

    layout = FloatLayout()

    ed = TextInput(text="USER.COM")
    global ed
    ed.size_hint = None, None
    ed.height = 300
    ed.width = 400
    ed.y = 60
    ed.x = 250

    bt = Button(text="Click Me")
    bt.size_hint = None, None
    bt.height = 50
    bt.width = 200
    bt.y = 150
    bt.x = 170
    bt.size_hint = None, None
    bt.on_press = click()

    layout.add_widget(ed)
    layout.add_widget(bt)

    return layout

Window.size=600,600
open= App()
open.title = "USER_FREE_AS"
open.buid=build
open.run()
</code>```

The log reports that pycharm is not allowed to access the function. Is my log:

```<code>/home/user/.virtualenvs/k35/bin/python /home/user/Projetos/Python/kivy/source/tela_layout/main.py
/home/user/Projetos/Python/kivy/source/tela_layout/main.py:18: SyntaxWarning: name 'ed' is assigned to before global declaration
  global ed
[INFO   ] [Logger      ] Record log in /home/victorpenna/.kivy/logs/kivy_17-11-13_11.txt
[INFO   ] [Kivy        ] v1.10.0
[INFO   ] [Python      ] v3.5.2 (default, Sep 14 2017, 22:51:06)
[GCC 5.4.0 20160609]
[INFO   ] [Factory     ] 194 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [OSC         ] using <multiprocessing> for socket
[INFO   ] [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
[INFO   ] [GL          ] Using the "OpenGL" graphics system
[INFO   ] [GL          ] Backend used <gl>
[INFO   ] [GL          ] OpenGL version <b'3.0 Mesa 17.3.0-rc2 - padoka PPA'>
[INFO   ] [GL          ] OpenGL vendor <b'Intel Open Source Technology Center'>
[INFO   ] [GL          ] OpenGL renderer <b'Mesa DRI Intel(R) HD Graphics 5500 (Broadwell GT2) '>
[INFO   ] [GL          ] OpenGL parsed version: 3, 0
[INFO   ] [GL          ] Shading version <b'1.30'>
[INFO   ] [GL          ] Texture max size <16384>
[INFO   ] [GL          ] Texture max units <32>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event8
[INFO   ] [MTD         ] Read event from </dev/input/event8>
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event13
[INFO   ] [MTD         ] Read event from </dev/input/event13>
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event14
[INFO   ] [MTD         ] Read event from </dev/input/event14>
[INFO   ] [Base        ] Start application main loop
[WARNING] [MTD         ] Unable to open device "/dev/input/event8". Please ensure you have the appropriate permissions.
[WARNING] [MTD         ] Unable to open device "/dev/input/event13". Please ensure you have the appropriate permissions.
[WARNING] [MTD         ] Unable to open device "/dev/input/event14". Please ensure you have the appropriate permissions.
[INFO   ] [Base        ] Leaving application in progress...

Process finished with exit code 0
</code>```

How can I solve this problem?

P.S: My linux is ubuntu 16.04, Intel GPU.

答:
Dark Window

A dark window was displayed because there is a typo error.

Replace:

```<code>open.buid=build
</code>```

with:

```<code>open.build=build
</code>```

Kivy Documentation

Programming Guide » Kivy Basics

Programming Guide » Kv language

Device Permission

In order to use these devices, you need to grant the user or group permission. This can be done via (in your case, replace "X" with 8, 13, 14):

```<code>$ sudo chmod u+r /dev/input/eventX
</code>```

SyntaxWarning: name 'ed'

You should declare global variable ed before assignment.

```<code>ed = ""

def click():
    print (ed.text)

def build():
    global ed

    layout = FloatLayout()

    ed = TextInput(text="USER.COM")
</code>```

Output

Title: Kivy - Error Unable permissions?

Body:
I need some help. I'm studying kivy and I use pycharm as IDE for development.
To work with kivy I created a virtualenvs with requeriments:

kivy = 1.10
Cython = 0.23
Python = 3.5

As for setup I did not have too much trouble. It came later when I tried to generate a layout and it did not appear.
Is my code:

# coding = utf-8

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.core.window import Window

def click():
    print (ed.text)

def build():

    layout = FloatLayout()

    ed = TextInput(text="USER.COM")
    global ed
    ed.size_hint = None, None
    ed.height = 300
    ed.width = 400
    ed.y = 60
    ed.x = 250

    bt = Button(text="Click Me")
    bt.size_hint = None, None
    bt.height = 50
    bt.width = 200
    bt.y = 150
    bt.x = 170
    bt.size_hint = None, None
    bt.on_press = click()

    layout.add_widget(ed)
    layout.add_widget(bt)

    return layout

Window.size=600,600
open= App()
open.title = "USER_FREE_AS"
open.buid=build
open.run()

The log reports that pycharm is not allowed to access the function. Is my log:

/home/user/.virtualenvs/k35/bin/python /home/user/Projetos/Python/kivy/source/tela_layout/main.py
/home/user/Projetos/Python/kivy/source/tela_layout/main.py:18: SyntaxWarning: name 'ed' is assigned to before global declaration
  global ed
[INFO   ] [Logger      ] Record log in /home/victorpenna/.kivy/logs/kivy_17-11-13_11.txt
[INFO   ] [Kivy        ] v1.10.0
[INFO   ] [Python      ] v3.5.2 (default, Sep 14 2017, 22:51:06)
[GCC 5.4.0 20160609]
[INFO   ] [Factory     ] 194 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [OSC         ] using <multiprocessing> for socket
[INFO   ] [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
[INFO   ] [GL          ] Using the "OpenGL" graphics system
[INFO   ] [GL          ] Backend used <gl>
[INFO   ] [GL          ] OpenGL version
[INFO   ] [GL          ] OpenGL vendor
[INFO   ] [GL          ] OpenGL renderer
[INFO   ] [GL          ] OpenGL parsed version: 3, 0
[INFO   ] [GL          ] Shading version
[INFO   ] [GL          ] Texture max size <16384>
[INFO   ] [GL          ] Texture max units <32>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event8
[INFO   ] [MTD         ] Read event from </dev/input/event8>
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event13
[INFO   ] [MTD         ] Read event from </dev/input/event13>
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event14
[INFO   ] [MTD         ] Read event from </dev/input/event14>
[INFO   ] [Base        ] Start application main loop
[WARNING] [MTD         ] Unable to open device "/dev/input/event8". Please ensure you have the appropriate permissions.
[WARNING] [MTD         ] Unable to open device "/dev/input/event13". Please ensure you have the appropriate permissions.
[WARNING] [MTD         ] Unable to open device "/dev/input/event14". Please ensure you have the appropriate permissions.
[INFO   ] [Base        ] Leaving application in progress...

Process finished with exit code 0

How can I solve this problem?

P.S: My linux is ubuntu 16.04, Intel GPU.

Body:
Dark Window

A dark window was displayed because there is a typo error.

Replace:

open.buid=build

with:

open.build=build

Kivy Documentation

Programming Guide » Kivy Basics

Programming Guide » Kv language

Device Permission

In order to use these devices, you need to grant the user or group permission. This can be done via (in your case, replace "X" with 8, 13, 14):

$ sudo chmod u+r /dev/input/eventX

SyntaxWarning: name 'ed'

You should declare global variable ed before assignment.

ed = ""

def click():
    print (ed.text)

def build():
    global ed

    layout = FloatLayout()

    ed = TextInput(text="USER.COM")

Output


问:
Why does SerializeJSON return an int with .0?
The following code:

```<code><cfscript>
struct = StructNew();
struct.x = 1;
struct.y = 2;
</cfscript>

<cfoutput>#SerializeJSON(struct)#</cfoutput>
</code>```

Results in the following output:

```<code>{"Y":2.0,"X":1.0}
</code>```

So my question is why does the .0 get added? and is there some way to remove it?

答: i assume the implementation is not the best :-/ try to checkout this: http://craigkaminsky.blogspot.com/2008/11/coldfusion-serializejson-gotcha.html</p>

Body:
The following code:

<cfscript>
struct = StructNew();
struct.x = 1;
struct.y = 2;
</cfscript>

<cfoutput>#SerializeJSON(struct)#</cfoutput>

Results in the following output:

{"Y":2.0,"X":1.0}

So my question is why does the .0 get added? and is there some way to remove it?


问:
How to remove or deactivate a listener
So, the way I have things set up, is that at specific conditions, I want a listener to be active, and after it has fired, stop listening for changes. Maybe I'm missing something, but I can't seem to figure out how to use the removeListener() function, or if that's even the way to go about doing this.

Some code:

```<code>        break1.setOnAction(e ->{
        final String fieldValue = manage_money.getText();
        int pp = Integer.parseInt(platinum_num.getText());
        int gp = Integer.parseInt(gold_num.getText());
        int sp = Integer.parseInt(silver_num.getText());
        int cp = Integer.parseInt(copper_num.getText());
        if (fieldValue != null && fieldValue.matches("\\d+")) {
            int value = Integer.parseInt(manage_money.getText());
            if (silver.isSelected()){
                if (value <= sp){
                    try {
                        tooltip_inv.getChildren().addAll(select);
                        radio_money2.selectedToggleProperty().addListener(((observable, oldValue, newValue) -> {
                            if (newValue == copper){
                                silver_num.setText(Integer.toString(sp - value));
                                copper_num.setText(Integer.toString(cp + value * 10));
                                manage_money.clear();
                                tooltip_inv.getChildren().clear();
                            }
                        }));
                    } catch (IllegalArgumentException ex) {
                    }
                }else{
                    manage_money.setText("ERR");
                }
            }
        }else{
            manage_money.setText("NaN");
        }
    });
</code>```

答:
What you've done in your example is you've defined a listener in your addListener method. You don't have any reference to it except there! One way to fix this is to simply create a variable for it and keep it somewhere, something like</p>

```<code>ChangeListener listener = new ChangeListener(){
    @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {
            // your code here
        }
};
radio_money2.selectedToggleProperty().addListener(listener);
radio_money2.selectedToggleProperty().removeListener(listener);
</code>```

Title: How to remove or deactivate a listener

Body:
So, the way I have things set up, is that at specific conditions, I want a listener to be active, and after it has fired, stop listening for changes. Maybe I'm missing something, but I can't seem to figure out how to use the removeListener() function, or if that's even the way to go about doing this.

Some code:

        break1.setOnAction(e ->{
        final String fieldValue = manage_money.getText();
        int pp = Integer.parseInt(platinum_num.getText());
        int gp = Integer.parseInt(gold_num.getText());
        int sp = Integer.parseInt(silver_num.getText());
        int cp = Integer.parseInt(copper_num.getText());
        if (fieldValue != null && fieldValue.matches("\\d+")) {
            int value = Integer.parseInt(manage_money.getText());
            if (silver.isSelected()){
                if (value <= sp){
                    try {
                        tooltip_inv.getChildren().addAll(select);
                        radio_money2.selectedToggleProperty().addListener(((observable, oldValue, newValue) -> {
                            if (newValue == copper){
                                silver_num.setText(Integer.toString(sp - value));
                                copper_num.setText(Integer.toString(cp + value * 10));
                                manage_money.clear();
                                tooltip_inv.getChildren().clear();
                            }
                        }));
                    } catch (IllegalArgumentException ex) {
                    }
                }else{
                    manage_money.setText("ERR");
                }
            }
        }else{
            manage_money.setText("NaN");
        }
    });

Body:
What you've done in your example is you've defined a listener in your addListener method. You don't have any reference to it except there! One way to fix this is to simply create a variable for it and keep it somewhere, something like

ChangeListener listener = new ChangeListener(){
    @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {
            // your code here
        }
};
radio_money2.selectedToggleProperty().addListener(listener);
radio_money2.selectedToggleProperty().removeListener(listener);


问:
Count with WHERE clause from two tables in Oracle?
I have two tables, one called STUDENTS and the other CLASSES. I have to select all the students that are from the same class of one student, and this student has his own number id, and through this number id that I have to select everything.

```<code>TABLE STUDENTS

nr_rgm
nm_name
nm_father
nm_mother
dt_birth
id_sex

TABLE CLASSES

cd_class
nr_schoolyear
cd_school
cd_degree
nr_series
cd_class
cd_period
</code>```

So I tried something like that :

```<code>SELECT count(*) FROM students, classes WHERE id_sex = 'M' AND
cd_class = (SELECT cd_class FROM classes WHERE nr_rgm = '12150');
</code>```

But then it points an error, and the error is the follow :

single-row subquery returns more than one row

So, how can I make this work ?

答: you should use "in" and not "=" when applying subselects. </p>

Body:
I have two tables, one called STUDENTS and the other CLASSES. I have to select all the students that are from the same class of one student, and this student has his own number id, and through this number id that I have to select everything.

TABLE STUDENTS

nr_rgm
nm_name
nm_father
nm_mother
dt_birth
id_sex

TABLE CLASSES

cd_class
nr_schoolyear
cd_school
cd_degree
nr_series
cd_class
cd_period

So I tried something like that :

SELECT count(*) FROM students, classes WHERE id_sex = 'M' AND
cd_class = (SELECT cd_class FROM classes WHERE nr_rgm = '12150');

But then it points an error, and the error is the follow :

single-row subquery returns more than one row

So, how can I make this work ?


问:
Top css Jquery in base a number
Hi guys i want to make a number to 100% for apply css in jquery for example:

```<code>var number = 14034 - 3000;
</code>```

Make that number the 100% for apply the css

```<code>$(this).css('top', number);
</code>```

but obviously i not want =

```<code>top: 11034%
</code>```

if 14034 is the 100%, how position one div in order the result, thanks :D

答: The formula is number / total * 100 :D

Title: Top css Jquery in base a number

Body:
Hi guys i want to make a number to 100% for apply css in jquery for example:

var number = 14034 - 3000;

Make that number the 100% for apply the css

$(this).css('top', number);

but obviously i not want =

top: 11034%

if 14034 is the 100%, how position one div in order the result, thanks :D

Body: The formula is number / total * 100 :D