问:
MediaPlayer URI
```<code>String path = Environment.getExternalStorageDirectory().toString()+"/Music/";
    File directory = new File(path);
    File[] mSongsList = directory.listFiles();

    Uri mUri= Uri.fromFile(mSongsList[0]);
    Log.v("MainActivity",mUri.toString());
    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mMediaPlayer.setDataSource(this, mUri);
    mMediaPlayer.prepare();
    mMediaPlayer.start();
</code>```

I am trying to play the first song in my list but,
i am getting an error on setDataSource.

it say "Unhandled Exception: java.io.IOException"

答:
Place music files(s) under res/raw or any other folder under SD card. We are going to refer the audio file based on the Uri.

Create MediaPlayer object:

```<code>MediaPlayer mPlayer = new MediaPlayer();
</code>```

Locate the audio file:

```<code>Uri myUri1 = Uri.parse("file:///sdcard/Songs/ARR Hits/hosannatamil.mp3");
</code>```

Set the audio stream type of the media player:

```<code>mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
</code>```

Set the data source as a content Uri:

```<code>try {
    mPlayer.setDataSource(getApplicationContext(), myUri1);
} catch (IllegalArgumentException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
} catch (SecurityException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
} catch (IllegalStateException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
    e.printStackTrace();
}
</code>```

Prepare the player for playback, synchronously:

```<code>try {
    mPlayer.prepare();
} catch (IllegalStateException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
}
</code>```

Start the player:

```<code>mPlayer.start();
</code>```

The above information has been taken from the below link:

"https://programmerguru.com/android-tutorial/android-mediaplayer-example-play-from-uri/"

Title: MediaPlayer URI

Body:
String path = Environment.getExternalStorageDirectory().toString()+"/Music/";
    File directory = new File(path);
    File[] mSongsList = directory.listFiles();

    Uri mUri= Uri.fromFile(mSongsList[0]);
    Log.v("MainActivity",mUri.toString());
    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mMediaPlayer.setDataSource(this, mUri);
    mMediaPlayer.prepare();
    mMediaPlayer.start();

I am trying to play the first song in my list but,
i am getting an error on setDataSource.

it say "Unhandled Exception: java.io.IOException"

Body:
Place music files(s) under res/raw or any other folder under SD card. We are going to refer the audio file based on the Uri.

Create MediaPlayer object:

MediaPlayer mPlayer = new MediaPlayer();

Locate the audio file:

Uri myUri1 = Uri.parse("file:///sdcard/Songs/ARR Hits/hosannatamil.mp3");

Set the audio stream type of the media player:

mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

Set the data source as a content Uri:

try {
    mPlayer.setDataSource(getApplicationContext(), myUri1);
} catch (IllegalArgumentException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
} catch (SecurityException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
} catch (IllegalStateException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
    e.printStackTrace();
}

Prepare the player for playback, synchronously:

try {
    mPlayer.prepare();
} catch (IllegalStateException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
    Toast.makeText(getApplicationContext(), "You might not set the URI
    correctly!", Toast.LENGTH_LONG).show();
}

Start the player:

mPlayer.start();

The above information has been taken from the below link:

"https://programmerguru.com/android-tutorial/android-mediaplayer-example-play-from-uri/"


来源: stackexchange

问:
Returning an 3D array from an image file in C programming
I'm currently trying to convert a bitmap image file into a 3D array. The program gets stuck after 3 tries after start = 1. I don't know what's wrong.</p>

```<code>uint8_t*** loadImage(const int size[3], const char url[]){
uint8_t*** output_array;
output_array = malloc((size[0] * size[1]) * 3 * sizeof(uint8_t));
uint8_t byte, RGB = 0, start = 0; int x = 0, y = 0; uint64_t i;
FILE * fp = fopen(url, "rb");
if(fp == NULL){
    perror("Unable to open file!");
    exit(1);
} else {
    for(i = 0; y < size[1]; i++) {
        fread(&byte, sizeof(uint8_t), 1, fp);
        if(start == 1){
            //it ends here in the 3rd rotation after start
            if(RGB < 2){
                output_array[x][y][RGB] = byte;
                RGB++;
            }
            else if (RGB >= 2 && x <= size[0]) {
                x++;
                output_array[x][y][0] = byte;
                RGB = 1;
            }
            else if(RGB >= 2 && x > size[0]){
                y++;
                x = 0;
                RGB = 1;
                output_array[0][y][0] = byte;
            }
        }
        else if(byte == 255 && start == 0){
        //trying to find the starting position, which is always white(255)
            start = 1;
        }
}}
fclose(fp);
return output_array;
}
</code>```

答:
Allocating a Three-Dimensional Array

The statement output_array = malloc((size[0] * size[1]) * 3 * sizeof(uint8_t)); allocates space for size[0] * size[1] * 3 objects of type uint8_t. But output_array does not point to a uint8_t. Its type is uint8_t ***, which means it points to a uint8_t **. Therefore, it would need space for objects of type uint8_t **.

Somebody may have told you that arrays are pointers, and therefore uint8_t *** is a three-dimensional array. That is false. uint8_t *** is a pointer to a pointer to a pointer to a uint8_t (or, if they point to the first of several objects, then a pointer to pointers to pointers to several uint8_t). From your code, it looks like you want a multidimensional array, not a bunch of pointers.

The “easiest” way to do a malloc correctly is to declare a pointer to the thing you want. If you want an array of size[0] arrays of size[1] arrays of 3 arrays of uint8_t, then that would be declared with uint8_t SomeName [size[0]] [size[1]] [3];1, and a pointer to it would be declared with uint8_t (*Pointer) [size[0]] [size[1]] [3];. Then you can allocate space with2:

```<code>uint8_t (*Pointer) [size[0]] [size[1]] [3] = malloc(sizeof *Pointer);
</code>```

Using the thing a pointer points to requires using the * operator, so you would access array elements with (*Pointer)[i][j][k]. However, you can instead make yourself a pointer to the first element of the array with:

```<code>uint8_t (*Pointer) [size[0]] [size[1]] [3] = malloc(sizeof *Pointer);
uint8_t (*output_array) [size[1]] [3] = *Pointer;
</code>```

This first sets Pointer to point to one three-dimensional array. Then *Pointer designates the first array, but it is automatically converted to be a pointer to the first element of that array. (That first element is a two-dimensional array.) This pointer is used to initialize output_array, so output_array points to the first of several two-dimensional arrays. Now you can use output_array much as if it were an array: You can refer to an element as output_array[i][j][k] and return that pointer with return output_array.

However, most people do not use the two lines as I have shown them above. I used that for illustration, to show the single object we want to allocate (a three-dimensional array) and how sizeof calculates its size for you. Most people consolidate these lines into one line that allocates several of the contained arrays, with the same effect:

```<code>uint8_t (*output_array) [size[1]] [3] = malloc(size[0] * sizeof *output_array);
</code>```

Returning the Array

An array defined with uint8_t [size[0]] [size[1]] [3] is a variable length array, because its dimensions are not integer constants as defined by the C standard. Such a type is called a variably modified type, and so is a pointer to it. Functions cannot return variably modified types, so this function cannot return a pointer to the array it created, or even a pointer to its first element, since the subarray is also variably modified.

A workaround is to convert the pointer to void * and return that. First, modify the array declaration to return void *:

```<code>void *loadImage(const int size[3], const char url[])
</code>```

Then, in the caller, put the return value in a pointer of the desired type:

```<code>uint8_t (*output_array) [size[1]] [3] = loadImage(size, url);
</code>```

Another option is to have the caller pass the address of a pointer which they would like to be set to point to the new array (by its first element). The function would change to:

```<code>void loadImage(const int size[3], const char url[],
    uint8_t (**returned_array) [size[1]] [3])
{
    …
    *returned_array = output_array;
}
</code>```

and the caller would change to:

```<code>    uint8_t (*output_array) [size[1]] [3];
    loadImage(size, url, &output_array);
</code>```

Footnotes

1 The spaces between the brackets are just for readability, since there are so many brackets here. You can use that spacing in source code or not, as desired.

2 This requires that your C implementation support variable-length arrays. Those are currently optional in the C standard but are supported by common C compilers, although they might not be when compiling for C++.

ContentLicense: CC BY-SA 4.0

Body:
I'm currently trying to convert a bitmap image file into a 3D array. The program gets stuck after 3 tries after start = 1. I don't know what's wrong.

uint8_t*** loadImage(const int size[3], const char url[]){
uint8_t*** output_array;
output_array = malloc((size[0] * size[1]) * 3 * sizeof(uint8_t));
uint8_t byte, RGB = 0, start = 0; int x = 0, y = 0; uint64_t i;
FILE * fp = fopen(url, "rb");
if(fp == NULL){
    perror("Unable to open file!");
    exit(1);
} else {
    for(i = 0; y < size[1]; i++) {
        fread(&byte, sizeof(uint8_t), 1, fp);
        if(start == 1){
            //it ends here in the 3rd rotation after start
            if(RGB < 2){
                output_array[x][y][RGB] = byte;
                RGB++;
            }
            else if (RGB >= 2 && x <= size[0]) {
                x++;
                output_array[x][y][0] = byte;
                RGB = 1;
            }
            else if(RGB >= 2 && x > size[0]){
                y++;
                x = 0;
                RGB = 1;
                output_array[0][y][0] = byte;
            }
        }
        else if(byte == 255 && start == 0){
        //trying to find the starting position, which is always white(255)
            start = 1;
        }
}}
fclose(fp);
return output_array;
}

Body:
Allocating a Three-Dimensional Array

The statement output_array = malloc((size[0] * size[1]) * 3 * sizeof(uint8_t)); allocates space for size[0] * size[1] * 3 objects of type uint8_t. But output_array does not point to a uint8_t. Its type is uint8_t ***, which means it points to a uint8_t **. Therefore, it would need space for objects of type uint8_t **.

Somebody may have told you that arrays are pointers, and therefore uint8_t *** is a three-dimensional array. That is false. uint8_t *** is a pointer to a pointer to a pointer to a uint8_t (or, if they point to the first of several objects, then a pointer to pointers to pointers to several uint8_t). From your code, it looks like you want a multidimensional array, not a bunch of pointers.

The “easiest” way to do a malloc correctly is to declare a pointer to the thing you want. If you want an array of size[0] arrays of size[1] arrays of 3 arrays of uint8_t, then that would be declared with uint8_t SomeName [size[0]] [size[1]] [3];1, and a pointer to it would be declared with uint8_t (*Pointer) [size[0]] [size[1]] [3];. Then you can allocate space with2:

uint8_t (*Pointer) [size[0]] [size[1]] [3] = malloc(sizeof *Pointer);

Using the thing a pointer points to requires using the * operator, so you would access array elements with (*Pointer)[i][j][k]. However, you can instead make yourself a pointer to the first element of the array with:

uint8_t (*Pointer) [size[0]] [size[1]] [3] = malloc(sizeof *Pointer);
uint8_t (*output_array) [size[1]] [3] = *Pointer;

This first sets Pointer to point to one three-dimensional array. Then *Pointer designates the first array, but it is automatically converted to be a pointer to the first element of that array. (That first element is a two-dimensional array.) This pointer is used to initialize output_array, so output_array points to the first of several two-dimensional arrays. Now you can use output_array much as if it were an array: You can refer to an element as output_array[i][j][k] and return that pointer with return output_array.

However, most people do not use the two lines as I have shown them above. I used that for illustration, to show the single object we want to allocate (a three-dimensional array) and how sizeof calculates its size for you. Most people consolidate these lines into one line that allocates several of the contained arrays, with the same effect:

uint8_t (*output_array) [size[1]] [3] = malloc(size[0] * sizeof *output_array);

Returning the Array

An array defined with uint8_t [size[0]] [size[1]] [3] is a variable length array, because its dimensions are not integer constants as defined by the C standard. Such a type is called a variably modified type, and so is a pointer to it. Functions cannot return variably modified types, so this function cannot return a pointer to the array it created, or even a pointer to its first element, since the subarray is also variably modified.

A workaround is to convert the pointer to void * and return that. First, modify the array declaration to return void *:

void *loadImage(const int size[3], const char url[])

Then, in the caller, put the return value in a pointer of the desired type:

uint8_t (*output_array) [size[1]] [3] = loadImage(size, url);

Another option is to have the caller pass the address of a pointer which they would like to be set to point to the new array (by its first element). The function would change to:

void loadImage(const int size[3], const char url[],
    uint8_t (**returned_array) [size[1]] [3])
{
    …
    *returned_array = output_array;
}

and the caller would change to:

    uint8_t (*output_array) [size[1]] [3];
    loadImage(size, url, &output_array);

Footnotes

1 The spaces between the brackets are just for readability, since there are so many brackets here. You can use that spacing in source code or not, as desired.

2 This requires that your C implementation support variable-length arrays. Those are currently optional in the C standard but are supported by common C compilers, although they might not be when compiling for C++.


问:
SQL - Need help filtering results based on rows
I have a table that looks like this:

```<code>p_id | comp_id
-----+--------
 100 | 1
 100 | 2
 101 | 1
 102 | 1
</code>```

Basically, the p_id can be entered multiple times into the table for as many comp_id as needed.

What I need is to select all the p_ids that have been on comp_id 1 and 2. In the above table, that would mean only p_id == 100 would be returned.

Is there an efficient way to do this?

答:
```<code>select distinct p_id from table a
    inner join table b on a.p_id = b.p_id where a.p_id = 1 and b.p_id = 2
</code>```

this way would probably work but it seems pretty inefficient

ContentLicense: CC BY-SA 3.0

Body:
I have a table that looks like this:

p_id | comp_id
-----+--------
 100 | 1
 100 | 2
 101 | 1
 102 | 1

Basically, the p_id can be entered multiple times into the table for as many comp_id as needed.

What I need is to select all the p_ids that have been on comp_id 1 and 2. In the above table, that would mean only p_id == 100 would be returned.

Is there an efficient way to do this?

Body:
select distinct p_id from table a
    inner join table b on a.p_id = b.p_id where a.p_id = 1 and b.p_id = 2

this way would probably work but it seems pretty inefficient


问:
How can I get green color rectangle if result is True and Red box if result is False in result = (paper == dict_k)?
I am trying to add id text and rectangle with green if result is True and Red if result is false. I am able to get the id in text from live data but I don't get the rectangle with color. Can someone please help me with this issue. When I remove the rectangle block I am able to get id and True/False result</p>

```<code>from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
from PyQt5.QtCore import QTimer
import sys
from PyQt5.QtGui import QPainter, QBrush, QPen
from PyQt5.QtCore import Qt

class MainWindow(QMainWindow):
  # constructor
  def __init__(self):
    QMainWindow.__init__(self)
    # counter
    # self.i = 0
    # add QLabel
    self.top = 150
    self.left = 150
    self.width = 1000
    self.height = 1000
    self.qLbl = QLabel('Not yet initialized')
    self.setCentralWidget(self.qLbl)
    # make QTimer
    self.qTimer = QTimer()
    # set interval to 1 s
    self.qTimer.setInterval(1000) # 1000 ms = 1 s
    # connect timeout signal to signal handler
    # label.setFont(QFont('Arial', 20))
    self.setStyleSheet("QLabel {font: 16pt Arial}")
    self.qTimer.timeout.connect(self.getSensorValue)
    self.qTimer.timeout.connect(self.paintevent)

    # start timer
    self.qTimer.start()

  def getSensorValue(self):
    # self.i += 1
    # print('%d. call of getSensorValue()' % self.i)
    id = 'ID1123'
    t = neo4jconnection(paper_id=id)
    paper = neo4jresultparser(t)
    dict_k = jsonfilereader(paper_id=id)  # probably not need it
    result = (paper == dict_k)
    self.qLbl.setText((id +" "+str( result)))

def paintEvent(self, event):
    painter = QPainter(self)
    painter.setPen(QPen(Qt.green, 5, Qt.SolidLine))
    painter.setBrush(QBrush(Qt.green, Qt.SolidPattern))
    painter.drawRect(40, 40, 400, 200)

qApp = QApplication(sys.argv)
# setup GUI
qWin = MainWindow()
qWin.setGeometry(100, 100, 1000, 1000)
qWin.show()
# run application
sys.exit(qApp.exec_())
</code>```

答:
You should not call paintEvent directly but through the update() or repaint() methods, on the other hand the color must be an attribute of the class that changes according to the value of result and then call update():

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setStyleSheet("QLabel {font: 16pt Arial}")
        self.qLbl = QLabel("Not yet initialized")
        self.setCentralWidget(self.qLbl)

        self.qTimer = QTimer()
        self.qTimer.setInterval(1000)
        self.qTimer.timeout.connect(self.getSensorValue)
        self.qTimer.start()

        self.color = QColor()

    def getSensorValue(self):
        id_ = "ID1123"
        t = neo4jconnection(paper_id=id_)
        paper = neo4jresultparser(t)
        dict_k = jsonfilereader(paper_id=id_)
        result = paper == dict_k
        self.qLbl.setText("{} {}".format(id_, result))
        self.color = QColor("green") if result else QColor("red")
        self.update()

    def paintEvent(self, event):
        if self.color.isValid():
            painter = QPainter(self)
            painter.setPen(QPen(self.color, 5, Qt.SolidLine))
            painter.setBrush(QBrush(self.color, Qt.SolidPattern))
            painter.drawRect(40, 40, 400, 200)
```

Body:
I am trying to add id text and rectangle with green if result is True and Red if result is false. I am able to get the id in text from live data but I don't get the rectangle with color. Can someone please help me with this issue. When I remove the rectangle block I am able to get id and True/False result

from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
from PyQt5.QtCore import QTimer
import sys
from PyQt5.QtGui import QPainter, QBrush, QPen
from PyQt5.QtCore import Qt

class MainWindow(QMainWindow):
  # constructor
  def __init__(self):
    QMainWindow.__init__(self)
    # counter
    # self.i = 0
    # add QLabel
    self.top = 150
    self.left = 150
    self.width = 1000
    self.height = 1000
    self.qLbl = QLabel('Not yet initialized')
    self.setCentralWidget(self.qLbl)
    # make QTimer
    self.qTimer = QTimer()
    # set interval to 1 s
    self.qTimer.setInterval(1000) # 1000 ms = 1 s
    # connect timeout signal to signal handler
    # label.setFont(QFont('Arial', 20))
    self.setStyleSheet("QLabel {font: 16pt Arial}")
    self.qTimer.timeout.connect(self.getSensorValue)
    self.qTimer.timeout.connect(self.paintevent)

    # start timer
    self.qTimer.start()

  def getSensorValue(self):
    # self.i += 1
    # print('%d. call of getSensorValue()' % self.i)
    id = 'ID1123'
    t = neo4jconnection(paper_id=id)
    paper = neo4jresultparser(t)
    dict_k = jsonfilereader(paper_id=id)  # probably not need it
    result = (paper == dict_k)
    self.qLbl.setText((id +" "+str( result)))

def paintEvent(self, event):
    painter = QPainter(self)
    painter.setPen(QPen(Qt.green, 5, Qt.SolidLine))
    painter.setBrush(QBrush(Qt.green, Qt.SolidPattern))
    painter.drawRect(40, 40, 400, 200)

qApp = QApplication(sys.argv)
# setup GUI
qWin = MainWindow()
qWin.setGeometry(100, 100, 1000, 1000)
qWin.show()
# run application
sys.exit(qApp.exec_())


问:
Set a different color to a row of dataframe
In the below code we can pick any pair (name and age) and make the histogram of them:

import pandas as pd
import matplotlib.pyplot as plt

```<code>df = pd.DataFrame({
    'name':['john','mary','peter','jeff','bill','lisa','jose'],
    'age':[23,78,22,19,45,33,20],
    'gender':['M','F','M','M','M','F','M'],
    'state':['california','dc','california','dc','california','texas','texas'],
    'num_children':[2,0,0,3,2,1,4],
    'num_pets':[5,1,0,5,2,2,3]
})
df.plot(kind='bar',x='name',y='age')
plt.show()
</code>```

What I want to do is to make the bar for Lisa in red color, and the rest of them is unchanged.

How to set the color to a certain row?

答:
Looking at the docs of df.plot():

DataFrame.plot(x=None, y=None, kind='line', ax=None, subplots=False,
  sharex=None, sharey=False, layout=None, figsize=None, use_index=True,
  title=None, grid=None, legend=True, style=None, logx=False,
  logy=False, loglog=False, xticks=None, yticks=None, xlim=None,
  ylim=None, rot=None, fontsize=None, colormap=None, table=False,
  yerr=None, xerr=None, secondary_y=False, sort_columns=False,
  **kwds)

We can see that the function takes **kwds (last line of the quote)

Looking further:

[...]
  **kwds : keywords
  Options to pass to matplotlib plotting method

The plotting method you call is plt.bar(), whose documentation says:

```<code>Other Parameters:
    color : scalar or array-like, optional
    The colors of the bar faces.

    edgecolor : scalar or array-like, optional
    The colors of the bar edges.
</code>```

So, you can pass a list or an array of the desired colors to the method, like so:

```<code>color = 7*['blue']
color[-2] = 'red'

df.plot(kind='bar',x='name',y='age', color=color)
plt.show()
</code>```

Body:
In the below code we can pick any pair (name and age) and make the histogram of them:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({
    'name':['john','mary','peter','jeff','bill','lisa','jose'],
    'age':[23,78,22,19,45,33,20],
    'gender':['M','F','M','M','M','F','M'],
    'state':['california','dc','california','dc','california','texas','texas'],
    'num_children':[2,0,0,3,2,1,4],
    'num_pets':[5,1,0,5,2,2,3]
})
df.plot(kind='bar',x='name',y='age')
plt.show()

What I want to do is to make the bar for Lisa in red color, and the rest of them is unchanged.

How to set the color to a certain row?

Body:
Looking at the docs of df.plot():

DataFrame.plot(x=None, y=None, kind='line', ax=None, subplots=False,
  sharex=None, sharey=False, layout=None, figsize=None, use_index=True,
  title=None, grid=None, legend=True, style=None, logx=False,
  logy=False, loglog=False, xticks=None, yticks=None, xlim=None,
  ylim=None, rot=None, fontsize=None, colormap=None, table=False,
  yerr=None, xerr=None, secondary_y=False, sort_columns=False,
  **kwds)

We can see that the function takes **kwds (last line of the quote)

Looking further:

[...]
  **kwds : keywords
  Options to pass to matplotlib plotting method

The plotting method you call is plt.bar(), whose documentation says:

Other Parameters:
    color : scalar or array-like, optional
    The colors of the bar faces.

    edgecolor : scalar or array-like, optional
    The colors of the bar edges.

So, you can pass a list or an array of the desired colors to the method, like so:

color = 7*['blue']
color[-2] = 'red'

df.plot(kind='bar',x='name',y='age', color=color)
plt.show()


问:
matching row values (text) with column names and return value
I am trying to find the column name with the same name as the text in another column called "region", and return the corresponding value. My data "df" looks like something similar to this

```<code>region  A   B   C   D   E   F
H      796  792 844 812 796 776
J      568  564 508 268 320 396
A      820  804 748 528 560 600
X      292  272 260 324 224 200
M      872  812 792 760 668 656
N      100 992  972 880 872 864
C      940  948 952 916 864 880
L      960  956 952 920 900 920
E      980  968 956 940 944 932
F      236  364 460 524 552 616
P      796  792 844 812 796 776
Q      568  564 508 268 320 396
</code>```

And I want to get something that looks like this:

```<code>region  A   B   C   D   E   F
H       NA  NA  NA  NA  NA  NA
J       NA  NA  NA  NA  NA  NA
A       820 NA  NA  NA  NA  NA
X       NA  NA  NA  NA  NA  NA
M       NA  NA  NA  NA  NA  NA
N       NA  NA  NA  NA  NA  NA
C       NA  NA  952 NA  NA  NA
L       NA  NA  NA  NA  NA  NA
E       NA  NA  NA  NA  944 NA
F       NA  NA  NA  NA  NA  616
P       NA  NA  NA  NA  NA  NA
Q       NA  NA  NA  NA  NA  NA
</code>```

To do this, I tried this piece of code from this other questions (Loop that matches row to column names and computes an average of the 3 preceding columns) but it only returns the position, and I would like to get the value as shown in the example above.

apply (df, MARGIN = 1, FUN = function(x, i){
  position <- (which(x[['region']] == colnames(df)))
})

How can I modify the code to get the real value?
Thanks

答:
Since dplyr 1.0.0, you can use cur_column():

```<code>df %>%
 mutate(across(-region, ~ replace(., cur_column() != region, NA_integer_)))

   region   A  B   C  D   E   F
1       H  NA NA  NA NA  NA  NA
2       J  NA NA  NA NA  NA  NA
3       A 820 NA  NA NA  NA  NA
4       X  NA NA  NA NA  NA  NA
5       M  NA NA  NA NA  NA  NA
6       N  NA NA  NA NA  NA  NA
7       C  NA NA 952 NA  NA  NA
8       L  NA NA  NA NA  NA  NA
9       E  NA NA  NA NA 944  NA
10      F  NA NA  NA NA  NA 616
11      P  NA NA  NA NA  NA  NA
12      Q  NA NA  NA NA  NA  NA
</code>```

Arguably not the cleanest dplyr way, but you can also try:

```<code>df %>%
 mutate_at(vars(-1),
           funs(replace(., .*(deparse(substitute(.)) == region) == 0, NA_integer_)))
</code>```

Or adapting the logic from @markus:

```<code>df %>%
 rowwise() %>%
 mutate_at(vars(-1), funs(.[match(region, deparse(substitute(.)))]))
</code>```

And one exotic base R option:

```<code>df[-1] <- sweep(t(apply(df[1], 1, rep, length(df)-1)), 2, FUN = `==`, names(df[-1]))*df[-1]
df[-1] <- replace(df[-1], df[-1] == 0, NA_integer_)
</code>```

Body:
I am trying to find the column name with the same name as the text in another column called "region", and return the corresponding value. My data "df" looks like something similar to this

region  A   B   C   D   E   F
H      796  792 844 812 796 776
J      568  564 508 268 320 396
A      820  804 748 528 560 600
X      292  272 260 324 224 200
M      872  812 792 760 668 656
N      100 992  972 880 872 864
C      940  948 952 916 864 880
L      960  956 952 920 900 920
E      980  968 956 940 944 932
F      236  364 460 524 552 616
P      796  792 844 812 796 776
Q      568  564 508 268 320 396

And I want to get something that looks like this:

region  A   B   C   D   E   F
H       NA  NA  NA  NA  NA  NA
J       NA  NA  NA  NA  NA  NA
A       820 NA  NA  NA  NA  NA
X       NA  NA  NA  NA  NA  NA
M       NA  NA  NA  NA  NA  NA
N       NA  NA  NA  NA  NA  NA
C       NA  NA  952 NA  NA  NA
L       NA  NA  NA  NA  NA  NA
E       NA  NA  NA  NA  944 NA
F       NA  NA  NA  NA  NA  616
P       NA  NA  NA  NA  NA  NA
Q       NA  NA  NA  NA  NA  NA

To do this, I tried this piece of code from this other questions (Loop that matches row to column names and computes an average of the 3 preceding columns) but it only returns the position, and I would like to get the value as shown in the example above.

apply (df, MARGIN = 1, FUN = function(x, i){
  position <- (which(x[['region']] == colnames(df)))
})

How can I modify the code to get the real value?
Thanks

Body:
Since dplyr 1.0.0, you can use cur_column():

df %>%
 mutate(across(-region, ~ replace(., cur_column() != region, NA_integer_)))

   region   A  B   C  D   E   F
1       H  NA NA  NA NA  NA  NA
2       J  NA NA  NA NA  NA  NA
3       A 820 NA  NA NA  NA  NA
4       X  NA NA  NA NA  NA  NA
5       M  NA NA  NA NA  NA  NA
6       N  NA NA  NA NA  NA  NA
7       C  NA NA 952 NA  NA  NA
8       L  NA NA  NA NA  NA  NA
9       E  NA NA  NA NA 944  NA
10      F  NA NA  NA NA  NA 616
11      P  NA NA  NA NA  NA  NA
12      Q  NA NA  NA NA  NA  NA

Arguably not the cleanest dplyr way, but you can also try:

df %>%
 mutate_at(vars(-1),
           funs(replace(., .*(deparse(substitute(.)) == region) == 0, NA_integer_)))

Or adapting the logic from @markus:

df %>%
 rowwise() %>%
 mutate_at(vars(-1), funs(.[match(region, deparse(substitute(.)))]))

And one exotic base R option:

df[-1] <- sweep(t(apply(df[1], 1, rep, length(df)-1)), 2, FUN = `==`, names(df[-1]))*df[-1]
df[-1] <- replace(df[-1], df[-1] == 0, NA_integer_)


问:
Trigger update the rest of the table values once one attribute has been populated
I want to make a trigger that would populate the rest of the values in the table once one attribute has been inserted.

So once a date has been inserted, I need the trigger to fill out the rest of the columns.

```<code>CREATE TABLE dim_date
(
    Date_Id INTEGER
        CONSTRAINT date_id_pk PRIMARY KEY IDENTITY (1,1),
    CalendarDate DATE NOT NULL,
    CalendarYear VARCHAR (20),
    CalendarQuarter VARCHAR (20),
    CalendarMonth VARCHAR (20),
    CalendarMonthNumber SMALLINT,
    CalendarDateNumber SMALLINT,
    CalendarYearNumber SMALLINT,
    CalendarQuarterNumber CHAR(1),
    CalendarWeek SMALLINT,
    CalendarWeekdayNumber Char(1),
    CalendarWeekday VARCHAR (20),
    CalendarWeekNumber SMALLINT,
    CalendarHalf CHAR(1)
);

INSERT INTO dim_date (CalendarDate)
VALUES ('2018-07-26'),
       ('2017-05-02'),
       ('2015-09-10'),
       ('2017-04-23');

CREATE TRIGGER trg_date ON dim_date
FOR INSERT
AS
    UPDATE dim_date
    SET CalendarYear = (SELECT YEAR(CalendarDate) FROM INSERTED)
    WHERE -- not sure how to proceed from here
GO
</code>```

答:
You basically need to use a properly relational, set-based approach - by joining to the Inserted pseudo table, and set the date part information for those newly inserted rows.

Something along the lines of this:

```<code>CREATE TRIGGER trg_date
ON dim_date
FOR INSERT
AS
    UPDATE dd
    SET CalendarYear = YEAR(dd.CalendarDate),
        CalendarQuarter = DATEPART(Quarter, dd.CalendarDate),
        CalendarMonthNumber = MONTH(dd.CalendarDate)
        -- and so on, for all the other DATEPART pieces you need

    FROM dim_date dd
    -- join on the primary key to update all rows that were newly inserted only
    INNER JOIN Inserted i ON dd.Date_Id = i.Date_Id
GO
</code>```

Now you just need to fill in the remaining date parts you need to determine - check the official MS documentation on DATEPART for insights!

Body:
I want to make a trigger that would populate the rest of the values in the table once one attribute has been inserted.

So once a date has been inserted, I need the trigger to fill out the rest of the columns.

CREATE TABLE dim_date
(
    Date_Id INTEGER
        CONSTRAINT date_id_pk PRIMARY KEY IDENTITY (1,1),
    CalendarDate DATE NOT NULL,
    CalendarYear VARCHAR (20),
    CalendarQuarter VARCHAR (20),
    CalendarMonth VARCHAR (20),
    CalendarMonthNumber SMALLINT,
    CalendarDateNumber SMALLINT,
    CalendarYearNumber SMALLINT,
    CalendarQuarterNumber CHAR(1),
    CalendarWeek SMALLINT,
    CalendarWeekdayNumber Char(1),
    CalendarWeekday VARCHAR (20),
    CalendarWeekNumber SMALLINT,
    CalendarHalf CHAR(1)
);

INSERT INTO dim_date (CalendarDate)
VALUES ('2018-07-26'),
       ('2017-05-02'),
       ('2015-09-10'),
       ('2017-04-23');

CREATE TRIGGER trg_date ON dim_date
FOR INSERT
AS
    UPDATE dim_date
    SET CalendarYear = (SELECT YEAR(CalendarDate) FROM INSERTED)
    WHERE -- not sure how to proceed from here
GO

Body:
You basically need to use a properly relational, set-based approach - by joining to the Inserted pseudo table, and set the date part information for those newly inserted rows.

Something along the lines of this:

CREATE TRIGGER trg_date
ON dim_date
FOR INSERT
AS
    UPDATE dd
    SET CalendarYear = YEAR(dd.CalendarDate),
        CalendarQuarter = DATEPART(Quarter, dd.CalendarDate),
        CalendarMonthNumber = MONTH(dd.CalendarDate)
        -- and so on, for all the other DATEPART pieces you need

    FROM dim_date dd
    -- join on the primary key to update all rows that were newly inserted only
    INNER JOIN Inserted i ON dd.Date_Id = i.Date_Id
GO

Now you just need to fill in the remaining date parts you need to determine - check the official MS documentation on DATEPART for insights!


问:
Python: How to convert string entries with only numeric components in a column to integer?
I have a data frame with string type columns that have both character and numeric entries.

Below is an example df:

```<code>A        B
101a5    12222
11111    e2edw2
22222    33333
asxaa    0045
</code>```

I want to turn the entries with only numeric values from string into integer, but keep the rest as string.

What would be the best approach?

Thanks in advance!

答:
Just convert the dataframe to integers and ignore any resulting errors which would return the original string instead.

Can't get much simpler...

```<code>df.astype(int, errors='ignore')

# pandas 1.0.0
>>> df.astype(int, errors='ignore').applymap(type)
               A              B
0  <class 'str'>  <class 'int'>
1  <class 'int'>  <class 'str'>
2  <class 'int'>  <class 'int'>
3  <class 'str'>  <class 'int'>
</code>```

Body:
I have a data frame with string type columns that have both character and numeric entries.

Below is an example df:

A        B
101a5    12222
11111    e2edw2
22222    33333
asxaa    0045

I want to turn the entries with only numeric values from string into integer, but keep the rest as string.

What would be the best approach?

Thanks in advance!

Body:
Just convert the dataframe to integers and ignore any resulting errors which would return the original string instead.

Can't get much simpler...

df.astype(int, errors='ignore')

# pandas 1.0.0
>>> df.astype(int, errors='ignore').applymap(type)
               A              B
0  <class 'str'>  <class 'int'>
1  <class 'int'>  <class 'str'>
2  <class 'int'>  <class 'int'>
3  <class 'str'>  <class 'int'>


问:
How would you design a good search UI?
I want to provide my users with an 'advanced' search engine.
I basically have a lot of search criteria to chose from :

some are very simple/common and will be largely use (ie time period, item id)

some are a bit less mainstream

and some won't be used a lot, but I still want to provide them

Overall, I have around 30+ criteria to chose from

The result is a dataset which I display in a grid.

I've search for inspiration on internet, and even google doesn't seem to have a nice solution for advanced search.

I've designed this kind of tools in the past, and I wasn't really pleased by the result, although the user were eventually able to use it quite effectively.

Do you think the search panel should be visible all the time (ie displayed on top of my result grid) or available in a separate form (which would let me use more place for all the controls)

Do you think it's better to display all the search criteria, or to let the user click on 'advanced' if he wants to see/use more criteria

How would you organize the criteria? by usage frequency, or rather by area (ie. criteria related to user, to location, to time, etc.)

Where should I put the 'Search' button? next to the more common search controls, or at the bottom, or both?

And more generally, do you have tips you want to share on how to design a nice search UI ?
What kind of functionalities do you usually miss in this kind of 'advanced' search engines?

答: Don't think this has been mentioned yet but dont forget that you will also need to initiate the search when the user presses enter in any of the search fields. Probably aware of this already, but worth mentioning anyway.</p>

OwnerDisplayName: Brann

ContentLicense: CC BY-SA 2.5

Title: How would you design a good search UI?

LastEditorDisplayName: onnodb

OwnerDisplayName: willcodejavaforfood


问:
c# stopwatch.startnew() always returns 0
I have this loop that I want to measure the speed of:

```<code>        private static string[] sequentialTest(string[] thisstringlist)
    {
        var watch = Stopwatch.StartNew();

        string[] returnList = new string[2150];
        for (int i = 0; i < thisstringlist.Length; ++i)
        {
            int thisI = i;
            returnList[i] = thisstringlist[i] + "pluuus this";
        }
        int thiss = 0;

        var elapsedMs = watch.ElapsedMilliseconds;
        Console.WriteLine("execution time" + watch.ElapsedMilliseconds);

        return returnList;

    }
</code>```

Should be really simple, the stopwatch should just measure how long this operation takes, but i keeps returning 0

I have also tried inserting thread.sleep(), just to force the code to take some time, but that doesnt work either

答:
As the name suggests, a stopwatch needs to be stopped in order to see all these values, as shown in the documentation as well. So in order to fix this, write watch.Stop(); before var elapsedMs = watch.ElapsedMilliseconds;.

Note: in newer versions of .NET framework stop is not required.

Also, check the docs

Body:
I have this loop that I want to measure the speed of:

        private static string[] sequentialTest(string[] thisstringlist)
    {
        var watch = Stopwatch.StartNew();

        string[] returnList = new string[2150];
        for (int i = 0; i < thisstringlist.Length; ++i)
        {
            int thisI = i;
            returnList[i] = thisstringlist[i] + "pluuus this";
        }
        int thiss = 0;

        var elapsedMs = watch.ElapsedMilliseconds;
        Console.WriteLine("execution time" + watch.ElapsedMilliseconds);

        return returnList;

    }

Should be really simple, the stopwatch should just measure how long this operation takes, but i keeps returning 0

I have also tried inserting thread.sleep(), just to force the code to take some time, but that doesnt work either


问:
using a string in a math equation in Dart
I store various formulas in Postgres and I want to use those formulas in my code. It would look something like this:

```<code>var amount = 100;
var formula = '5/105'; // normally something I would fetch from Postgres
var total = amount * formula; // should return 4.76
</code>```

Is there a way to evaluate the string in this manner?

答:
There are a few packages that can be used to accomplish this:

pub.dev/packages/function_tree

pub.dev/packages/math_expressions

pub.dev/packages/expressions

I used function_tree as follows:

```<code>double amount = 100.55;
String formula = '5/105*.5'; // From Postgres

final tax = amount * formula.interpret();
</code>```

I haven't tried it, but using math_expressions it should look like this:

```<code>double amount = 100.55;
String formula = '5/105*.5'; // From Postgres

Parser p = Parser();
// Context is used to evaluate variables, can be empty in this case.
ContextModel cm = ContextModel();

Expression exp = p.parse(formula) * p.parse(amount.toString());
// or..
//Expression exp = p.parse(formula) * Number(amount);

double result = exp.evaluate(EvaluationType.REAL, cm);

// Result: 2.394047619047619
print('Result: ${result}');
</code>```

Thanks to fkleon for the math_expressions help.

Body:
I store various formulas in Postgres and I want to use those formulas in my code. It would look something like this:

var amount = 100;
var formula = '5/105'; // normally something I would fetch from Postgres
var total = amount * formula; // should return 4.76

Is there a way to evaluate the string in this manner?

Body:
There are a few packages that can be used to accomplish this:

pub.dev/packages/function_tree

pub.dev/packages/math_expressions

pub.dev/packages/expressions

I used function_tree as follows:

double amount = 100.55;
String formula = '5/105*.5'; // From Postgres

final tax = amount * formula.interpret();

I haven't tried it, but using math_expressions it should look like this:

double amount = 100.55;
String formula = '5/105*.5'; // From Postgres

Parser p = Parser();
// Context is used to evaluate variables, can be empty in this case.
ContextModel cm = ContextModel();

Expression exp = p.parse(formula) * p.parse(amount.toString());
// or..
//Expression exp = p.parse(formula) * Number(amount);

double result = exp.evaluate(EvaluationType.REAL, cm);

// Result: 2.394047619047619
print('Result: ${result}');

Thanks to fkleon for the math_expressions help.


问:
How to get rid of Spring Neo4j startup warnings?
I am using Spring Data Neo4j with Springboot, and the application works.

However, I have a raft of warnings on startup that I'd like to get rid of if possible.

```<code>2019-09-08 14:15:20.788  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.fatalEnabled
2019-09-08 14:15:20.789  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.errorEnabled
2019-09-08 14:15:20.790  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.infoEnabled
2019-09-08 14:15:20.790  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.debugEnabled
2019-09-08 14:15:20.790  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.traceEnabled
2019-09-08 14:15:20.791  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.warnEnabled
2019-09-08 14:15:20.796  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.parent
2019-09-08 14:15:20.796  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.environment
2019-09-08 14:15:20.797  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.classLoader
2019-09-08 14:15:20.797  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.displayName
2019-09-08 14:15:20.797  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.startupDate
2019-09-08 14:15:20.798  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.beanDefinitionCount
2019-09-08 14:15:20.798  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.autowireCapableBeanFactory
2019-09-08 14:15:20.798  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.beanDefinitionNames
2019-09-08 14:15:20.799  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.parentBeanFactory
2019-09-08 14:15:20.799  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.id
2019-09-08 14:15:20.799  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.applicationName
2019-09-08 14:15:20.801  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration so treating as simple type for SD Commons
2019-09-08 14:15:20.802  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder so treating as simple type for SD Commons
2019-09-08 14:15:20.805  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class org.springframework.security.config.annotation.web.builders.HttpSecurity so treating as simple type for SD Commons
2019-09-08 14:15:20.850  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class java.util.ArrayList so treating as simple type for SD Commons
2019-09-08 14:15:20.896  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class org.springframework.http.HttpHeaders so treating as simple type for SD Commons
2019-09-08 14:15:20.929  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.core.env.Environment.defaultProfiles
2019-09-08 14:15:20.929  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.core.env.Environment.activeProfiles
2019-09-08 14:15:20.932  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.initParameterNames
2019-09-08 14:15:20.932  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.virtualServerName
2019-09-08 14:15:20.932  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.classLoader
2019-09-08 14:15:20.932  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.filterRegistrations
2019-09-08 14:15:20.933  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.servletNames
2019-09-08 14:15:20.933  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.sessionTrackingModes
2019-09-08 14:15:20.933  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.contextPath
2019-09-08 14:15:20.933  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.defaultSessionTrackingModes
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.majorVersion
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.effectiveMinorVersion
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.sessionCookieConfig
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.effectiveSessionTrackingModes
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.attributeNames
2019-09-08 14:15:20.935  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.serverInfo
2019-09-08 14:15:20.935  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.servletRegistrations
2019-09-08 14:15:20.935  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.jspConfigDescriptor
2019-09-08 14:15:20.935  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.servlets
2019-09-08 14:15:20.936  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.requestCharacterEncoding
2019-09-08 14:15:20.936  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.responseCharacterEncoding
2019-09-08 14:15:20.936  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.sessionTimeout
2019-09-08 14:15:20.936  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.minorVersion
2019-09-08 14:15:20.937  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.servletContextName
2019-09-08 14:15:20.937  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.effectiveMajorVersion
2019-09-08 14:15:20.938  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.FilterConfig.initParameterNames
2019-09-08 14:15:20.938  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.FilterConfig.servletContext
2019-09-08 14:15:20.939  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.FilterConfig.filterName
</code>```

What is making it so unhappy?

答:
Had same problem (SpringBoot 2.2.2 with dependency spring-boot-starter-data-neo4j).  Got rid of the warning and narrowed scanning of entity/model classes by adding both annotations to the main @SpringBootApplication annotated application class:

@EnableNeo4jRepositories("my.project.reposoitory")
@EntityScan("my.project.model")
```

Avoids the need for a separate @Config class / overriding SpringBoot auto config. See the docs.

Update:
Bumped the Spring Boot version to 2.2.4.RELEASE as I was having problems returning any data from my Neo4jRepository declarative methods. Suspect this is tx related, will raise a defect.

Body:
I am using Spring Data Neo4j with Springboot, and the application works.

However, I have a raft of warnings on startup that I'd like to get rid of if possible.

2019-09-08 14:15:20.788  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.fatalEnabled
2019-09-08 14:15:20.789  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.errorEnabled
2019-09-08 14:15:20.790  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.infoEnabled
2019-09-08 14:15:20.790  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.debugEnabled
2019-09-08 14:15:20.790  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.traceEnabled
2019-09-08 14:15:20.791  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.apache.commons.logging.Log.warnEnabled
2019-09-08 14:15:20.796  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.parent
2019-09-08 14:15:20.796  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.environment
2019-09-08 14:15:20.797  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.classLoader
2019-09-08 14:15:20.797  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.displayName
2019-09-08 14:15:20.797  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.startupDate
2019-09-08 14:15:20.798  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.beanDefinitionCount
2019-09-08 14:15:20.798  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.autowireCapableBeanFactory
2019-09-08 14:15:20.798  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.beanDefinitionNames
2019-09-08 14:15:20.799  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.parentBeanFactory
2019-09-08 14:15:20.799  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.id
2019-09-08 14:15:20.799  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.context.ApplicationContext.applicationName
2019-09-08 14:15:20.801  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration so treating as simple type for SD Commons
2019-09-08 14:15:20.802  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder so treating as simple type for SD Commons
2019-09-08 14:15:20.805  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class org.springframework.security.config.annotation.web.builders.HttpSecurity so treating as simple type for SD Commons
2019-09-08 14:15:20.850  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class java.util.ArrayList so treating as simple type for SD Commons
2019-09-08 14:15:20.896  INFO 10121 --- [  restartedMain] o.s.d.neo4j.mapping.Neo4jMappingContext  : No class information found in OGM meta-data for class org.springframework.http.HttpHeaders so treating as simple type for SD Commons
2019-09-08 14:15:20.929  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.core.env.Environment.defaultProfiles
2019-09-08 14:15:20.929  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: org.springframework.core.env.Environment.activeProfiles
2019-09-08 14:15:20.932  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.initParameterNames
2019-09-08 14:15:20.932  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.virtualServerName
2019-09-08 14:15:20.932  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.classLoader
2019-09-08 14:15:20.932  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.filterRegistrations
2019-09-08 14:15:20.933  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.servletNames
2019-09-08 14:15:20.933  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.sessionTrackingModes
2019-09-08 14:15:20.933  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.contextPath
2019-09-08 14:15:20.933  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.defaultSessionTrackingModes
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.majorVersion
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.effectiveMinorVersion
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.sessionCookieConfig
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.effectiveSessionTrackingModes
2019-09-08 14:15:20.934  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.attributeNames
2019-09-08 14:15:20.935  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.serverInfo
2019-09-08 14:15:20.935  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.servletRegistrations
2019-09-08 14:15:20.935  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.jspConfigDescriptor
2019-09-08 14:15:20.935  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.servlets
2019-09-08 14:15:20.936  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.requestCharacterEncoding
2019-09-08 14:15:20.936  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.responseCharacterEncoding
2019-09-08 14:15:20.936  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.sessionTimeout
2019-09-08 14:15:20.936  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.minorVersion
2019-09-08 14:15:20.937  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.servletContextName
2019-09-08 14:15:20.937  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.ServletContext.effectiveMajorVersion
2019-09-08 14:15:20.938  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.FilterConfig.initParameterNames
2019-09-08 14:15:20.938  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.FilterConfig.servletContext
2019-09-08 14:15:20.939  WARN 10121 --- [  restartedMain] o.s.d.n.mapping.Neo4jPersistentProperty  : Owning ClassInfo is null for property: javax.servlet.FilterConfig.filterName

What is making it so unhappy?

Body:
Had same problem (SpringBoot 2.2.2 with dependency spring-boot-starter-data-neo4j).  Got rid of the warning and narrowed scanning of entity/model classes by adding both annotations to the main @SpringBootApplication annotated application class:

@EnableNeo4jRepositories("my.project.reposoitory")
@EntityScan("my.project.model")

Avoids the need for a separate @Config class / overriding SpringBoot auto config. See the docs.

Update:
Bumped the Spring Boot version to 2.2.4.RELEASE as I was having problems returning any data from my Neo4jRepository declarative methods. Suspect this is tx related, will raise a defect.


问:
Querying multiple Data Sources together
We have multiple data sources, which have more than a billion records in different tables, most of them are Oracle SQL data sources along with a few NoSQL solutions. The primary fields have different names in different sources. SQL Queries can only join tables in a particular data source. Writing REST API's and stitching data in each API is not possible as our queries are dynamic and might change over time.

How can we tackle this problem, Can GraphQL servers help us stitch multiple data sources and query each with different conditions?

What we seek is a query language that can query across data sources, stitch them together based on certain conditions like join queries and return us the resultset.

```<code>Table 1(Oracle SQL server 1):-

|username | age | tenant |
 abc        56    US
 xyz        32    IN

Table 2 (Oracle SQL server 2):-

|userid | config | duration |
 abc     {..json.}    2100s

the query could be like:-
select * from table1, table2 where table1.userid=table2.username and duration>2000s
</code>```

答:
```<code>CREATE DATABASE LINK dblink1
   CONNECT TO user1 IDENTIFIED BY password1 USING 'connect1';

CREATE DATABASE LINK dblink2
   CONNECT TO user2 IDENTIFIED BY password2 USING 'connect2';

select * from table1@dblink1 AS t1, table2@dblink2 AS t2 where t1.userid=t2.userid and t2.duration > 2000;
</code>```

Note: DB Link should be created once, select could be repeated many times.

```<code>CREATE DATABASE LINK has many options, but I hope the idea helps.
</code>```

Title: Querying multiple Data Sources together

Body:
We have multiple data sources, which have more than a billion records in different tables, most of them are Oracle SQL data sources along with a few NoSQL solutions. The primary fields have different names in different sources. SQL Queries can only join tables in a particular data source. Writing REST API's and stitching data in each API is not possible as our queries are dynamic and might change over time.

How can we tackle this problem, Can GraphQL servers help us stitch multiple data sources and query each with different conditions?

What we seek is a query language that can query across data sources, stitch them together based on certain conditions like join queries and return us the resultset.

Table 1(Oracle SQL server 1):-

|username | age | tenant |
 abc        56    US
 xyz        32    IN

Table 2 (Oracle SQL server 2):-

|userid | config | duration |
 abc     {..json.}    2100s

the query could be like:-
select * from table1, table2 where table1.userid=table2.username and duration>2000s

Body:
CREATE DATABASE LINK dblink1
   CONNECT TO user1 IDENTIFIED BY password1 USING 'connect1';

CREATE DATABASE LINK dblink2
   CONNECT TO user2 IDENTIFIED BY password2 USING 'connect2';

select * from table1@dblink1 AS t1, table2@dblink2 AS t2 where t1.userid=t2.userid and t2.duration > 2000;

Note: DB Link should be created once, select could be repeated many times.

CREATE DATABASE LINK has many options, but I hope the idea helps.


问:
ViewPager2 preloaing next fragment even when offsetlimit is the default(0)
I am facing this rather strange problem with viewPager2.
I did some reading and found out that viewPager2 has a default offset limit of 0 which is perfect for my application.
I'm using it with a tab layout and I have 3 fragments (Home, Profile, Notification).
When the activity loads and the first fragment(Home) loads, I can see in my logcat that the next fragment(Profile) is not loaded, as expected.
But when I click on the profile tab something strange happens, the next tab(Notification) is preloaded. The methods
onAttach,onCreate,onCreateView,onActivityCreated,onStart for the Notification tab is called.
Why is this doing so and how to I fix this ?
Logcat Screenshot
I have attached a screen shot of my logcat here.
Thankyou in advance.</p>

答:
I Assume you mean OFFSCREEN_PAGE_LIMIT_DEFAULT not offsetlimit as you are talking about a preloading of fragments problem.

And the default value is -1 not zero https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2.html#OFFSCREEN_PAGE_LIMIT_DEFAULT

and the default means

Value to indicate that the default caching mechanism of RecyclerView should be used instead of explicitly prefetch and retain pages to either side of the current page.

As this is a performance optimisation of the recyclerview, I would say it's not a guarantee that it won't preload your fragments, it's just left to the caching mechanism of the recyclerview to decide.

There are a number of factors that can affect the recyclerview's caching mechanism.

If preloading of your fragment is a problem because you have dynamic data in it that you only want to be loaded when the page is shown then it would be better to move your fragment to use a "lazy loading" method i.e. only load the data when it is shown.

I had a similar problem with the original viewpager and solved it with "lazy loading". If the timing of loading of your dynamic data is the problem then update the question and then I can outline a possible solution.

Update:3

It seems that Viewpager2 actually works correctly with the Fragments lifecycle unlike the original Viewpager thus you can call updateView() as shown in update2 example from the Fragments onResume method without having to use the pageSelected callback via the Adapter to trigger the update of the View.

Update:

I believe the actual cause from looking at the viewpager2 code is that selecting the Tab does a fake drag with smooth scrolling and smooth scrolling adds the selected item +1 to the cache, if you swipe from Tab0 to Tab1 yourself it does not create Tab2

ViewPager2 is a bit different and "lazy loading" method I used for the original ViewPager does not totally fit but there is a slightly different way to do the same.

The main idea with the original ViewPager was to update the view ONLY when a page was selected using a onPageChangeListener but ViewPager2 uses a callback instead

So add the following after you have created the ViewPager2 (in the Activity onCreate usually)

        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                // Tell the recyclerview that position 2 has changed when selected
                // Thus it recreates it updating the dynamic data
                if (position == 2) {
                    // the adapter for the ViewPager needs to a member of the Activity class so accessible here
                    adapter.notifyItemChanged(position);
                }
            }
        });
