问:
JQuery Sortable + Bootstrap - 1st column to last column - item vanishes
I'm trying to work out how to use JQuery Sortable with Bootstrap v3.

I have 3 columns and I want the list of items in column 1 to be dragged and dropped into column 3 - column 2 will contain some buttons to move all items back and forth.

The functionality works however while dragging, the item vanishes behind the middle column.

I've tried setting Z-Index of the column and the items being moved but still no joy.

Here's a basic fiddle...JsFiddle

$(".sortableList").sortable({
  cancel: ".fixed",
  connectWith: '.sortableList',
  distance: 6,
  opacity: 0.5
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#available {
  background-color: #ebebeb;
  height: 200px;
}

#selected {
  background-color: #ebebeb;
  height: 200px;
}

.item {
  margin: 1px;
  background-color: #bebebe;
}

.sortPlaceholder {
  opacity: 0.25;
}</code>```

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

Item 1

Item 2

Item 3

Item 4

Item 5

      <input type="button" class="btn btn-primary" value="<<" onclick="removeAll()" />
      <input type="button" class="btn btn-primary" value=">>" onclick="addAll()" />

```

答:
there is a div with overflow:hidden right inside the scroll-vertical . you need to remove that or change it to visible

then if you need to scroll inside the containers, add overflow-y auto to .sortableList

see snippet below

$(".sortableList").sortable({
  cancel: ".fixed",
  connectWith: '.sortableList',
  distance: 6,
  opacity: 0.5
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.sortableList  {
    overflow-y:auto;
}
#available {
  background-color: #ebebeb;
  height: 50px;

}

#selected {
  background-color: #ebebeb;
  height: 200px;

}

.item {
  margin: 1px;
  background-color: #bebebe;
}

.sortPlaceholder {
  opacity: 0.25;
}</code>```

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

Item 1

Item 2

Item 3

Item 4

Item 5

      <input type="button" class="btn btn-primary" value="<<" onclick="removeAll()" />
      <input type="button" class="btn btn-primary" value=">>" onclick="addAll()" />

```

Body:
I'm trying to work out how to use JQuery Sortable with Bootstrap v3.

I have 3 columns and I want the list of items in column 1 to be dragged and dropped into column 3 - column 2 will contain some buttons to move all items back and forth.

The functionality works however while dragging, the item vanishes behind the middle column.

I've tried setting Z-Index of the column and the items being moved but still no joy.

Here's a basic fiddle...JsFiddle

$(".sortableList").sortable({
  cancel: ".fixed",
  connectWith: '.sortableList',
  distance: 6,
  opacity: 0.5
});

#available {
  background-color: #ebebeb;
  height: 200px;
}

#selected {
  background-color: #ebebeb;
  height: 200px;
}

.item {
  margin: 1px;
  background-color: #bebebe;
}

.sortPlaceholder {
  opacity: 0.25;
}

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

Item 1

Item 2

Item 3

Item 4

Item 5

      <input type="button" class="btn btn-primary" value="<<" onclick="removeAll()" />
      <input type="button" class="btn btn-primary" value=">>" onclick="addAll()" />

Body:
there is a div with overflow:hidden right inside the scroll-vertical . you need to remove that or change it to visible

then if you need to scroll inside the containers, add overflow-y auto to .sortableList

see snippet below

$(".sortableList").sortable({
  cancel: ".fixed",
  connectWith: '.sortableList',
  distance: 6,
  opacity: 0.5
});

.sortableList  {
    overflow-y:auto;
}
#available {
  background-color: #ebebeb;
  height: 50px;

}

#selected {
  background-color: #ebebeb;
  height: 200px;

}

.item {
  margin: 1px;
  background-color: #bebebe;
}

.sortPlaceholder {
  opacity: 0.25;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<div id="sortContainer" class="container-fluid">
  <div class="row">
    <div class="col-xs-5 scroll-vertical">
      <div style="overflow: visible; position: relative">
        <div id="available" class="sortableList" runat="server">
          <div class="item">Item 1</div>
          <div class="item">Item 2</div>
          <div class="item">Item 3</div>
          <div class="item">Item 4</div>
          <div class="item">Item 5</div>
        </div>
      </div>
    </div>
    <div class="col-xs-2">
      <input type="button" class="btn btn-primary" value="<<" onclick="removeAll()" />
      <input type="button" class="btn btn-primary" value=">>" onclick="addAll()" />
    </div>
    <div class="col-xs-5  scroll-vertical">
      <div style="overflow: visible; position: relative">
        <div id="selected" class="sortableList" runat="server"></div>
      </div>
    </div>
  </div>
</div>


来源: stackexchange

问:
Java_why print member variable give actual value?
```<code>class Customer {
    public String name;

    public Customer(String name) {
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        Customer c = new Customer("Sally");
        System.out.println(c);
        System.out.println(c.name);
    }
}
</code>```

It's a simple question and we all know the output, but there's one quesiton about it

Please see the code above and the Picture here Passing Value

Question:

if I print out a reference of a object like this: System.out.println(c);, the IDE would generate a memory address for me: Customer@60e53b93

But, in the video tutorial(screenshot, see the image link Passing Value)

, the object have a member variable which is a reference to a String -> "Sally", why when I do System.out.println(c.name), trying to print out a reference(name), it give a real String object("Sally "). Shouldn't it print a memory address of the real Object("Sally")???

答:
First Question Answer:-
1.out is the static variable of PrintStream  in System Class.
   Which is declared in System class as

```<code>   public final static PrintStream out = null;
</code>```

And when you call System.out.println((Object)c);
which internally call the println method of PrintStrem Class.
The implementation of the println mehtod in PrintStream class is as below:-

```<code>   public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }
  public void print(Object obj) {
        write(String.valueOf(obj));
    }
</code>```

By this code it is clear that out will call the String ValueOf method.
and Implemetation of ValueOf() method in String Class as below:-

```<code> public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
</code>```

2.String class has Override the toString method of the Object Class as Below :-

```<code>    /**
     * This object (which is already a string!) is itself returned.
     *
     * @return  the string itself.
     */
    public String toString() {
       return this;
     }
</code>```

The toString() Method in Object Class:-

```<code>  /**
   * Returns a string representation of the object. In general, the
   */
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
</code>```

Your class Customer didn't override the toString() method of Object class so when you Call System.out.println(c); it  will call the toString method of Object Class. Thats y you will get Customer@60e53b93 as a output.

ContentLicense: CC BY-SA 3.0

Body:
class Customer {
    public String name;

    public Customer(String name) {
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        Customer c = new Customer("Sally");
        System.out.println(c);
        System.out.println(c.name);
    }
}

It's a simple question and we all know the output, but there's one quesiton about it

Please see the code above and the Picture here Passing Value

Question:

if I print out a reference of a object like this: System.out.println(c);, the IDE would generate a memory address for me: Customer@60e53b93

But, in the video tutorial(screenshot, see the image link Passing Value)

, the object have a member variable which is a reference to a String -> "Sally", why when I do System.out.println(c.name), trying to print out a reference(name), it give a real String object("Sally "). Shouldn't it print a memory address of the real Object("Sally")???

Body:
First Question Answer:-
1.out is the static variable of PrintStream  in System Class.
   Which is declared in System class as

   public final static PrintStream out = null;

And when you call System.out.println((Object)c);
which internally call the println method of PrintStrem Class.
The implementation of the println mehtod in PrintStream class is as below:-

   public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }
  public void print(Object obj) {
        write(String.valueOf(obj));
    }

By this code it is clear that out will call the String ValueOf method.
and Implemetation of ValueOf() method in String Class as below:-

 public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }

2.String class has Override the toString method of the Object Class as Below :-

    /**
     * This object (which is already a string!) is itself returned.
     *
     * @return  the string itself.
     */
    public String toString() {
       return this;
     }

The toString() Method in Object Class:-

  /**
   * Returns a string representation of the object. In general, the
   */
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

Your class Customer didn't override the toString() method of Object class so when you Call System.out.println(c); it  will call the toString method of Object Class. Thats y you will get Customer@60e53b93 as a output.


问:
Adding prev&next buttons only on specific pages in Wordpress
I have 6 pages which are under specific parent page, like:

```<code>http://example.com/parent/page1
...
http://example.com/parent/page6
</code>```

I want to show previous and next link only on those 6 pages. The problem is that it's showed on all other pages also.

What I'm trying according to documentation I need to use TRUE in the links. This is what I have tried in my function.php

```<code>function new_post_navigation(){
?>
    <div class="arrowNav">
        <div class="arrowLeft">
            <?php previous_post_link('%link', '<i class="fa fa-chevron-circle-left" aria-hidden="true"></i>', TRUE); ?>
        </div>
        <div class="arrowRight">
            <?php next_post_link('%link', '<i class="fa fa-chevron-circle-right" aria-hidden="true"></i>', TRUE); ?>
        </div>
    </div>
<?php
}
add_action('wp_footer', 'new_post_navigation');
</code>```

When I add TRUE to the link it's not showed on the page at all. When I put it FALSE the links are visible but also all other pages.

答:
you can try this code and check once, do put the name of the pages inside the array</p>

```<code>function new_post_navigation(){
$pages = ['page1',.......];
$title = wp_title('',false);
if(in_array($title, $pages)){
?>
    <div class="arrowNav">
        <div class="arrowLeft">
            <?php previous_post_link('%link', '<i class="fa fa-chevron-circle-left" aria-hidden="true"></i>', TRUE); ?>
        </div>
        <div class="arrowRight">
            <?php next_post_link('%link', '<i class="fa fa-chevron-circle-right" aria-hidden="true"></i>', TRUE); ?>
        </div>
    </div>
<?php
}
}
add_action('wp_footer', 'new_post_navigation');
</code>```

Body:
I have 6 pages which are under specific parent page, like:

http://example.com/parent/page1
...
http://example.com/parent/page6

I want to show previous and next link only on those 6 pages. The problem is that it's showed on all other pages also.

What I'm trying according to documentation I need to use TRUE in the links. This is what I have tried in my function.php

function new_post_navigation(){
?>

            <?php previous_post_link('%link', '', TRUE); ?>

            <?php next_post_link('%link', '', TRUE); ?>

<?php
}
add_action('wp_footer', 'new_post_navigation');

When I add TRUE to the link it's not showed on the page at all. When I put it FALSE the links are visible but also all other pages.

Body:
you can try this code and check once, do put the name of the pages inside the array