```

<p>This is simpler but has a minor drawback that the dynamic data is loaded when it is preloaded and then again when it is actually displayed.</p>

<p><strong>Update2:</strong>
A more efficient addition to first method more similar to my original approach</p>

<p>This is a full working example as it is easier to explain.</p>

<p>The main idea is in your fragment with the dynamic data that you ONLY want to load when it is displayed is to create an empty "placeholder" view item and you don't fill it with data in the Fragments <code>onViewCreated</code>, in this example it is a second <code>textview</code> with no text but could be a recyclerview with zero objects or any other type of view.</p>

<p>In your Fragment you then create a method to update the "placeholder" with the data (in this case the method is called <code>updateView()</code> which sets the textview text to the current date and time)</p>

<p>Then in your Fragment Adapter you store a reference to each fragment it creates in a <code>ArrayList</code> (this allows you get the fragment back) and you then create an <code>updateFragment()</code> method in the adapter that uses the position to get the Fragment to be able to call the <code>updateView()</code> on it.</p>

<p>Finally again you use <code>onPageSelected</code> to call the <code>updateFragment</code> with the position you want to dynamically update.</p>

<p>So <code>textview1</code> shows the data and time the fragement was created and <code>textview2</code> is only shown on the third Tab and has a date and time on when page was selected. Note that <code>texview1</code> on "Tab 2" and "Tab 3" is the same time when you click on the "Tab 2" headers to change tabs (this is the problem in the question)</p>

<p>MainActivity.java</p>

<pre class="lang-java prettyprint-override"><code>package com.test.viewpager2;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

import android.os.Bundle;

import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

public class MainActivity extends AppCompatActivity {

    TabLayout tabLayout;
    ViewPager2 viewPager2;
    ViewPager2Adapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager2 = findViewById(R.id.viewpager2);
        tabLayout = findViewById(R.id.tabLayout);

        viewPager2.setAdapter(createCardAdapter());

        new TabLayoutMediator(tabLayout, viewPager2,
                new TabLayoutMediator.TabConfigurationStrategy() {
                    @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                        tab.setText("Tab " + (position + 1));
                    }
                }).attach();

        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                // Tell the recyclerview that position 2 has changed when selected
                // Thus it recreates it updating the dynamic data
                if (position == 2) {
                    adapter.updateFragment(position);
                }
            }
        });
    }

    private ViewPager2Adapter createCardAdapter() {
        adapter = new ViewPager2Adapter(this);
        return adapter;
    }

}

</code>```

ViewPager2Adapter.java

package com.test.viewpager2;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import java.util.ArrayList;

public class ViewPager2Adapter extends FragmentStateAdapter {

    private static final int numOfTabs = 3;
    private ArrayList<Fragment> fragments = new ArrayList<>();

    public ViewPager2Adapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    @NonNull @Override public Fragment createFragment(int position){
        Fragment fragment = TextFragment.newInstance(position);
        fragments.add(fragment);
        return fragment;
    }

    @Override
    public int getItemCount(){
        return numOfTabs;
    }

    public void updateFragment(int position){
        Fragment fragment = fragments.get(position);
        // Check fragment type to make sure it is one we know has an updateView Method
        if (fragment instanceof TextFragment){
            TextFragment textFragment = (TextFragment) fragment;
            textFragment.updateView();
        }
    }
}
```

<p>TextFragment.java</p>

<pre class="lang-java prettyprint-override"><code>package com.test.viewpager2;

import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

public class TextFragment extends Fragment {
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";

    private int mParam1;
    private View view;

    public TextFragment() {
        // Required empty public constructor
    }

    public static TextFragment newInstance(int param1) {
        TextFragment fragment = new TextFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PARAM1, param1);
        fragment.setArguments(args);
        Log.d("Frag", "newInstance");
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getInt(ARG_PARAM1);
        }
        Log.d("Frag", "onCreate");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        Log.d("Frag", "onCreateView");
        view = inflater.inflate(R.layout.fragment_text, container, false);

        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        Bundle args = getArguments();
        TextView textView1 = view.findViewById(R.id.textview1);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss.sss", Locale.US);
        String dt = df.format(Calendar.getInstance().getTime());
        textView1.setText(dt);
    }

    public void updateView(){
        Log.d("Frag", "updateView");
        TextView textView2 = view.findViewById(R.id.textview2);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss.sss", Locale.US);
        String dt = df.format(Calendar.getInstance().getTime());
        textView2.setText(dt);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d("Frag", "onAttach");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d("Frag", "onDetach");
    }
}
</code>```

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
```

<pre class="lang-xml prettyprint-override"><code><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TextFragment">

    <TextView
        android:id="@+id/textview1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textview2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textview1" />/>

</androidx.constraintlayout.widget.ConstraintLayout>
</code>```