function new_post_navigation(){
$pages = ['page1',.......];
$title = wp_title('',false);
if(in_array($title, $pages)){
?>
    <div class="arrowNav">
        <div class="arrowLeft">
            <?php previous_post_link('%link', '<i class="fa fa-chevron-circle-left" aria-hidden="true"></i>', TRUE); ?>
        </div>
        <div class="arrowRight">
            <?php next_post_link('%link', '<i class="fa fa-chevron-circle-right" aria-hidden="true"></i>', TRUE); ?>
        </div>
    </div>
<?php
}
}
add_action('wp_footer', 'new_post_navigation');


问:
When to use an object or an array in javascript?
I just found out that Arrays inherit directly from Object in javascript.  I'm finding the difference between an array and an object is fairly minuscule.

How do i know when to use one over the other?

答: When you need to depend on the order of the elements in the collection, use Arrays, when order is not important, use objects. Order is not guaranteed in objects, but they provide for fast key-value pair lookups.

ContentLicense: CC BY-SA 2.5


问:
AppDynamics database agent 4.3.10 error on SQL Server 2005
I just testing AppDynamics for my database, I am able get it work on MySQL 5 and SQL Server 2014, but I got a JDBC error on SQL Server 2005.

Here is the error log:

06 6月 2017 00:55:59,461 ERROR [AD Thread Pool-Global0] DBAgentPollingForUpdate:30 - Fatal transport error while connecting to URL [/controller/instance/DBAGENT_MACHINE_ID/db-monit
  or-config/37784]: org.apache.http.NoHttpResponseException: davinci2017060100542331.saas.appdynamics.com:443 failed to respond
  06 6月 2017 00:55:59,473  WARN [AD Thread Pool-Global0] DBAgentPollingForUpdate:62 - Invalid response for configuration request from controller/could not connect. Msg: Fatal transp
  ort error while connecting to URL [/controller/instance/DBAGENT_MACHINE_ID/db-monitor-config/37784]
  06 6月 2017 00:56:00,026  INFO [-Scheduler-3] ADBCollector:141 - DB Collector DBSERVER01 is temporarily disabled.
  06 6月 2017 00:56:01,026  INFO [-Scheduler-3] ARelationalDBCollector:59 - (Re)initialize the DB collector 'DBSERVER01'.
  06 6月 2017 00:56:01,040  INFO [-Scheduler-3] MSSqlCollector:74 - Obtained connection for url jdbc:sqlserver://192.168.1.100:1433
  06 6月 2017 00:56:01,047  INFO [-Scheduler-3] MSSqlCollector:139 - SQL Server Version = 9.00.5057.00 ( 2005.0 )
  06 6月 2017 00:57:00,025 ERROR [-Scheduler-1] ADBCollector:172 - Error collecting data for database 'DBSERVER01'
  com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'sys'.
          at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
          at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)
          at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404)
          at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)
          at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
          at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
          at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
          at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
          at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:285)
          at com.singularity.ee.agent.dbagent.collector.db.relational.mssql.AMSSqlCollectorDelegate.collectDBMSMetrics(AMSSqlCollectorDelegate.java:335)
          at com.singularity.ee.agent.dbagent.collector.db.ADBCollectorDelegate.collectPerMinute(ADBCollectorDelegate.java:88)
          at com.singularity.ee.agent.dbagent.collector.db.ADBCollector.collect(ADBCollector.java:156)
          at com.singularity.ee.agent.dbagent.collector.db.ADBCollector.run(ADBCollector.java:139)
          at com.singularity.ee.util.javaspecific.scheduler.AgentScheduledExecutorServiceImpl$SafeRunnable.run(AgentScheduledExecutorServiceImpl.java:122)
          at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
          at com.singularity.ee.util.javaspecific.scheduler.ADFutureTask$Sync.innerRunAndReset(ADFutureTask.java:335)
          at com.singularity.ee.util.javaspecific.scheduler.ADFutureTask.runAndReset(ADFutureTask.java:152)
          at com.singularity.ee.util.javaspecific.scheduler.ADScheduledThreadPoolExecutor$ADScheduledFutureTask.access$101(ADScheduledThreadPoolExecutor.java:119)
          at com.singularity.ee.util.javaspecific.scheduler.ADScheduledThreadPoolExecutor$ADScheduledFutureTask.runPeriodic(ADScheduledThreadPoolExecutor.java:206)
          at com.singularity.ee.util.javaspecific.scheduler.ADScheduledThreadPoolExecutor$ADScheduledFutureTask.run(ADScheduledThreadPoolExecutor.java:236)
          at com.singularity.ee.util.javaspecific.scheduler.ADThreadPoolExecutor$Worker.runTask(ADThreadPoolExecutor.java:694)
          at com.singularity.ee.util.javaspecific.scheduler.ADThreadPoolExecutor$Worker.run(ADThreadPoolExecutor.java:726)
          at java.lang.Thread.run(Unknown Source)

答: SQL 2005 is supported, but this was a bug which was introduced in version 4.3.0. There is currently a diagnostic patch for this issue for supported customers. The fix should be in the next patch level once we isolate the issue. If you'd like support just email help@appdynamics.com and they can assist. Thanks.</p>


问:
upload a file and obtain its file name and save it to database that is in pgsql
in index.js file i have given

```<code>router.post('/postfileupload',User.postFileUpload,function(req,res,next){
    User.postFileUpload(req,res);
});
</code>```

and in user.js I have provided the function definition as:

```<code>function postFileUpload(req,res){
  if(req.files)
    console.log('request for fileupload \n ',req.files);
}
</code>```

and while running the code i get the error
"Error: Route.post() requires callback functions but got a [object Undefined]"

Please help...

答:
First, it should be if(req.files) in postFileUpload, not res.files

Second, postFileUpload function does not return anything to the user and does not call next(). Change it to:

```<code>function postFileUpload(req, res, next){
  if(req.files)
    console.log('request for fileupload \n ',req.files);
  next();
}
</code>```

Third, your other middleware function, which also calls User.postFileUpload for some weird reason (do you even need to call that function twice?), also doesn't return anything to the user. Change it to something like:

```<code>function(req,res,next){
    res.status(200).send('OK');
}
</code>```

In short, your router should look like:

```<code>router.post('/postfileupload', User.postFileUpload, function(req,res,next){
    // Do whatever you want to do here
    res.status(200).send('OK');
});
</code>```

Body:
in index.js file i have given

router.post('/postfileupload',User.postFileUpload,function(req,res,next){
    User.postFileUpload(req,res);
});

and in user.js I have provided the function definition as:

function postFileUpload(req,res){
  if(req.files)
    console.log('request for fileupload \n ',req.files);
}

and while running the code i get the error
"Error: Route.post() requires callback functions but got a [object Undefined]"

Please help...

Body:
First, it should be if(req.files) in postFileUpload, not res.files

Second, postFileUpload function does not return anything to the user and does not call next(). Change it to:

function postFileUpload(req, res, next){
  if(req.files)
    console.log('request for fileupload \n ',req.files);
  next();
}

Third, your other middleware function, which also calls User.postFileUpload for some weird reason (do you even need to call that function twice?), also doesn't return anything to the user. Change it to something like:

function(req,res,next){
    res.status(200).send('OK');
}

In short, your router should look like:

router.post('/postfileupload', User.postFileUpload, function(req,res,next){
    // Do whatever you want to do here
    res.status(200).send('OK');
});


问:
Pandas, sorting a dataframe in a useful way to find the difference between times. Why are key and value errors appearing?
I have a pandas DataFrame containing 5 columns.

```<code>['date', 'sensorId', 'readerId', 'rssi']
df_json['time'] = df_json.date.dt.time
</code>```

I am aiming to find people who have entered a store (rssi > 380). However this would be much more accurate if I could also check every record a sensorId appears in and whether the time in that record is within 5 seconds of the current record.

Data from the dataFrame: (df_json)

```<code>                       date  sensorId  readerId  rssi
0   2017-03-17 09:15:59.453   4000068        76   352
0   2017-03-17 09:20:17.708   4000068        56   374
1   2017-03-17 09:20:42.561   4000068        60   392
0   2017-03-17 09:44:21.728   4000514        76   352
0   2017-03-17 10:32:45.227   4000461        76   332
0   2017-03-17 12:47:06.639   4000046        43   364
0   2017-03-17 12:49:34.438   4000046        62   423
0   2017-03-17 12:52:28.430   4000072        62   430
1   2017-03-17 12:52:32.593   4000072        62   394
0   2017-03-17 12:53:17.708   4000917        76   335
0   2017-03-17 12:54:24.848   4000072        25   402
1   2017-03-17 12:54:35.738   4000072        20   373
</code>```

I would like to use jezrael's answer of df['date'].diff(). However I cannot successfully use this, I receive many different errors. The ['date'] column is of dtype datetime64[ns].

How the data is stored above is not useful, for the .diff() to be of any use the data must be stored as below (dfEntered):

Sample Data: dfEntered

```<code>    date       sensorId readerId time            rssi
    2017-03-17 4000046  43       12:47:06.639000 364
                        62       12:49:34.438000 423
               4000068  56       09:20:17.708000 374
                        60       09:20:42.561000 392
                        76       09:15:59.453000 352
               4000072  20       12:54:35.738000 373
                                 12:54:42.673000 374
                        25       12:54:24.848000 402
                                 12:54:39.723000 406
                        62       12:52:28.430000 430
                                 12:52:32.593000 394
               4000236  18       13:28:14.834000 411
</code>```

I am planning on replacing 'time' with 'date'. Time is of dtype object and I cannot seem to cast it or diff() it.'date' will be just as useful.

The only way (I have found) of having df_json appear as dfEntered is with:
    dfEntered = df_json.groupby(by=[df_json.date.dt.time, 'sensorId', 'readerId', 'date'])

If I do:

```<code>dfEntered = df_json.groupby(by=[df_json.date.dt.time, 'sensorId', 'readerId'])['date'].diff()
</code>```

results in:

```<code>File "processData.py", line 61, in <module>
dfEntered = df_json.groupby(by=[df_json.date.dt.date, 'sensorId', 'readerId', 'rssi'])['date'].diff()
  File "<string>", line 17, in diff
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\groupby.py", line 614, in wrapper
    raise ValueError
ValueError
</code>```

If I do:

```<code>dfEntered = df_json.groupby(by=[df_json.date.dt.date, 'sensorId', 'readerId', 'rssi'])['time'].count()
print(dfEntered['date'])
</code>```

Results in:

```<code>File "processData.py", line 65, in <module>
    print(dfEntered['date'])
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\series.py", line 601, in __getitem__
    result = self.index.get_value(self, key)
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\indexes\multi.py", line 821, in get_value
    raise e1
KeyError: 'date'
</code>```

I applied a .count() to the groupby just so that I can output it. I had previously tried a .agg({'date':'diff'}) which resluts in the valueError, but the dtype is datetime64[ns] (atleast in the original df_json, I cannot view the dtype of dfEntered['date']

If the above would work I would like to have a df of [df_json.date.dt.date, 'sensorId', 'readerId', 'mask'] mask being true if they entered a store.

I then have the below df (contains sensorIds that received a text)

```<code>   sensor_id sms_status                date_report  rssi  readerId
0    5990100    SUCCESS 2017-05-03 13:41:28.412800   500  10
1    5990001    SUCCESS 2017-05-03 13:41:28.412800   500  11
2    5990100    SUCCESS 2017-05-03 13:41:30.413000   500  12
3    5990001    SUCCESS 2017-05-03 13:41:31.413100   500  13
4    5990100    SUCCESS 2017-05-03 13:41:34.413400   500  14
5    5990001    SUCCESS 2017-05-03 13:41:35.413500   500  52
6    5990100    SUCCESS 2017-05-03 13:41:38.413800   500  60
7    5990001    SUCCESS 2017-05-03 13:41:39.413900   500  61
</code>```

I would then like to merge the two together on day, sensorId, readerId.
I am hoping that would result in a df that could appear as [df_json.date.dt.date, 'sensorId', 'readerId', 'mask'] and therefore I could say that a sensorId with a mask of true is a conversion. A conversion being that sensorId received a text that day and also entered the store that day.

I'm beginning to get wary that my end aim isn't even achievable, as I simply do not understand how pandas works yet :D (damn errors)

UPDATE

```<code>dfEntered = dfEntered.reset_index()
</code>```

This is allowing me to access the date and apply a diff.

I don't quite understand the theory of how this problem occurred, and why reset_index() fixed this.

Body:
I have a pandas DataFrame containing 5 columns.

['date', 'sensorId', 'readerId', 'rssi']
df_json['time'] = df_json.date.dt.time

I am aiming to find people who have entered a store (rssi > 380). However this would be much more accurate if I could also check every record a sensorId appears in and whether the time in that record is within 5 seconds of the current record.

Data from the dataFrame: (df_json)

                       date  sensorId  readerId  rssi
0   2017-03-17 09:15:59.453   4000068        76   352
0   2017-03-17 09:20:17.708   4000068        56   374
1   2017-03-17 09:20:42.561   4000068        60   392
0   2017-03-17 09:44:21.728   4000514        76   352
0   2017-03-17 10:32:45.227   4000461        76   332
0   2017-03-17 12:47:06.639   4000046        43   364
0   2017-03-17 12:49:34.438   4000046        62   423
0   2017-03-17 12:52:28.430   4000072        62   430
1   2017-03-17 12:52:32.593   4000072        62   394
0   2017-03-17 12:53:17.708   4000917        76   335
0   2017-03-17 12:54:24.848   4000072        25   402
1   2017-03-17 12:54:35.738   4000072        20   373

I would like to use jezrael's answer of df['date'].diff(). However I cannot successfully use this, I receive many different errors. The ['date'] column is of dtype datetime64[ns].

How the data is stored above is not useful, for the .diff() to be of any use the data must be stored as below (dfEntered):

Sample Data: dfEntered

    date       sensorId readerId time            rssi
    2017-03-17 4000046  43       12:47:06.639000 364
                        62       12:49:34.438000 423
               4000068  56       09:20:17.708000 374
                        60       09:20:42.561000 392
                        76       09:15:59.453000 352
               4000072  20       12:54:35.738000 373
                                 12:54:42.673000 374
                        25       12:54:24.848000 402
                                 12:54:39.723000 406
                        62       12:52:28.430000 430
                                 12:52:32.593000 394
               4000236  18       13:28:14.834000 411

I am planning on replacing 'time' with 'date'. Time is of dtype object and I cannot seem to cast it or diff() it.'date' will be just as useful.

The only way (I have found) of having df_json appear as dfEntered is with:
    dfEntered = df_json.groupby(by=[df_json.date.dt.time, 'sensorId', 'readerId', 'date'])

If I do:

dfEntered = df_json.groupby(by=[df_json.date.dt.time, 'sensorId', 'readerId'])['date'].diff()

results in:

File "processData.py", line 61, in <module>
dfEntered = df_json.groupby(by=[df_json.date.dt.date, 'sensorId', 'readerId', 'rssi'])['date'].diff()
  File "<string>", line 17, in diff
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\groupby.py", line 614, in wrapper
    raise ValueError
ValueError

If I do:

dfEntered = df_json.groupby(by=[df_json.date.dt.date, 'sensorId', 'readerId', 'rssi'])['time'].count()
print(dfEntered['date'])

Results in:

File "processData.py", line 65, in <module>
    print(dfEntered['date'])
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\series.py", line 601, in __getitem__
    result = self.index.get_value(self, key)
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\indexes\multi.py", line 821, in get_value
    raise e1
KeyError: 'date'

I applied a .count() to the groupby just so that I can output it. I had previously tried a .agg({'date':'diff'}) which resluts in the valueError, but the dtype is datetime64[ns] (atleast in the original df_json, I cannot view the dtype of dfEntered['date']

If the above would work I would like to have a df of [df_json.date.dt.date, 'sensorId', 'readerId', 'mask'] mask being true if they entered a store.

I then have the below df (contains sensorIds that received a text)

   sensor_id sms_status                date_report  rssi  readerId
0    5990100    SUCCESS 2017-05-03 13:41:28.412800   500  10
1    5990001    SUCCESS 2017-05-03 13:41:28.412800   500  11
2    5990100    SUCCESS 2017-05-03 13:41:30.413000   500  12
3    5990001    SUCCESS 2017-05-03 13:41:31.413100   500  13
4    5990100    SUCCESS 2017-05-03 13:41:34.413400   500  14
5    5990001    SUCCESS 2017-05-03 13:41:35.413500   500  52
6    5990100    SUCCESS 2017-05-03 13:41:38.413800   500  60
7    5990001    SUCCESS 2017-05-03 13:41:39.413900   500  61

I would then like to merge the two together on day, sensorId, readerId.
I am hoping that would result in a df that could appear as [df_json.date.dt.date, 'sensorId', 'readerId', 'mask'] and therefore I could say that a sensorId with a mask of true is a conversion. A conversion being that sensorId received a text that day and also entered the store that day.

I'm beginning to get wary that my end aim isn't even achievable, as I simply do not understand how pandas works yet :D (damn errors)

UPDATE

dfEntered = dfEntered.reset_index()

This is allowing me to access the date and apply a diff.

I don't quite understand the theory of how this problem occurred, and why reset_index() fixed this.

Body:
I think you need boolean indexing with mask created with diff:

df = pd.DataFrame({'rssi': [500,530,1020,1201,1231,10],
                   'time': pd.to_datetime(['2017-01-01 14:01:08','2017-01-01 14:01:14',
                                           '2017-01-01 14:01:17', '2017-01-01 14:01:27',
                                           '2017-01-01 14:01:29', '2017-01-01 14:01:30'])})
print (df)
   rssi                time
0   500 2017-01-01 14:01:08
1   530 2017-01-01 14:01:14
2  1020 2017-01-01 14:01:17
3  1201 2017-01-01 14:01:27
4  1231 2017-01-01 14:01:29
5    10 2017-01-01 14:01:30

print (df['time'].diff())
0        NaT
1   00:00:06
2   00:00:03
3   00:00:10
4   00:00:02
5   00:00:01
Name: time, dtype: timedelta64[ns]

mask = (df['time'].diff() >'00:00:05')  & (df['rssi'] > 380)
print (mask)
0    False
1     True
2    False
3     True
4    False
5    False
dtype: bool

df1 = df[mask]
print (df1)
   rssi                time
1   530 2017-01-01 14:01:14
3  1201 2017-01-01 14:01:27


问:
SpriteKit Shop Scene in game
Any idea how I could implement a shop in my spriteKit game that users could buy different players with coins they have earned in game? any tutorials out there?</p>

答:
This is a multi-step project that took me about 500 loc (more without using .SKS) Here is the link to github finished project: https://github.com/fluidityt/ShopScene

Note, I am using a macOS SpriteKit project because it launches much faster on my computer. Simply change mouseDown() to touchesBegan() to get this to run on iOS.

First edit your GameScene.sks to look like this: (saves a bunch of time coding labels)

Make sure that you name everything EXACTLY as we need this to detect touch:

"entershop", "getcoins", "coinlabel", "levellabel"

This is the main "gameplay" scene and as you click coins++ you get levels and can move around. Clicking the shop will enter the shop.

Here is our GameScene.swift which matches this SKS:

```<code>import SpriteKit

class GameScene: SKScene {

  let player = Player(costume: Costume.defaultCostume)

  lazy var enterNode:  SKLabelNode = { return (self.childNode(withName: "entershop")  as! SKLabelNode) }()
  lazy var coinNode:   SKLabelNode = { return (self.childNode(withName: "getcoins" )  as! SKLabelNode) }()
  lazy var coinLabel:  SKLabelNode = { return (self.childNode(withName: "coinlabel")  as! SKLabelNode) }()
  lazy var levelLabel: SKLabelNode = { return (self.childNode(withName: "levellabel") as! SKLabelNode) }()

  override func didMove(to view: SKView) {
    player.name = "player"
    if player.scene == nil { addChild(player) }
  }

  override func mouseDown(with event: NSEvent) {

    let location = event.location(in: self)

    if let name = atPoint(location).name {

      switch name {

      case "entershop": view!.presentScene(ShopScene(previousGameScene: self))

      case "getcoins":  player.getCoins(1)

      default: ()
      }
    }

    else {
      player.run(.move(to: location, duration: 1))
    }
  }

  override func update(_ currentTime: TimeInterval) {

    func levelUp(_ level: Int) {
      player.levelsCompleted = level
      levelLabel.text = "Level: \(player.levelsCompleted)"
    }

    switch player.coins {
      case 10: levelUp(2)
      case 20: levelUp(3)
      case 30: levelUp(4)
      default: ()
    }
  }
};
</code>```

Here you can see that we have a few other things going on not yet introduced: Player and Costume

Player is a spritenode subclass (it doubles as a data model and a UI element). Our player is just a colored square that gets moved around when you click the screen

The player wears something of Costume type, which is just a model that keeps track of data such as price, name, and the texture for the player to display.

Here is Costume.swift:

```<code>import SpriteKit

/// This is just a test method should be deleted when you have actual texture assets:
private func makeTestTexture() -> (SKTexture, SKTexture, SKTexture, SKTexture) {

  func texit(_ sprite: SKSpriteNode) -> SKTexture { return SKView().texture(from: sprite)! }
  let size = CGSize(width: 50, height: 50)

  return (
    texit(SKSpriteNode(color: .gray,  size: size)),
    texit(SKSpriteNode(color: .red,   size: size)),
    texit(SKSpriteNode(color: .blue,  size: size)),
    texit(SKSpriteNode(color: .green, size: size))
  )
}

/// The items that are for sale in our shop:
struct Costume {

  static var allCostumes: [Costume] = []

  let name:    String
  let texture: SKTexture
  let price:   Int

  init(name: String, texture: SKTexture, price: Int) { self.name = name; self.texture = texture; self.price = price
    // This init simply adds all costumes to a master list for easy sorting later on.
    Costume.allCostumes.append(self)
  }

  private static let (tex1, tex2, tex3, tex4) = makeTestTexture()  // Just a test needed to be deleted when you have actual assets.

  static let list = (
    // Hard-code any new costumes you create here (this is a "master list" of costumes)
    // (make sure all of your costumes have a unique name, or the program will not work properly)
    gray:  Costume(name: "Gray Shirt",  texture: tex1 /*SKTexture(imageNamed: "grayshirt")*/,  price:  0),
    red:   Costume(name: "Red Shirt",   texture: tex2 /*SKTexture(imageNamed: "redshirt")*/,   price: 5),
    blue:  Costume(name: "Blue Shirt",  texture: tex3 /*SKTexture(imageNamed: "blueshirt")*/,  price: 25),
    green: Costume(name: "Green Shirt", texture: tex4 /*SKTexture(imageNamed: "greenshirt")*/, price: 50)
  )

  static let defaultCostume = list.gray
};

func == (lhs: Costume, rhs: Costume) -> Bool {
  // The reason why you need unique names:
  if lhs.name == rhs.name { return true }
  else { return false }
}
</code>```

The design of this struct is twofold.. first is to be a blueprint for a Costume object (which holds the name, price, and texture of a costume), and second it serves as a repository for all of your costumes via a hard-coded static master list property.

The function at the top makeTestTextures() is just an example for this project. I did this just so that way you can copy and paste instead of having to download image files to use.

Here is the Player.swift, which can wear the costumes in the list:

```<code>final class Player: SKSpriteNode {

  var coins = 0
  var costume: Costume
  var levelsCompleted = 0

  var ownedCostumes: [Costume] = [Costume.list.gray]      // FIXME: This should be a Set, but too lazy to do Hashable.

  init(costume: Costume) {
    self.costume = costume
    super.init(texture: costume.texture, color: .clear, size: costume.texture.size())
  }

  func getCoins(_ amount: Int) {
    guard let scene = self.scene as? GameScene else {     // This is very specific code just for this example.
      fatalError("only call this func after scene has been set up")
    }

    coins += amount
    scene.coinLabel.text = "Coins: \(coins)"
  }

  func loseCoins(_ amount: Int) {
    guard let scene = self.scene as? GameScene else {     // This is very specific code just for this example.
      fatalError("only call this func after scene has been set up")
    }

    coins -= amount
    scene.coinLabel.text = "Coins: \(coins)"
  }

  func hasCostume(_ costume: Costume) -> Bool {
    if ownedCostumes.contains(where: {$0.name == costume.name}) { return true }
    else { return false }
  }

  func getCostume(_ costume: Costume) {
    if hasCostume(costume) { fatalError("trying to get costume already owned") }
    else { ownedCostumes.append(costume) }
  }

  func wearCostume(_ costume: Costume) {
    guard hasCostume(costume) else { fatalError("trying to wear a costume you don't own") }
    self.costume = costume
    self.texture = costume.texture
  }

  required init?(coder aDecoder: NSCoder) { fatalError() }
};
</code>```

Player has a lot of functions, but they all could be handled elsewhere in the code. I just went for this design decision, but don't feel like you need to load up your classes with 2 line methods.

Now we are getting to the more nitty-gritty stuff, since we have set up our:

Base scene

Costume list

Player object

The last two things we really need are:
1. A shop model to keep track of inventory
2. A shop scene to display inventory, UI elements, and handle the logic of whether or not you can buy items

Here is Shop.swift:

```<code>/// Our model class to be used inside of our ShopScene:
final class Shop {

  weak private(set) var scene: ShopScene!     // The scene in which this shop will be called from.

  var player: Player { return scene.player }

  var availableCostumes: [Costume] = [Costume.list.red, Costume.list.blue]   // (The green shirt wont become available until the player has cleared 2 levels).

  // var soldCostumes: [Costume] = [Costume.defaultCostume] // Implement something with this if you want to exclude previously bought items from the store.

  func canSellCostume(_ costume: Costume) -> Bool {
    if player.coins < costume.price                { return false }
    else if player.hasCostume(costume)             { return false }
    else if player.costume == costume              { return false }
    else                                           { return true  }
  }

  /// Only call this after checking canBuyCostume(), or you likely will have errors:
  func sellCostume(_ costume: Costume) {
    player.loseCoins(costume.price)
    player.getCostume(costume)
    player.wearCostume(costume)
  }

  func newCostumeBecomesAvailable(_ costume: Costume) {
    if availableCostumes.contains(where: {$0.name == costume.name}) /*|| soldCostumes.contains(costume)*/ {
      fatalError("trying to add a costume that is already available (or sold!)")
    }
    else { availableCostumes.append(costume) }
  }

  init(shopScene: ShopScene) {
    self.scene = shopScene
  }

  deinit { print("shop: if you don't see this message when exiting shop then you have a retain cycle") }
};
</code>```

The idea was to have the fourth costume only be available at a certain level, but I've run out of time to implement this feature, but most of the supporting methods are there (you just need to implement the logic).

Also, Shop can pretty much just be a struct, but I feel that it's more flexible as a class for now.

Now, before jumping into ShopScene, our biggest file, let me tell you about a couple of design decisions.

First, I'm using node.name to handle touches / clicks. This lets me use the .SKS and the regular SKNode types quickly and easily. Normally, I like to subclass SKNodes and then override their own touchesBegan method to handle clicks. You can do it either way.

Now, in ShopScene you have buttons for "buy", "exit" which I have used as just regular SKLabelNodes; but for the actual nodes that display the costume, I have created a subclass called CostumeNode.

I made CostumeNode so that way it could handle nodes for displaying the costume's name, price, and doing some animations. CostumeNode is just a visual element (unlike Player).

Here is CostumeNode.swift:

```<code>/// Just a UI representation, does not manipulate any models.
final class CostumeNode: SKSpriteNode {

  let costume:   Costume

  weak private(set) var player: Player!

  private(set) var
  backgroundNode = SKSpriteNode(),
  nameNode       = SKLabelNode(),
  priceNode      = SKLabelNode()

  private func label(text: String, size: CGSize) -> SKLabelNode {
    let label = SKLabelNode(text: text)
    label.fontName = "Chalkduster"
    // FIXME: deform label to fit size and offset
    return label
  }

  init(costume: Costume, player: Player) {

     func setupNodes(with size: CGSize) {

      let circle = SKShapeNode(circleOfRadius: size.width)
      circle.fillColor = .yellow
      let bkg = SKSpriteNode(texture: SKView().texture(from: circle))
      bkg.zPosition -= 1

      let name = label(text: "\(costume.name)", size: size)
      name.position.y = frame.maxY + name.frame.size.height

      let price = label(text: "\(costume.price)", size: size)
      price.position.y = frame.minY - price.frame.size.height

      addChildrenBehind([bkg, name, price])
      (backgroundNode, nameNode, priceNode) = (bkg, name, price)
    }

    self.player = player
    self.costume = costume

    let size = costume.texture.size()
    super.init(texture: costume.texture, color: .clear, size: size)

    name = costume.name   // Name is needed for sorting and detecting touches.

    setupNodes(with: size)
    becomesUnselected()
  }

  private func setPriceText() { // Updates the color and text of price labels

    func playerCanAfford() {
      priceNode.text = "\(costume.price)"
      priceNode.fontColor = .white
    }

    func playerCantAfford() {
      priceNode.text = "\(costume.price)"
      priceNode.fontColor = .red
    }

    func playerOwns() {
      priceNode.text = ""
      priceNode.fontColor = .white
    }

    if player.hasCostume(self.costume)         { playerOwns()       }
    else if player.coins < self.costume.price  { playerCantAfford() }
    else if player.coins >= self.costume.price { playerCanAfford()  }
    else                                       { fatalError()       }
  }

  func becomesSelected() {    // For animation / sound purposes (could also just be handled by the ShopScene).
    backgroundNode.run(.fadeAlpha(to: 0.75, duration: 0.25))
    setPriceText()
    // insert sound if desired.
  }

  func becomesUnselected() {
    backgroundNode.run(.fadeAlpha(to: 0, duration: 0.10))
    setPriceText()
    // insert sound if desired.
  }

  required init?(coder aDecoder: NSCoder) { fatalError() }

  deinit { print("costumenode: if you don't see this then you have a retain cycle") }
};
</code>```

Finally we have ShopScene, which is the behemoth file. It handles the data and logic for not only showing UI elements, but also for updating the Shop and Player models.

```<code>import SpriteKit

// Helpers:
extension SKNode {
  func addChildren(_ nodes: [SKNode]) { for node in nodes { addChild(node) } }

  func addChildrenBehind(_ nodes: [SKNode]) { for node in nodes {
    node.zPosition -= 2
    addChild(node)
    }
  }
}
 func halfHeight(_ node: SKNode) -> CGFloat { return node.frame.size.height/2 }
 func halfWidth (_ node: SKNode) -> CGFloat { return node.frame.size.width/2 }

// MARK: -
/// The scene in which we can interact with our shop and player:
class ShopScene: SKScene {

  lazy private(set) var shop: Shop = { return Shop(shopScene: self) }()

  let previousGameScene: GameScene

  var player: Player { return self.previousGameScene.player }    // The player is actually still in the other scene, not this one.

  private var costumeNodes = [CostumeNode]()                   // All costume textures will be node-ified here.

  lazy private(set) var selectedNode: CostumeNode? = {
    return self.costumeNodes.first!
  }()

  private let
  buyNode  = SKLabelNode(fontNamed: "Chalkduster"),
  coinNode = SKLabelNode(fontNamed: "Chalkduster"),
  exitNode = SKLabelNode(fontNamed: "Chalkduster")

  // MARK: - Node setup:
  private func setUpNodes() {

    buyNode.text = "Buy Costume"
    buyNode.name = "buynode"
    buyNode.position.y = frame.minY + halfHeight(buyNode)

    coinNode.text = "Coins: \(player.coins)"
    coinNode.name = "coinnode"
    coinNode.position = CGPoint(x: frame.minX + halfWidth(coinNode), y: frame.minY + halfHeight(coinNode))

    exitNode.text = "Leave Shop"
    exitNode.name = "exitnode"
    exitNode.position.y = frame.maxY - buyNode.frame.height

    setupCostumeNodes: do {
      guard Costume.allCostumes.count > 1 else {
        fatalError("must have at least two costumes (for while loop)")
      }
      for costume in Costume.allCostumes {
        costumeNodes.append(CostumeNode(costume: costume, player: player))
      }
      guard costumeNodes.count == Costume.allCostumes.count else {
        fatalError("duplicate nodes found, or nodes are missing")
      }

      let offset = CGFloat(150)

      func findStartingPosition(offset: CGFloat, yPos: CGFloat) -> CGPoint {   // Find the correct position to have all costumes centered on screen.
        let
        count = CGFloat(costumeNodes.count),
        totalOffsets = (count - 1) * offset,
        textureWidth = Costume.list.gray.texture.size().width,                 // All textures must be same width for centering to work.
        totalWidth = (textureWidth * count) + totalOffsets

        let measurementNode = SKShapeNode(rectOf: CGSize(width: totalWidth, height: 0))

        return CGPoint(x: measurementNode.frame.minX + textureWidth/2, y: yPos)
      }

      costumeNodes.first!.position = findStartingPosition(offset: offset, yPos: self.frame.midY)

      var counter = 1
      let finalIndex = costumeNodes.count - 1
      // Place nodes from left to right:
      while counter <= finalIndex {
        let thisNode = costumeNodes[counter]
        let prevNode = costumeNodes[counter - 1]

        thisNode.position.x = prevNode.frame.maxX + halfWidth(thisNode) + offset
        counter += 1
      }
    }

    addChildren(costumeNodes)
    addChildren([buyNode, coinNode, exitNode])
  }

  // MARK: - Init:
  init(previousGameScene: GameScene) {
    self.previousGameScene = previousGameScene
    super.init(size: previousGameScene.size)
  }

  required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented")}

  deinit { print("shopscene: if you don't see this message when exiting shop then you have a retain cycle") }

  // MARK: - Game loop:
  override func didMove(to view: SKView) {
    anchorPoint = CGPoint(x: 0.5, y: 0.5)
    setUpNodes()

    select(costumeNodes.first!)                           // Default selection.
    for node in costumeNodes {
      if node.costume == player.costume { select(node) }
    }
  }

  // MARK: - Touch / Click handling:
  private func unselect(_ costumeNode: CostumeNode) {
    selectedNode = nil
    costumeNode.becomesUnselected()
  }

  private func select(_ costumeNode: CostumeNode) {
    unselect(selectedNode!)
    selectedNode = costumeNode
    costumeNode.becomesSelected()

    if player.hasCostume(costumeNode.costume) {      // Wear selected costume if owned.
      player.costume = costumeNode.costume
      buyNode.text = "Bought Costume"
      buyNode.alpha = 1
    }

    else if player.coins < costumeNode.costume.price { // Can't afford costume.
      buyNode.text = "Buy Costume"
      buyNode.alpha = 0.5
    }

    else {                                            // Player can buy costume.
      buyNode.text = "Buy Costume"
      buyNode.alpha = 1
      }
  }

  // I'm choosing to have the buttons activated by searching for name here. You can also
  // subclass a node and have them do actions on their own when clicked.
  override func mouseDown(with event: NSEvent) {

    guard let selectedNode = selectedNode else { fatalError() }
    let location    = event.location(in: self)
    let clickedNode = atPoint(location)

    switch clickedNode {

      // Clicked empty space:
      case is ShopScene:
        return

      // Clicked Buy / Leave:
      case is SKLabelNode:
        if clickedNode.name == "exitnode" { view!.presentScene(previousGameScene) }

        if clickedNode.name == "buynode"  {
          // guard let shop = shop else { fatalError("where did the shop go?") }
          if shop.canSellCostume(selectedNode.costume) {
            shop.sellCostume(selectedNode.costume)
            coinNode.text = "Coins: \(player.coins)"
            buyNode.text = "Bought"
          }
        }

      // Clicked a costume:
      case let clickedCostume as CostumeNode:
        for node in costumeNodes {
          if node.name == clickedCostume.name {
            select(clickedCostume)
          }
        }

      default: ()
      }
  }
};
</code>```

There's a lot to digest here, but pretty much everything happens in mouseDown() (or touchesBegan for iOS). I had no need for update() or other every-frame methods.

So how did I make this? The first step was planning, and I knew there were several design decisions to make (which may not have been the best ones).

I knew that I needed a certain set of data for my player and shop inventory, and that those two things would also need UI elements.

I chose to combine the data + UI for Player by making it a Sprite subclass.

For the shop, I knew that the data and UI elements would be pretty intense, so I separated them (Shop.swift handling the inventory, Costume.swift being a blueprint, and CostumeNode.swift handling most of the UI)

Then, I needed to link the data to the UI elements, which meant that I needed a lot of logic, so I decided to make a whole new scene to handle logic pertaining just to entering and interacting with the shop (it handles some graphics stuff too).

This all works together like this:

Player has a costume and coins

GameScene is where you collect new coins (and levels)

ShopScene handles most of the logic for determining which UI elements to display, while CostumeNode has the functions for animating the UI.

ShopScene also provides the logic for updating the Player's texture (costume) and coins through Shop.

Shop just manages the player inventory, and has the data with which to populate more CostumeNodes

When you are done with the shop, your GameScene instance is immediately resumed where you left off prior to entering

So the question you may have is, "how do I use this in my game??"

Well, you aren't going to be able to just copy and paste it. A lot of refactoring will likely be needed. The takeaway here is to learn the basic system of the different types of data, logic, and actions that you will need to create, present, and interact with a shop.

Here is the github again:
https://github.com/fluidityt/ShopScene

Title: SpriteKit Shop Scene in game

Body:
This is a multi-step project that took me about 500 loc (more without using .SKS) Here is the link to github finished project: https://github.com/fluidityt/ShopScene

Note, I am using a macOS SpriteKit project because it launches much faster on my computer. Simply change mouseDown() to touchesBegan() to get this to run on iOS.

First edit your GameScene.sks to look like this: (saves a bunch of time coding labels)

Make sure that you name everything EXACTLY as we need this to detect touch:

"entershop", "getcoins", "coinlabel", "levellabel"

This is the main "gameplay" scene and as you click coins++ you get levels and can move around. Clicking the shop will enter the shop.

Here is our GameScene.swift which matches this SKS:

import SpriteKit

class GameScene: SKScene {

  let player = Player(costume: Costume.defaultCostume)

  lazy var enterNode:  SKLabelNode = { return (self.childNode(withName: "entershop")  as! SKLabelNode) }()
  lazy var coinNode:   SKLabelNode = { return (self.childNode(withName: "getcoins" )  as! SKLabelNode) }()
  lazy var coinLabel:  SKLabelNode = { return (self.childNode(withName: "coinlabel")  as! SKLabelNode) }()
  lazy var levelLabel: SKLabelNode = { return (self.childNode(withName: "levellabel") as! SKLabelNode) }()

  override func didMove(to view: SKView) {
    player.name = "player"
    if player.scene == nil { addChild(player) }
  }

  override func mouseDown(with event: NSEvent) {

    let location = event.location(in: self)

    if let name = atPoint(location).name {

      switch name {

      case "entershop": view!.presentScene(ShopScene(previousGameScene: self))

      case "getcoins":  player.getCoins(1)

      default: ()
      }
    }

    else {
      player.run(.move(to: location, duration: 1))
    }
  }

  override func update(_ currentTime: TimeInterval) {

    func levelUp(_ level: Int) {
      player.levelsCompleted = level
      levelLabel.text = "Level: \(player.levelsCompleted)"
    }

    switch player.coins {
      case 10: levelUp(2)
      case 20: levelUp(3)
      case 30: levelUp(4)
      default: ()
    }
  }
};

Here you can see that we have a few other things going on not yet introduced: Player and Costume

Player is a spritenode subclass (it doubles as a data model and a UI element). Our player is just a colored square that gets moved around when you click the screen

The player wears something of Costume type, which is just a model that keeps track of data such as price, name, and the texture for the player to display.

Here is Costume.swift:

import SpriteKit

/// This is just a test method should be deleted when you have actual texture assets:
private func makeTestTexture() -> (SKTexture, SKTexture, SKTexture, SKTexture) {

  func texit(_ sprite: SKSpriteNode) -> SKTexture { return SKView().texture(from: sprite)! }
  let size = CGSize(width: 50, height: 50)

  return (
    texit(SKSpriteNode(color: .gray,  size: size)),
    texit(SKSpriteNode(color: .red,   size: size)),
    texit(SKSpriteNode(color: .blue,  size: size)),
    texit(SKSpriteNode(color: .green, size: size))
  )
}

/// The items that are for sale in our shop:
struct Costume {

  static var allCostumes: [Costume] = []

  let name:    String
  let texture: SKTexture
  let price:   Int

  init(name: String, texture: SKTexture, price: Int) { self.name = name; self.texture = texture; self.price = price
    // This init simply adds all costumes to a master list for easy sorting later on.
    Costume.allCostumes.append(self)
  }

  private static let (tex1, tex2, tex3, tex4) = makeTestTexture()  // Just a test needed to be deleted when you have actual assets.

  static let list = (
    // Hard-code any new costumes you create here (this is a "master list" of costumes)
    // (make sure all of your costumes have a unique name, or the program will not work properly)
    gray:  Costume(name: "Gray Shirt",  texture: tex1 /*SKTexture(imageNamed: "grayshirt")*/,  price:  0),
    red:   Costume(name: "Red Shirt",   texture: tex2 /*SKTexture(imageNamed: "redshirt")*/,   price: 5),
    blue:  Costume(name: "Blue Shirt",  texture: tex3 /*SKTexture(imageNamed: "blueshirt")*/,  price: 25),
    green: Costume(name: "Green Shirt", texture: tex4 /*SKTexture(imageNamed: "greenshirt")*/, price: 50)
  )

  static let defaultCostume = list.gray
};

func == (lhs: Costume, rhs: Costume) -> Bool {
  // The reason why you need unique names:
  if lhs.name == rhs.name { return true }
  else { return false }
}

The design of this struct is twofold.. first is to be a blueprint for a Costume object (which holds the name, price, and texture of a costume), and second it serves as a repository for all of your costumes via a hard-coded static master list property.

The function at the top makeTestTextures() is just an example for this project. I did this just so that way you can copy and paste instead of having to download image files to use.

Here is the Player.swift, which can wear the costumes in the list:

final class Player: SKSpriteNode {

  var coins = 0
  var costume: Costume
  var levelsCompleted = 0

  var ownedCostumes: [Costume] = [Costume.list.gray]      // FIXME: This should be a Set, but too lazy to do Hashable.

  init(costume: Costume) {
    self.costume = costume
    super.init(texture: costume.texture, color: .clear, size: costume.texture.size())
  }

  func getCoins(_ amount: Int) {
    guard let scene = self.scene as? GameScene else {     // This is very specific code just for this example.
      fatalError("only call this func after scene has been set up")
    }

    coins += amount
    scene.coinLabel.text = "Coins: \(coins)"
  }

  func loseCoins(_ amount: Int) {
    guard let scene = self.scene as? GameScene else {     // This is very specific code just for this example.
      fatalError("only call this func after scene has been set up")
    }

    coins -= amount
    scene.coinLabel.text = "Coins: \(coins)"
  }

  func hasCostume(_ costume: Costume) -> Bool {
    if ownedCostumes.contains(where: {$0.name == costume.name}) { return true }
    else { return false }
  }

  func getCostume(_ costume: Costume) {
    if hasCostume(costume) { fatalError("trying to get costume already owned") }
    else { ownedCostumes.append(costume) }
  }

  func wearCostume(_ costume: Costume) {
    guard hasCostume(costume) else { fatalError("trying to wear a costume you don't own") }
    self.costume = costume
    self.texture = costume.texture
  }

  required init?(coder aDecoder: NSCoder) { fatalError() }
};

Player has a lot of functions, but they all could be handled elsewhere in the code. I just went for this design decision, but don't feel like you need to load up your classes with 2 line methods.

Now we are getting to the more nitty-gritty stuff, since we have set up our:

Base scene

Costume list

Player object

The last two things we really need are:
1. A shop model to keep track of inventory
2. A shop scene to display inventory, UI elements, and handle the logic of whether or not you can buy items

Here is Shop.swift:

/// Our model class to be used inside of our ShopScene:
final class Shop {

  weak private(set) var scene: ShopScene!     // The scene in which this shop will be called from.

  var player: Player { return scene.player }

  var availableCostumes: [Costume] = [Costume.list.red, Costume.list.blue]   // (The green shirt wont become available until the player has cleared 2 levels).

  // var soldCostumes: [Costume] = [Costume.defaultCostume] // Implement something with this if you want to exclude previously bought items from the store.

  func canSellCostume(_ costume: Costume) -> Bool {
    if player.coins < costume.price                { return false }
    else if player.hasCostume(costume)             { return false }
    else if player.costume == costume              { return false }
    else                                           { return true  }
  }

  /// Only call this after checking canBuyCostume(), or you likely will have errors:
  func sellCostume(_ costume: Costume) {
    player.loseCoins(costume.price)
    player.getCostume(costume)
    player.wearCostume(costume)
  }

  func newCostumeBecomesAvailable(_ costume: Costume) {
    if availableCostumes.contains(where: {$0.name == costume.name}) /*|| soldCostumes.contains(costume)*/ {
      fatalError("trying to add a costume that is already available (or sold!)")
    }
    else { availableCostumes.append(costume) }
  }

  init(shopScene: ShopScene) {
    self.scene = shopScene
  }

  deinit { print("shop: if you don't see this message when exiting shop then you have a retain cycle") }
};

The idea was to have the fourth costume only be available at a certain level, but I've run out of time to implement this feature, but most of the supporting methods are there (you just need to implement the logic).

Also, Shop can pretty much just be a struct, but I feel that it's more flexible as a class for now.

Now, before jumping into ShopScene, our biggest file, let me tell you about a couple of design decisions.

First, I'm using node.name to handle touches / clicks. This lets me use the .SKS and the regular SKNode types quickly and easily. Normally, I like to subclass SKNodes and then override their own touchesBegan method to handle clicks. You can do it either way.

Now, in ShopScene you have buttons for "buy", "exit" which I have used as just regular SKLabelNodes; but for the actual nodes that display the costume, I have created a subclass called CostumeNode.

I made CostumeNode so that way it could handle nodes for displaying the costume's name, price, and doing some animations. CostumeNode is just a visual element (unlike Player).

Here is CostumeNode.swift:

/// Just a UI representation, does not manipulate any models.
final class CostumeNode: SKSpriteNode {

  let costume:   Costume

  weak private(set) var player: Player!

  private(set) var
  backgroundNode = SKSpriteNode(),
  nameNode       = SKLabelNode(),
  priceNode      = SKLabelNode()

  private func label(text: String, size: CGSize) -> SKLabelNode {
    let label = SKLabelNode(text: text)
    label.fontName = "Chalkduster"
    // FIXME: deform label to fit size and offset
    return label
  }

  init(costume: Costume, player: Player) {

     func setupNodes(with size: CGSize) {

      let circle = SKShapeNode(circleOfRadius: size.width)
      circle.fillColor = .yellow
      let bkg = SKSpriteNode(texture: SKView().texture(from: circle))
      bkg.zPosition -= 1

      let name = label(text: "\(costume.name)", size: size)
      name.position.y = frame.maxY + name.frame.size.height

      let price = label(text: "\(costume.price)", size: size)
      price.position.y = frame.minY - price.frame.size.height

      addChildrenBehind([bkg, name, price])
      (backgroundNode, nameNode, priceNode) = (bkg, name, price)
    }

    self.player = player
    self.costume = costume

    let size = costume.texture.size()
    super.init(texture: costume.texture, color: .clear, size: size)

    name = costume.name   // Name is needed for sorting and detecting touches.

    setupNodes(with: size)
    becomesUnselected()
  }

  private func setPriceText() { // Updates the color and text of price labels

    func playerCanAfford() {
      priceNode.text = "\(costume.price)"
      priceNode.fontColor = .white
    }

    func playerCantAfford() {
      priceNode.text = "\(costume.price)"
      priceNode.fontColor = .red
    }

    func playerOwns() {
      priceNode.text = ""
      priceNode.fontColor = .white
    }

    if player.hasCostume(self.costume)         { playerOwns()       }
    else if player.coins < self.costume.price  { playerCantAfford() }
    else if player.coins >= self.costume.price { playerCanAfford()  }
    else                                       { fatalError()       }
  }

  func becomesSelected() {    // For animation / sound purposes (could also just be handled by the ShopScene).
    backgroundNode.run(.fadeAlpha(to: 0.75, duration: 0.25))
    setPriceText()
    // insert sound if desired.
  }

  func becomesUnselected() {
    backgroundNode.run(.fadeAlpha(to: 0, duration: 0.10))
    setPriceText()
    // insert sound if desired.
  }

  required init?(coder aDecoder: NSCoder) { fatalError() }

  deinit { print("costumenode: if you don't see this then you have a retain cycle") }
};

Finally we have ShopScene, which is the behemoth file. It handles the data and logic for not only showing UI elements, but also for updating the Shop and Player models.

import SpriteKit

// Helpers:
extension SKNode {
  func addChildren(_ nodes: [SKNode]) { for node in nodes { addChild(node) } }

  func addChildrenBehind(_ nodes: [SKNode]) { for node in nodes {
    node.zPosition -= 2
    addChild(node)
    }
  }
}
 func halfHeight(_ node: SKNode) -> CGFloat { return node.frame.size.height/2 }
 func halfWidth (_ node: SKNode) -> CGFloat { return node.frame.size.width/2 }

// MARK: -
/// The scene in which we can interact with our shop and player:
class ShopScene: SKScene {

  lazy private(set) var shop: Shop = { return Shop(shopScene: self) }()

  let previousGameScene: GameScene

  var player: Player { return self.previousGameScene.player }    // The player is actually still in the other scene, not this one.

  private var costumeNodes = [CostumeNode]()                   // All costume textures will be node-ified here.

  lazy private(set) var selectedNode: CostumeNode? = {
    return self.costumeNodes.first!
  }()

  private let
  buyNode  = SKLabelNode(fontNamed: "Chalkduster"),
  coinNode = SKLabelNode(fontNamed: "Chalkduster"),
  exitNode = SKLabelNode(fontNamed: "Chalkduster")

  // MARK: - Node setup:
  private func setUpNodes() {

    buyNode.text = "Buy Costume"
    buyNode.name = "buynode"
    buyNode.position.y = frame.minY + halfHeight(buyNode)

    coinNode.text = "Coins: \(player.coins)"
    coinNode.name = "coinnode"
    coinNode.position = CGPoint(x: frame.minX + halfWidth(coinNode), y: frame.minY + halfHeight(coinNode))

    exitNode.text = "Leave Shop"
    exitNode.name = "exitnode"
    exitNode.position.y = frame.maxY - buyNode.frame.height

    setupCostumeNodes: do {
      guard Costume.allCostumes.count > 1 else {
        fatalError("must have at least two costumes (for while loop)")
      }
      for costume in Costume.allCostumes {
        costumeNodes.append(CostumeNode(costume: costume, player: player))
      }
      guard costumeNodes.count == Costume.allCostumes.count else {
        fatalError("duplicate nodes found, or nodes are missing")
      }

      let offset = CGFloat(150)

      func findStartingPosition(offset: CGFloat, yPos: CGFloat) -> CGPoint {   // Find the correct position to have all costumes centered on screen.
        let
        count = CGFloat(costumeNodes.count),
        totalOffsets = (count - 1) * offset,
        textureWidth = Costume.list.gray.texture.size().width,                 // All textures must be same width for centering to work.
        totalWidth = (textureWidth * count) + totalOffsets

        let measurementNode = SKShapeNode(rectOf: CGSize(width: totalWidth, height: 0))

        return CGPoint(x: measurementNode.frame.minX + textureWidth/2, y: yPos)
      }

      costumeNodes.first!.position = findStartingPosition(offset: offset, yPos: self.frame.midY)

      var counter = 1
      let finalIndex = costumeNodes.count - 1
      // Place nodes from left to right:
      while counter <= finalIndex {
        let thisNode = costumeNodes[counter]
        let prevNode = costumeNodes[counter - 1]

        thisNode.position.x = prevNode.frame.maxX + halfWidth(thisNode) + offset
        counter += 1
      }
    }

    addChildren(costumeNodes)
    addChildren([buyNode, coinNode, exitNode])
  }

  // MARK: - Init:
  init(previousGameScene: GameScene) {
    self.previousGameScene = previousGameScene
    super.init(size: previousGameScene.size)
  }

  required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented")}

  deinit { print("shopscene: if you don't see this message when exiting shop then you have a retain cycle") }

  // MARK: - Game loop:
  override func didMove(to view: SKView) {
    anchorPoint = CGPoint(x: 0.5, y: 0.5)
    setUpNodes()

    select(costumeNodes.first!)                           // Default selection.
    for node in costumeNodes {
      if node.costume == player.costume { select(node) }
    }
  }

  // MARK: - Touch / Click handling:
  private func unselect(_ costumeNode: CostumeNode) {
    selectedNode = nil
    costumeNode.becomesUnselected()
  }

  private func select(_ costumeNode: CostumeNode) {
    unselect(selectedNode!)
    selectedNode = costumeNode
    costumeNode.becomesSelected()

    if player.hasCostume(costumeNode.costume) {      // Wear selected costume if owned.
      player.costume = costumeNode.costume
      buyNode.text = "Bought Costume"
      buyNode.alpha = 1
    }

    else if player.coins < costumeNode.costume.price { // Can't afford costume.
      buyNode.text = "Buy Costume"
      buyNode.alpha = 0.5
    }

    else {                                            // Player can buy costume.
      buyNode.text = "Buy Costume"
      buyNode.alpha = 1
      }
  }

  // I'm choosing to have the buttons activated by searching for name here. You can also
  // subclass a node and have them do actions on their own when clicked.
  override func mouseDown(with event: NSEvent) {

    guard let selectedNode = selectedNode else { fatalError() }
    let location    = event.location(in: self)
    let clickedNode = atPoint(location)

    switch clickedNode {

      // Clicked empty space:
      case is ShopScene:
        return

      // Clicked Buy / Leave:
      case is SKLabelNode:
        if clickedNode.name == "exitnode" { view!.presentScene(previousGameScene) }

        if clickedNode.name == "buynode"  {
          // guard let shop = shop else { fatalError("where did the shop go?") }
          if shop.canSellCostume(selectedNode.costume) {
            shop.sellCostume(selectedNode.costume)
            coinNode.text = "Coins: \(player.coins)"
            buyNode.text = "Bought"
          }
        }

      // Clicked a costume:
      case let clickedCostume as CostumeNode:
        for node in costumeNodes {
          if node.name == clickedCostume.name {
            select(clickedCostume)
          }
        }

      default: ()
      }
  }
};

There's a lot to digest here, but pretty much everything happens in mouseDown() (or touchesBegan for iOS). I had no need for update() or other every-frame methods.

So how did I make this? The first step was planning, and I knew there were several design decisions to make (which may not have been the best ones).

I knew that I needed a certain set of data for my player and shop inventory, and that those two things would also need UI elements.

I chose to combine the data + UI for Player by making it a Sprite subclass.

For the shop, I knew that the data and UI elements would be pretty intense, so I separated them (Shop.swift handling the inventory, Costume.swift being a blueprint, and CostumeNode.swift handling most of the UI)

Then, I needed to link the data to the UI elements, which meant that I needed a lot of logic, so I decided to make a whole new scene to handle logic pertaining just to entering and interacting with the shop (it handles some graphics stuff too).

This all works together like this:

Player has a costume and coins

GameScene is where you collect new coins (and levels)

ShopScene handles most of the logic for determining which UI elements to display, while CostumeNode has the functions for animating the UI.

ShopScene also provides the logic for updating the Player's texture (costume) and coins through Shop.

Shop just manages the player inventory, and has the data with which to populate more CostumeNodes

When you are done with the shop, your GameScene instance is immediately resumed where you left off prior to entering

So the question you may have is, "how do I use this in my game??"

Well, you aren't going to be able to just copy and paste it. A lot of refactoring will likely be needed. The takeaway here is to learn the basic system of the different types of data, logic, and actions that you will need to create, present, and interact with a shop.

Here is the github again:
https://github.com/fluidityt/ShopScene


问:
cakephp performances in a big project
I have to develop a big application (an advertising platform, will get more than 10K users and 100K's of listings ) Is it a good idea to choose cakephp for building such a site ?

Thank a  lot

答: That is a horrible idea and wont scale.  Keep it light weight and use memcache. </p>

Title: cakephp performances in a big project


问:
RecyclerView doesn't load data on first launch after Permission Check inside fragment
RecyclerView adapter doesn't load data on first launch after Permission check. I have to re-tap the tab to get the data.

I have already visited/tried these links -

-- RecyclerView doesn't load data in first launch using FirebaseRecyclerAdapter

-- RecyclerView doesn't load items on first start of activity

-- recyclerview not loading adapter values in a fragment

But nothing works yet.
Tried to set global adapter, So I can call notifyDataSetChanged() from onResume(). Still It didn't worked.

Here's code -

onCreateView() -

```<code>@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_third, container, false);

    recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);

    if (checkAndRequestPermissions()) {
        loadSongList();
    }

    return view;
}
</code>```

onRequestPermissionResult -

```<code>loadSongList();  // method
</code>```

loadSongList() -

```<code>private void loadSongList() {
    loadAudio();
    initRecyclerView();
}
</code>```

loadAudio() -

```<code>loadAudio() // accessing data from content resolver
</code>```

initRecyclerView()-

```<code>private void initRecyclerView() {
    if (mAudioList != null && mAudioList.size() > 0) {
        AudioAdapter adapter = new AudioAdapter(mAudioList, getActivity());
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(linearLayoutManager);
        DIviderItemDecoration dividerItemDecoration = new DIviderItemDecoration(getContext(), linearLayoutManager.getOrientation());
        recyclerView.addItemDecoration(dividerItemDecoration);
        recyclerView.setAdapter(adapter);

        RecyclerViewItemClick.addTo(recyclerView).setOnItemClickListener(new RecyclerViewItemClick.OnItemClickListener() {
            @Override
            public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                // life sucks
            }
        });
    }
}
</code>```

EDIT :

loadAudio() -

```<code>private void loadAudio() {
    ContentResolver contentResolver = getActivity().getContentResolver();
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
    String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
    Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);

    if (cursor != null && cursor.getCount() > 0) {
        mAudioList = new ArrayList<>();
        while (cursor.moveToNext()) {
            String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
            String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
            String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
            String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));

            Long albumId = cursor.getLong(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
            Long artWorkId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

            int duration = cursor.getInt(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));

            Uri sArtworkUri = Uri
                    .parse("content://media/external/audio/albumart");
            Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, artWorkId);

            // Save to audioList
            mAudioList.add(new Audio(albumId, data, title, album, artist, albumArtUri, duration));
        }
    }
    if (cursor != null) {
        cursor.close();
    }

}
</code>```

AudioAdapter -

```<code>public class AudioAdapter extends RecyclerView.Adapter<AudioAdapter.CustomViewHolder> {

List<Audio> mList = Collections.emptyList();
Context mContext;

public AudioAdapter(List<Audio> list, Context context) {
    mList = list;
    mContext = context;
}

@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.custom_row, parent, false);
    return new CustomViewHolder(v);
}

@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
    Audio audio = mList.get(position);

    holder.title.setText(audio.getTitle());
    holder.description.setText(audio.getArtist());

    Glide.with(mContext).load(audio.imageId).asBitmap()
            .centerCrop()
            .diskCacheStrategy(DiskCacheStrategy.RESULT)
            .skipMemoryCache(true)
            .placeholder(R.drawable.headset_2)
            .into(holder.imageView);

}

@Override
public int getItemCount() {
    return mList.size();
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

public void insert(int position, Audio list) {
    mList.add(position, list);
    notifyItemChanged(position);
}

public void remove(Audio list) {
    int position = mList.indexOf(list);
    mList.remove(position);
    notifyItemRemoved(position);
}

static class CustomViewHolder extends RecyclerView.ViewHolder {

    CardView cv;
    TextView title;
    TextView description;
    ImageView imageView;

    public CustomViewHolder(View itemView) {
        super(itemView);

        cv = (CardView) itemView.findViewById(R.id.cardView);
        title = (TextView) itemView.findViewById(R.id.playList_name);
        description = (TextView) itemView.findViewById(R.id.album_artist);
        imageView = (ImageView) itemView.findViewById(R.id.imageView1);
    }
}}
</code>```

UDPATE :
checkAndRequestPermission -

```<code>private boolean checkAndRequestPermissions() {
    if (SDK_INT >= Build.VERSION_CODES.M) {
        int permissionReadPhoneState = ContextCompat.checkSelfPermission(getContext(), (Manifest.permission.READ_PHONE_STATE));
        int permissionStorage = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE);
        List<String> listPermissionsNeeded = new ArrayList<>();

        if (permissionReadPhoneState != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
        }

        if (permissionStorage != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }

        if (!listPermissionsNeeded.isEmpty()) {
            requestPermissions(listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
            return false;
        } else {
            return true;
        }
    }
    return false;
}
</code>```

After removing ActivityCompat and just calling requestPermission, the fragment is receiving callback, But now I'm getting error. logcat below -

```<code>java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.ArrayList.get(int)' on a null object reference
                                                                                at com.example.ansh.sharedpreferencessimple.service.MusicService.playSong(MusicService.java:167)
                                                                                at com.example.ansh.sharedpreferencessimple.ThirdFragment$2.onItemClicked(ThirdFragment.java:196)
                                                                                at com.example.ansh.sharedpreferencessimple.helper.RecyclerViewItemClick$1.onClick(RecyclerViewItemClick.java:21)
                                                                                at android.view.View.performClick(View.java:6205)
                                                                                at android.view.View$PerformClick.run(View.java:23653)
                                                                                at android.os.Handler.handleCallback(Handler.java:751)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                at android.os.Looper.loop(Looper.java:154)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:6682)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
</code>```

Any help would be appreciated, Thanks.

答:
Here is the answer of your problem.

Your loadAudio() method fill up your mAudioList which is your arraylist or list whatever it was.

So, main problem is that when you call loadAudio() and then initRecyclerView() inside your initRecyclerView() the mAudioList is still null because at that time your mAudioList is not fill up inside your loadAudio().

So, the problem of your answer is to call initRecyclerView() at the end of loadAudio() function and this will resolve your issue.

For E.g.

```<code>private void loadAudio()
{
     // Get your arraylist of audio and all the stuff
     if (cursor != null)
     {
         cursor.close();
     }
    // Call init function here.
       initRecyclerView();
}
</code>```

Body:
RecyclerView adapter doesn't load data on first launch after Permission check. I have to re-tap the tab to get the data.

I have already visited/tried these links -

-- RecyclerView doesn't load data in first launch using FirebaseRecyclerAdapter

-- RecyclerView doesn't load items on first start of activity

-- recyclerview not loading adapter values in a fragment

But nothing works yet.
Tried to set global adapter, So I can call notifyDataSetChanged() from onResume(). Still It didn't worked.

Here's code -

onCreateView() -

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_third, container, false);

    recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);

    if (checkAndRequestPermissions()) {
        loadSongList();
    }

    return view;
}