Body:
I Assume you mean OFFSCREEN_PAGE_LIMIT_DEFAULT not offsetlimit as you are talking about a preloading of fragments problem.

And the default value is -1 not zero https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2.html#OFFSCREEN_PAGE_LIMIT_DEFAULT

and the default means

Value to indicate that the default caching mechanism of RecyclerView should be used instead of explicitly prefetch and retain pages to either side of the current page.

As this is a performance optimisation of the recyclerview, I would say it's not a guarantee that it won't preload your fragments, it's just left to the caching mechanism of the recyclerview to decide.

There are a number of factors that can affect the recyclerview's caching mechanism.

If preloading of your fragment is a problem because you have dynamic data in it that you only want to be loaded when the page is shown then it would be better to move your fragment to use a "lazy loading" method i.e. only load the data when it is shown.

I had a similar problem with the original viewpager and solved it with "lazy loading". If the timing of loading of your dynamic data is the problem then update the question and then I can outline a possible solution.

Update:3

It seems that Viewpager2 actually works correctly with the Fragments lifecycle unlike the original Viewpager thus you can call updateView() as shown in update2 example from the Fragments onResume method without having to use the pageSelected callback via the Adapter to trigger the update of the View.

Update:

I believe the actual cause from looking at the viewpager2 code is that selecting the Tab does a fake drag with smooth scrolling and smooth scrolling adds the selected item +1 to the cache, if you swipe from Tab0 to Tab1 yourself it does not create Tab2