onRequestPermissionResult -

loadSongList();  // method

loadSongList() -

private void loadSongList() {
    loadAudio();
    initRecyclerView();
}

loadAudio() -

loadAudio() // accessing data from content resolver

initRecyclerView()-

private void initRecyclerView() {
    if (mAudioList != null && mAudioList.size() > 0) {
        AudioAdapter adapter = new AudioAdapter(mAudioList, getActivity());
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(linearLayoutManager);
        DIviderItemDecoration dividerItemDecoration = new DIviderItemDecoration(getContext(), linearLayoutManager.getOrientation());
        recyclerView.addItemDecoration(dividerItemDecoration);
        recyclerView.setAdapter(adapter);

        RecyclerViewItemClick.addTo(recyclerView).setOnItemClickListener(new RecyclerViewItemClick.OnItemClickListener() {
            @Override
            public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                // life sucks
            }
        });
    }
}

EDIT :

loadAudio() -

private void loadAudio() {
    ContentResolver contentResolver = getActivity().getContentResolver();
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
    String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
    Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);

    if (cursor != null && cursor.getCount() > 0) {
        mAudioList = new ArrayList<>();
        while (cursor.moveToNext()) {
            String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
            String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
            String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
            String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));

            Long albumId = cursor.getLong(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
            Long artWorkId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

            int duration = cursor.getInt(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));

            Uri sArtworkUri = Uri
                    .parse("content://media/external/audio/albumart");
            Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, artWorkId);

            // Save to audioList
            mAudioList.add(new Audio(albumId, data, title, album, artist, albumArtUri, duration));
        }
    }
    if (cursor != null) {
        cursor.close();
    }

}

AudioAdapter -

public class AudioAdapter extends RecyclerView.Adapter<AudioAdapter.CustomViewHolder> {

List<Audio> mList = Collections.emptyList();
Context mContext;

public AudioAdapter(List<Audio> list, Context context) {
    mList = list;
    mContext = context;
}

@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.custom_row, parent, false);
    return new CustomViewHolder(v);
}

@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
    Audio audio = mList.get(position);

    holder.title.setText(audio.getTitle());
    holder.description.setText(audio.getArtist());

    Glide.with(mContext).load(audio.imageId).asBitmap()
            .centerCrop()
            .diskCacheStrategy(DiskCacheStrategy.RESULT)
            .skipMemoryCache(true)
            .placeholder(R.drawable.headset_2)
            .into(holder.imageView);

}

@Override
public int getItemCount() {
    return mList.size();
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

public void insert(int position, Audio list) {
    mList.add(position, list);
    notifyItemChanged(position);
}

public void remove(Audio list) {
    int position = mList.indexOf(list);
    mList.remove(position);
    notifyItemRemoved(position);
}

static class CustomViewHolder extends RecyclerView.ViewHolder {

    CardView cv;
    TextView title;
    TextView description;
    ImageView imageView;

    public CustomViewHolder(View itemView) {
        super(itemView);

        cv = (CardView) itemView.findViewById(R.id.cardView);
        title = (TextView) itemView.findViewById(R.id.playList_name);
        description = (TextView) itemView.findViewById(R.id.album_artist);
        imageView = (ImageView) itemView.findViewById(R.id.imageView1);
    }
}}