ViewPager2 is a bit different and "lazy loading" method I used for the original ViewPager does not totally fit but there is a slightly different way to do the same.

The main idea with the original ViewPager was to update the view ONLY when a page was selected using a onPageChangeListener but ViewPager2 uses a callback instead

So add the following after you have created the ViewPager2 (in the Activity onCreate usually)

        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                // Tell the recyclerview that position 2 has changed when selected
                // Thus it recreates it updating the dynamic data
                if (position == 2) {
                    // the adapter for the ViewPager needs to a member of the Activity class so accessible here
                    adapter.notifyItemChanged(position);
                }
            }
        });

This is simpler but has a minor drawback that the dynamic data is loaded when it is preloaded and then again when it is actually displayed.

Update2:
A more efficient addition to first method more similar to my original approach

This is a full working example as it is easier to explain.

The main idea is in your fragment with the dynamic data that you ONLY want to load when it is displayed is to create an empty "placeholder" view item and you don't fill it with data in the Fragments onViewCreated, in this example it is a second textview with no text but could be a recyclerview with zero objects or any other type of view.

In your Fragment you then create a method to update the "placeholder" with the data (in this case the method is called updateView() which sets the textview text to the current date and time)

Then in your Fragment Adapter you store a reference to each fragment it creates in a ArrayList (this allows you get the fragment back) and you then create an updateFragment() method in the adapter that uses the position to get the Fragment to be able to call the updateView() on it.