UDPATE :
checkAndRequestPermission -

private boolean checkAndRequestPermissions() {
    if (SDK_INT >= Build.VERSION_CODES.M) {
        int permissionReadPhoneState = ContextCompat.checkSelfPermission(getContext(), (Manifest.permission.READ_PHONE_STATE));
        int permissionStorage = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE);
        List<String> listPermissionsNeeded = new ArrayList<>();

        if (permissionReadPhoneState != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
        }

        if (permissionStorage != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }

        if (!listPermissionsNeeded.isEmpty()) {
            requestPermissions(listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
            return false;
        } else {
            return true;
        }
    }
    return false;
}

After removing ActivityCompat and just calling requestPermission, the fragment is receiving callback, But now I'm getting error. logcat below -

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.ArrayList.get(int)' on a null object reference
                                                                                at com.example.ansh.sharedpreferencessimple.service.MusicService.playSong(MusicService.java:167)
                                                                                at com.example.ansh.sharedpreferencessimple.ThirdFragment$2.onItemClicked(ThirdFragment.java:196)
                                                                                at com.example.ansh.sharedpreferencessimple.helper.RecyclerViewItemClick$1.onClick(RecyclerViewItemClick.java:21)
                                                                                at android.view.View.performClick(View.java:6205)
                                                                                at android.view.View$PerformClick.run(View.java:23653)
                                                                                at android.os.Handler.handleCallback(Handler.java:751)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                at android.os.Looper.loop(Looper.java:154)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:6682)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