Finally again you use onPageSelected to call the updateFragment with the position you want to dynamically update.

So textview1 shows the data and time the fragement was created and textview2 is only shown on the third Tab and has a date and time on when page was selected. Note that texview1 on "Tab 2" and "Tab 3" is the same time when you click on the "Tab 2" headers to change tabs (this is the problem in the question)

MainActivity.java

package com.test.viewpager2;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

import android.os.Bundle;

import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

public class MainActivity extends AppCompatActivity {

    TabLayout tabLayout;
    ViewPager2 viewPager2;
    ViewPager2Adapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager2 = findViewById(R.id.viewpager2);
        tabLayout = findViewById(R.id.tabLayout);

        viewPager2.setAdapter(createCardAdapter());

        new TabLayoutMediator(tabLayout, viewPager2,
                new TabLayoutMediator.TabConfigurationStrategy() {
                    @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                        tab.setText("Tab " + (position + 1));
                    }
                }).attach();

        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                // Tell the recyclerview that position 2 has changed when selected
                // Thus it recreates it updating the dynamic data
                if (position == 2) {
                    adapter.updateFragment(position);
                }
            }
        });
    }

    private ViewPager2Adapter createCardAdapter() {
        adapter = new ViewPager2Adapter(this);
        return adapter;
    }

}