Any help would be appreciated, Thanks.

Body:
Here is the answer of your problem.

Your loadAudio() method fill up your mAudioList which is your arraylist or list whatever it was.

So, main problem is that when you call loadAudio() and then initRecyclerView() inside your initRecyclerView() the mAudioList is still null because at that time your mAudioList is not fill up inside your loadAudio().

So, the problem of your answer is to call initRecyclerView() at the end of loadAudio() function and this will resolve your issue.

For E.g.

private void loadAudio()
{
     // Get your arraylist of audio and all the stuff
     if (cursor != null)
     {
         cursor.close();
     }
    // Call init function here.
       initRecyclerView();
}


问:
SQL partial date comparison
Which method is most efficient when comparing PARTS of date/datetime values? Example for comparing month of datetimes:

```<code>where insdate =DATEADD(month, DATEDIFF(month, 0, @insdate), 0)
</code>```

or

```<code>where year(insdate)=year(@insdate) and month(insdate)=month(@insdate)
</code>```

I'm using sql server

答:
I disagree with Damien_The_Unbeliever's assertion that you should just use whichever reads cleaner, as there are objective reasons why one approach will be better than the other.  The most pertinent of these is what is known as SARGability.

In essence this refers to whether SQL Server can use your values in the efficient manners it is designed to do, such as utilising indexes.