ViewPager2Adapter.java

package com.test.viewpager2;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import java.util.ArrayList;

public class ViewPager2Adapter extends FragmentStateAdapter {

    private static final int numOfTabs = 3;
    private ArrayList<Fragment> fragments = new ArrayList<>();

    public ViewPager2Adapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    @NonNull @Override public Fragment createFragment(int position){
        Fragment fragment = TextFragment.newInstance(position);
        fragments.add(fragment);
        return fragment;
    }

    @Override
    public int getItemCount(){
        return numOfTabs;
    }

    public void updateFragment(int position){
        Fragment fragment = fragments.get(position);
        // Check fragment type to make sure it is one we know has an updateView Method
        if (fragment instanceof TextFragment){
            TextFragment textFragment = (TextFragment) fragment;
            textFragment.updateView();
        }
    }
}

TextFragment.java

package com.test.viewpager2;

import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

public class TextFragment extends Fragment {
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";

    private int mParam1;
    private View view;

    public TextFragment() {
        // Required empty public constructor
    }

    public static TextFragment newInstance(int param1) {
        TextFragment fragment = new TextFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PARAM1, param1);
        fragment.setArguments(args);
        Log.d("Frag", "newInstance");
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getInt(ARG_PARAM1);
        }
        Log.d("Frag", "onCreate");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        Log.d("Frag", "onCreateView");
        view = inflater.inflate(R.layout.fragment_text, container, false);

        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        Bundle args = getArguments();
        TextView textView1 = view.findViewById(R.id.textview1);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss.sss", Locale.US);
        String dt = df.format(Calendar.getInstance().getTime());
        textView1.setText(dt);
    }

    public void updateView(){
        Log.d("Frag", "updateView");
        TextView textView2 = view.findViewById(R.id.textview2);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss.sss", Locale.US);
        String dt = df.format(Calendar.getInstance().getTime());
        textView2.setText(dt);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d("Frag", "onAttach");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d("Frag", "onDetach");
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TextFragment">

    <TextView
        android:id="@+id/textview1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textview2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textview1" />/>

</androidx.constraintlayout.widget.ConstraintLayout>