The differences in your two examples are nicely outlines here.

In short, if you have functions or calculated values on both sides of your equality conditions, SQL Server is definitely going to have to check every single value returned, whereas if you apply the principles of SARGability from the off, even if you don't see any significant benefits immediately you are at least in a better position to realise those benefits later on if required.

Title: SQL partial date comparison

Body:
Which method is most efficient when comparing PARTS of date/datetime values? Example for comparing month of datetimes:

where insdate =DATEADD(month, DATEDIFF(month, 0, @insdate), 0)

or

where year(insdate)=year(@insdate) and month(insdate)=month(@insdate)

I'm using sql server


问:
C# Properties wont save
I want to save settings between two sessions.

I change the value, save it, close the program and its still the old one... WHY?

```<code>int test = Properties.Settings.Default.mode;
        System.Console.WriteLine(test);
        Properties.Settings.Default.mode = 1;
        Properties.Settings.Default.Save();
        test = Properties.Settings.Default.mode;
        System.Console.WriteLine(test);
</code>```

XML:

```<code><userSettings>
    <PyControl.Properties.Settings>
        <setting name="mode" serializeAs="String">
            <value>0</value>
        </setting>
    </PyControl.Properties.Settings>
</userSettings>
</code>```

答:
Probably you were finding the settings file in wrong place? It isn't in your bin folder.

Your application will have a settings folder under
  %userprofile%\appdata\local or %userprofile%\Local
  Settings\Application Data depending on which version of Windows you're
  running, for settings that are user specific. If you store settings
  for all users, then they'll be in the corresponding folder under
  C:\users or C:\Documents and Settings for all user profiles (ex:
  C:\users\public\appdata\local).

Ref: Where are the Properties.Settings.Default stored?

Edit:

Assume if you're NOT using Windows IoT, try ~/.config/{AppName}/user.config? I don't write C# on RPi but above link mentioned this folder. -- If not here, I'm sorry that I can't offer further help :(

Title: C# Properties wont save

Body:
I want to save settings between two sessions.

I change the value, save it, close the program and its still the old one... WHY?

int test = Properties.Settings.Default.mode;
        System.Console.WriteLine(test);
        Properties.Settings.Default.mode = 1;
        Properties.Settings.Default.Save();
        test = Properties.Settings.Default.mode;
        System.Console.WriteLine(test);

XML:

<userSettings>
    <PyControl.Properties.Settings>
        <setting name="mode" serializeAs="String">
            <value>0</value>
        </setting>
    </PyControl.Properties.Settings>
</userSettings>