问:
What is the best method to use ObservableLists for both GUI and background Tasks?
SSCCE:

```<code>package sample;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        ListView<Integer> root = new ListView<Integer>();
        ObservableList<Integer> data = Model.getInstance().getData();
        root.setItems(data);

        // A Thread that simulates changes to GUI Observant List.
        Thread populate = new Thread(()->{
            for(int i=0;i<20000;i+=1){
                int finalInstance = i;
                // Changes are done on FXThread
                Platform.runLater(()->{
                    data.add(finalInstance);
                });
                try{
                    Thread.sleep(5);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        });populate.start();
        // Populates at 200 elements/s

        // Server Thread that Sends current status of ObservableList<Integer> data
        Thread server = new Thread(()->{
            try{
                // Server Socket
                ServerSocket ss = new ServerSocket(5555);System.out.println("SERVER ONLINE:");
                while(true){
                    Socket s = ss.accept();
                    // Client Handler Thread to Handle Clients
                    Thread clientHandler = new Thread(()->{
                        try{
                            System.out.println("SERVER CLIENT:"+s);
                            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
                            List<Integer> dataCopy = new ArrayList<Integer>();

                            // Get Current Status of data List that is being used in FXThread adn store in dataCopy
                            Semaphore waitForReadToComplete = new Semaphore(0);
                            Platform.runLater(()->{
                                System.out.println("EXPECTED LENGTH: "+data.size());
                                for(Integer a:data){
                                    dataCopy.add(a);
                                    try{
                                        Thread.sleep(5); // Simulate delay while copying large elements
                                    }catch (InterruptedException e){e.printStackTrace();}
                                }
                                waitForReadToComplete.release(); // Marks Read Operation Complete
                            });
                            waitForReadToComplete.acquire();// Resumes Client Thread
                            oos.writeObject(dataCopy);oos.flush();
                            s.close();
                        }catch (InterruptedException | IOException e){
                            e.printStackTrace();
                        }
                    });clientHandler.start();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        });server.start();

        // Client Thread that requests for current status of ObservableList<Integer> data.
        Thread client = new Thread(()->{
            try{
                Thread.sleep(1000);
                Socket s = new Socket(InetAddress.getLocalHost(),5555);
                ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
                List<Integer> dataCopy;
                dataCopy = (ArrayList<Integer>)ois.readObject();
                s.close();
                System.out.println("ACTUAL LENGTH RECIEVED BY CLIENT "+dataCopy.size());
            }catch (IOException | ClassNotFoundException | InterruptedException e){
                e.printStackTrace();
            }
        });client.start();

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

// Singleton Class with Eager Initialization
class Model{
    static Model onlyInstance = new Model();
    ObservableList<Integer> data = FXCollections.<Integer>observableArrayList();
    public static Model getInstance(){
        return onlyInstance;
    }

    public ObservableList<Integer> getData(){
        return data;
    }
}
</code>```

In this example, I intend to send over the status of the data List to a client when it connects to my Server Thread.

The problem is that every time I want to read the data List, I need to do it using a Platform.runLater() call, whose scheduling is not in my control.

I use a Semaphore to block the Server's Client Handler thread in order to make sure that the complete List is copied and then sent to the client.

As visible, This method makes my client wait for a longer period of time since copying the data List is done inside Platform.runLater().

I was wondering if there was a better way to share my data List between the FXThread and Background Threads.

EDIT:

Better wording, courtesy of @James_D

I have a model with some (possibly large amount of) data. The model is being updated by a background thread. The server has access to the model and sends the data on demand to network-connected clients. And then there's a UI, which is server-side. And I want the UI to display the current state of the model on the server-side and perform add/remove operations on the data from the UI user.

答:
I suggest using a Model shared between the javafx Application, the modifying thread, and the server:

```<code>import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

public class Main extends Application {

    private Model model;

    @Override
    public void start(Stage primaryStage) throws Exception{

        ListView<Integer> listView = new ListView<>();
        ObservableList<Integer> data = listView.getItems();

        model = new Model();

        model.getData().addListener(
                (ListChangeListener<Integer>) listener -> {
                    listener.next();
                    Platform.runLater(()->  data.addAll(listener.getAddedSubList()));
                }
        );

        populate();
        new Server(model, 5555).activate();
        new Client("localhost",5555).activate();

        primaryStage.setScene(new Scene(listView, 300, 275));
        primaryStage.show();
    }

    private void populate() {

        Thread populate = new Thread(()->{
            for(int i=0;i<20000;i+=1){
                model.addData(i);
                try{
                    Thread.sleep(50);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        });populate.start();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class Model{

    private final ObservableList<Integer> data = FXCollections.<Integer>observableArrayList();
    private final ObservableList<Integer> readOnlyData = FXCollections.unmodifiableObservableList(data);

    synchronized void addData(int i){
        data.add(i);
    }

    public ObservableList<Integer> getData(){
        return readOnlyData;
    }
}
</code>```

The Server definition, including ServerThread to support multiple clients:

```<code>import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javafx.collections.ObservableList;

public class Server {

    private final ExecutorService pool;
    private final List<ServerThread> clients;
    private final int portNumber;
    private  boolean stop;
    private ServerSocket serverSocket;
    private final Model model;

    Server(Model model, int portNumber) {
        this.model = model;
        this.portNumber = portNumber;
        pool = Executors.newFixedThreadPool(3);
        clients = new ArrayList<>();
    }

    private void runServer(){

        System.out.println("SERVER: Waiting for client");
        try{
            serverSocket = new ServerSocket(portNumber);
            stop = false;

            while(! stop){//do in loop to support multiple clients
                Socket clientSocket = serverSocket.accept();
                System.out.println("SERVER: client connected");
                ServerThread st1 = new ServerThread(model.getData(), clientSocket);
                pool.execute(st1);
                clients.add(st1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            closeSocket();
        }
    }

    public void stop(){

        for( ServerThread st : clients) {
            st.stopServerTread();
        }
        stop = true;
        pool.shutdown();
        closeSocket();
    }

    public void activate(){
        new Thread(()->runServer()).start();
    }

    private void closeSocket() {

        try {
            serverSocket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

class ServerThread extends Thread {

    private Socket socket = null;
    private  boolean stop;
    private final ObservableList observableList;

    public ServerThread(ObservableList<Integer> observableList ,Socket socket) {
        this.observableList = observableList;
        this.socket = socket;
    }

    @Override
    public void run() {

        try{
            stop = false;
            DataInputStream in = new DataInputStream( socket.getInputStream() );
            DataOutputStream out = new DataOutputStream( socket.getOutputStream() );
            String fromClient;
            while(! stop){
                if((fromClient = in.readUTF()) != null) {
                    System.out.println("SERVER: recieved message - " + fromClient);
                    out.writeUTF("Data size is " + observableList.size());
                }
            }

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

    void stopServerTread(){
        stop = true;
    }
}
</code>```

And finally the client which requests info from the server:

```<code>import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

public class Client{

    private final  int portNumber;
    private final String hostName;
    private  boolean stop;

    Client(String hostName, int portNumber )  {
        this.hostName = hostName;
        this.portNumber = portNumber;
    }

    private void runClient(){
        try {
            stop = false;
            Socket socket = new Socket(hostName, portNumber);
            DataInputStream in = new DataInputStream( socket.getInputStream() );
            DataOutputStream out = new DataOutputStream( socket.getOutputStream() );

            while (! stop) {
                out.writeUTF("Request Size"); //any not null string to get server response
                String fromServer  = in.readUTF();
                System.out.println(fromServer);
                TimeUnit.SECONDS.sleep(1);
            }

        } catch (UnknownHostException e) {
            e.printStackTrace();
            System.exit(1);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    public void activate(){
        new Thread(()->runClient()).start();
    }

    public void stop(){
        stop = true;
    }
}
</code>```

Body:
SSCCE:

package sample;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        ListView<Integer> root = new ListView<Integer>();
        ObservableList<Integer> data = Model.getInstance().getData();
        root.setItems(data);

        // A Thread that simulates changes to GUI Observant List.
        Thread populate = new Thread(()->{
            for(int i=0;i<20000;i+=1){
                int finalInstance = i;
                // Changes are done on FXThread
                Platform.runLater(()->{
                    data.add(finalInstance);
                });
                try{
                    Thread.sleep(5);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        });populate.start();
        // Populates at 200 elements/s

        // Server Thread that Sends current status of ObservableList<Integer> data
        Thread server = new Thread(()->{
            try{
                // Server Socket
                ServerSocket ss = new ServerSocket(5555);System.out.println("SERVER ONLINE:");
                while(true){
                    Socket s = ss.accept();
                    // Client Handler Thread to Handle Clients
                    Thread clientHandler = new Thread(()->{
                        try{
                            System.out.println("SERVER CLIENT:"+s);
                            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
                            List<Integer> dataCopy = new ArrayList<Integer>();

                            // Get Current Status of data List that is being used in FXThread adn store in dataCopy
                            Semaphore waitForReadToComplete = new Semaphore(0);
                            Platform.runLater(()->{
                                System.out.println("EXPECTED LENGTH: "+data.size());
                                for(Integer a:data){
                                    dataCopy.add(a);
                                    try{
                                        Thread.sleep(5); // Simulate delay while copying large elements
                                    }catch (InterruptedException e){e.printStackTrace();}
                                }
                                waitForReadToComplete.release(); // Marks Read Operation Complete
                            });
                            waitForReadToComplete.acquire();// Resumes Client Thread
                            oos.writeObject(dataCopy);oos.flush();
                            s.close();
                        }catch (InterruptedException | IOException e){
                            e.printStackTrace();
                        }
                    });clientHandler.start();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        });server.start();

        // Client Thread that requests for current status of ObservableList<Integer> data.
        Thread client = new Thread(()->{
            try{
                Thread.sleep(1000);
                Socket s = new Socket(InetAddress.getLocalHost(),5555);
                ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
                List<Integer> dataCopy;
                dataCopy = (ArrayList<Integer>)ois.readObject();
                s.close();
                System.out.println("ACTUAL LENGTH RECIEVED BY CLIENT "+dataCopy.size());
            }catch (IOException | ClassNotFoundException | InterruptedException e){
                e.printStackTrace();
            }
        });client.start();

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

// Singleton Class with Eager Initialization
class Model{
    static Model onlyInstance = new Model();
    ObservableList<Integer> data = FXCollections.<Integer>observableArrayList();
    public static Model getInstance(){
        return onlyInstance;
    }

    public ObservableList<Integer> getData(){
        return data;
    }
}

In this example, I intend to send over the status of the data List to a client when it connects to my Server Thread.

The problem is that every time I want to read the data List, I need to do it using a Platform.runLater() call, whose scheduling is not in my control.

I use a Semaphore to block the Server's Client Handler thread in order to make sure that the complete List is copied and then sent to the client.

As visible, This method makes my client wait for a longer period of time since copying the data List is done inside Platform.runLater().

I was wondering if there was a better way to share my data List between the FXThread and Background Threads.

EDIT:

Better wording, courtesy of @James_D

I have a model with some (possibly large amount of) data. The model is being updated by a background thread. The server has access to the model and sends the data on demand to network-connected clients. And then there's a UI, which is server-side. And I want the UI to display the current state of the model on the server-side and perform add/remove operations on the data from the UI user.

Body:
I suggest using a Model shared between the javafx Application, the modifying thread, and the server:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

public class Main extends Application {

    private Model model;

    @Override
    public void start(Stage primaryStage) throws Exception{

        ListView<Integer> listView = new ListView<>();
        ObservableList<Integer> data = listView.getItems();

        model = new Model();

        model.getData().addListener(
                (ListChangeListener<Integer>) listener -> {
                    listener.next();
                    Platform.runLater(()->  data.addAll(listener.getAddedSubList()));
                }
        );

        populate();
        new Server(model, 5555).activate();
        new Client("localhost",5555).activate();

        primaryStage.setScene(new Scene(listView, 300, 275));
        primaryStage.show();
    }

    private void populate() {

        Thread populate = new Thread(()->{
            for(int i=0;i<20000;i+=1){
                model.addData(i);
                try{
                    Thread.sleep(50);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        });populate.start();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class Model{

    private final ObservableList<Integer> data = FXCollections.<Integer>observableArrayList();
    private final ObservableList<Integer> readOnlyData = FXCollections.unmodifiableObservableList(data);

    synchronized void addData(int i){
        data.add(i);
    }

    public ObservableList<Integer> getData(){
        return readOnlyData;
    }
}

The Server definition, including ServerThread to support multiple clients:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javafx.collections.ObservableList;

public class Server {

    private final ExecutorService pool;
    private final List<ServerThread> clients;
    private final int portNumber;
    private  boolean stop;
    private ServerSocket serverSocket;
    private final Model model;

    Server(Model model, int portNumber) {
        this.model = model;
        this.portNumber = portNumber;
        pool = Executors.newFixedThreadPool(3);
        clients = new ArrayList<>();
    }

    private void runServer(){

        System.out.println("SERVER: Waiting for client");
        try{
            serverSocket = new ServerSocket(portNumber);
            stop = false;

            while(! stop){//do in loop to support multiple clients
                Socket clientSocket = serverSocket.accept();
                System.out.println("SERVER: client connected");
                ServerThread st1 = new ServerThread(model.getData(), clientSocket);
                pool.execute(st1);
                clients.add(st1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            closeSocket();
        }
    }

    public void stop(){

        for( ServerThread st : clients) {
            st.stopServerTread();
        }
        stop = true;
        pool.shutdown();
        closeSocket();
    }

    public void activate(){
        new Thread(()->runServer()).start();
    }

    private void closeSocket() {

        try {
            serverSocket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

class ServerThread extends Thread {

    private Socket socket = null;
    private  boolean stop;
    private final ObservableList observableList;

    public ServerThread(ObservableList<Integer> observableList ,Socket socket) {
        this.observableList = observableList;
        this.socket = socket;
    }

    @Override
    public void run() {

        try{
            stop = false;
            DataInputStream in = new DataInputStream( socket.getInputStream() );
            DataOutputStream out = new DataOutputStream( socket.getOutputStream() );
            String fromClient;
            while(! stop){
                if((fromClient = in.readUTF()) != null) {
                    System.out.println("SERVER: recieved message - " + fromClient);
                    out.writeUTF("Data size is " + observableList.size());
                }
            }

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

    void stopServerTread(){
        stop = true;
    }
}

And finally the client which requests info from the server:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

public class Client{

    private final  int portNumber;
    private final String hostName;
    private  boolean stop;

    Client(String hostName, int portNumber )  {
        this.hostName = hostName;
        this.portNumber = portNumber;
    }

    private void runClient(){
        try {
            stop = false;
            Socket socket = new Socket(hostName, portNumber);
            DataInputStream in = new DataInputStream( socket.getInputStream() );
            DataOutputStream out = new DataOutputStream( socket.getOutputStream() );

            while (! stop) {
                out.writeUTF("Request Size"); //any not null string to get server response
                String fromServer  = in.readUTF();
                System.out.println(fromServer);
                TimeUnit.SECONDS.sleep(1);
            }

        } catch (UnknownHostException e) {
            e.printStackTrace();
            System.exit(1);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    public void activate(){
        new Thread(()->runClient()).start();
    }

    public void stop(){
        stop = true;
    }
}


来源: stackexchange

问:
How to use NULL or empty string in SQL
I would like to know how to use NULL and an empty string at the same time in a WHERE clause in SQL Server. I need to find records that have either null values or an empty string. Thanks.

答:
```<code>select
   isnull(column,'') column, *
from Table
Where column = ''
</code>```

ContentLicense: CC BY-SA 3.0

Title: How to use NULL or empty string in SQL

ContentLicense: CC BY-SA 4.0


问:
Searching in all files since last commit
Is there any way to search in all modified and staged (git) files. I want to look for any debug logging that I may have put and remove them.</p>

答:
If you know what patterns to look for (e.g : console.log, DEBUG or some specific word ... ), you can use git grep with the --cahed option :

```<code># will loook in all staged files for the target pattern :
git grep --cached 'console\.log'

# you can add '-i' for a case insensitive search :
git grep -i --cached 'console\.log'
</code>```

You can run this from any command line, I don't know if the git interface for intellij has a menu entry for this command.

Body:
If you know what patterns to look for (e.g : console.log, DEBUG or some specific word ... ), you can use git grep with the --cahed option :

# will loook in all staged files for the target pattern :
git grep --cached 'console\.log'

# you can add '-i' for a case insensitive search :
git grep -i --cached 'console\.log'

You can run this from any command line, I don't know if the git interface for intellij has a menu entry for this command.


问:
Coroutines how to wait for the data and then continue process
I'm learning coroutines with kotlin, and I have problem how process can wait until process 1 finished then it continue to process 2, from my sample below I have object Network which access API server using getNews(it's running well and get the data)
I called this getNews from refreshNews using asynch - await, with the purpose it wait for the data then it continue running, but "The program Not Wait", it just running process 2 then process 1 finish, so I cannot capture data from API in refresh news</p>

```<code>// process 1 - calling api this running well can get the data see process 2

object Network {
    var status : NewsApiStatus =  NewsApiStatus.LOADING

    private var viewModelJob = Job()
    private val coroutineScope = CoroutineScope(viewModelJob + Dispatchers.Main)

    fun getNews(filter: String, page: Int =1) : newsData? {
        var allNews : newsData? = null
        coroutineScope.launch {
            RetrofitClient.instance.getAllNews(filter, page).enqueue(object: Callback<newsData>{
                override fun onFailure(call: Call<newsData>, t: Throwable) {
                    status = NewsApiStatus.ERROR
                }

                override fun onResponse(
                    call: Call<newsData>,
                    response: Response<newsData>
                ) {
                    status = NewsApiStatus.DONE
                    var listResult = response.body()
                    if (listResult != null) {
                        if (listResult.data.isNotEmpty())  {
                            allNews = listResult
                            Timber.tag(TAG).i( "process 1 total allNews = ${allNews!!.data.size}")
                        }
                    }
                }
            })
        }
        return(allNews)
    }
}

// process 2 - calling process 1 with runBlocking

fun refreshNews() = runBlocking{
    val newsData = async {
        Network.getNews("")
    }
    Timber.tag(TAG).i("proses 2 ${newsData.await()?.data?.size}")
    // here I want newsData to wait until it has data
}

// this main program that call process 2

class NewsListViewModel(application: Application) : AndroidViewModel(application) {
    init {
        refreshNews()
    }
}
</code>```

答:
launch returns a reference to the started job. You can use it to wait for the job to finish by calling join():

val job = GlobalScope.launch { // launch a new coroutine and keep a reference to its Job
    // ...
}
runBlocking {
    job.join() // wait until child coroutine completes
}
```

Currently, your getNews() launches a coroutine and immediately returns.  allNews isn't initialised at that point yet.

You need to either call job.join() inside getNews() (would make it blocking), or use async inside getNews() and return its result if you want to keep it asynchronous (you'd need to take the result differently from your http client as you won't be able to initialise the variable declared outside).

It's worth to go through the official coroutine docs:

https://kotlinlang.org/docs/reference/coroutines/basics.html

https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html

Body:
I'm learning coroutines with kotlin, and I have problem how process can wait until process 1 finished then it continue to process 2, from my sample below I have object Network which access API server using getNews(it's running well and get the data)
I called this getNews from refreshNews using asynch - await, with the purpose it wait for the data then it continue running, but "The program Not Wait", it just running process 2 then process 1 finish, so I cannot capture data from API in refresh news

// process 1 - calling api this running well can get the data see process 2

object Network {
    var status : NewsApiStatus =  NewsApiStatus.LOADING

    private var viewModelJob = Job()
    private val coroutineScope = CoroutineScope(viewModelJob + Dispatchers.Main)

    fun getNews(filter: String, page: Int =1) : newsData? {
        var allNews : newsData? = null
        coroutineScope.launch {
            RetrofitClient.instance.getAllNews(filter, page).enqueue(object: Callback<newsData>{
                override fun onFailure(call: Call<newsData>, t: Throwable) {
                    status = NewsApiStatus.ERROR
                }

                override fun onResponse(
                    call: Call<newsData>,
                    response: Response<newsData>
                ) {
                    status = NewsApiStatus.DONE
                    var listResult = response.body()
                    if (listResult != null) {
                        if (listResult.data.isNotEmpty())  {
                            allNews = listResult
                            Timber.tag(TAG).i( "process 1 total allNews = ${allNews!!.data.size}")
                        }
                    }
                }
            })
        }
        return(allNews)
    }
}

// process 2 - calling process 1 with runBlocking

fun refreshNews() = runBlocking{
    val newsData = async {
        Network.getNews("")
    }
    Timber.tag(TAG).i("proses 2 ${newsData.await()?.data?.size}")
    // here I want newsData to wait until it has data
}

// this main program that call process 2

class NewsListViewModel(application: Application) : AndroidViewModel(application) {
    init {
        refreshNews()
    }
}

Body:
launch returns a reference to the started job. You can use it to wait for the job to finish by calling join():

val job = GlobalScope.launch { // launch a new coroutine and keep a reference to its Job
    // ...
}
runBlocking {
    job.join() // wait until child coroutine completes
}

Currently, your getNews() launches a coroutine and immediately returns.  allNews isn't initialised at that point yet.

You need to either call job.join() inside getNews() (would make it blocking), or use async inside getNews() and return its result if you want to keep it asynchronous (you'd need to take the result differently from your http client as you won't be able to initialise the variable declared outside).

It's worth to go through the official coroutine docs:

https://kotlinlang.org/docs/reference/coroutines/basics.html

https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html


问:
How do I calculate average tons per hour by driver in Google Sheets?
https://docs.google.com/spreadsheets/d/1SiUfqrJNHPAYjibeNBdzWQEcuzka5srf7mSHAv_bn5k/edit?usp=sharing

What would a formula look like to calculate the average tons per hour by driver in this example spreadsheet? Correcting for long times or even days between loads.

We're being charged on an hourly basis for freight so I'd like to figure out which drivers are the most efficient.

It's been tricky because the only concrete source of information we have is the scale tickets. So if they only do a single load in a day or go several hours between loads then the data would be skewed if you use a simple metric like time elapsed.

Also, I'll need the time elapsed between rows (not just the difference between Time In and Time Out) unless that time is > 1.5 hours. So something like:

=(TIMEVALUE(E3)-TIMEVALUE(D2))*24

...With some added logic to not include anything over 1.5 hours.

If a pivot table would be better than a lengthy formula, that's fine with me.

Here's an example for some added context: Driver Cody goes to Farm Nic to receive a load of hay, then comes back to the weigh station (Ticket, Time In, Gross are then determined), dumps the load, comes back to weigh again empty (Tare, Net, and Time Out are determined here), and goes back to Farm Nic until all the hay is harvested. Then it's on to Farm Zach and Farm Williams to repeat the process. There are several Drivers going at a time, which can be seen if the spreadsheet is sorted by Ticket. My goal is to figure out how many Tons each driver delivers per hour. The time elapsed would include the time between Tickets, because Time In and Time Out just show the time elapsed between coming in with a load of hay and leaving to go back to the field. To get a true measure of tons delivered per hour, you'd need to include the time between tickets, but also remove any instance where that time is greater than 1.5 hours. That will account for circumstances where the Driver isn't working and we aren't being billed, such as during equipment breakdowns.

答:
I'm not much of a formulas guy so I hope this suffice your needs.

First I added a column to your sheet, to calculate how many amount of hours is taking for every single row, to do that I made use of the TIMEVALUE function:

```<code>=(TIMEVALUE(E2)-TIMEVALUE(D2))*24
</code>```

Now you just need to get all the driver's hours and tons and make the quotient total_tons / total_hours. For that they may be some other functions that would do the job, myself I have used QUERY:

```<code>=QUERY(Sheet1!A:M, "select C, sum(I), sum(M), sum(I) / sum(M) group by C", 1)
</code>```

I think pretty straightforward query, group all the data by C (Driver's name) and then sum the column I (tons) and the column M (hours).

With the following result:

The format may be a little off but you can change it as mush as you want. You can copy or play with the sheet

EDIT

After you change your requirements I made a change to my formula to calculate the hours worked:

```<code>=IF(
    AND(
        C3=C2,
        A3=A2,
        IFERROR(
               (TIMEVALUE(E3)-TIMEVALUE(D2))*24) <= 1.5,
                TRUE
        ),
    (TIMEVALUE(E3)-TIMEVALUE(D2))*24,
    (TIMEVALUE(E2)-TIMEVALUE(D2))*24
)
</code>```

Let me explain here, before there was a much simpler formula but now having multiple rows that we need to check makes the formula more lenghty.

First with the IF and AND statement we check if the next row has:

The same day (A3=A2)

The same Driver (C3=C2)

Less than an hour and a half of difference (TIMEVALUE(E3)-TIMEVALUE(D2))*24) <= 1.5)

And also because the last row throws an error trying to TIMEVALUE an empty column I had to add the IFERROR

After that the TRUE condition (same day, same driver, under 1.5h hours difference) will calculate from the current Time in (D2) to the next Time in (D3):

```<code>(TIMEVALUE(D3)-TIMEVALUE(D2))*24
</code>```

And in the FALSE statement we do the same we were doing before:

```<code>(TIMEVALUE(E2)-TIMEVALUE(D2))*24
</code>```

The QUERY function stays the same. And the results have decreased  drastically:

If you have any doubts you can go ahead and see the sheet

Body:
I'm not much of a formulas guy so I hope this suffice your needs.

First I added a column to your sheet, to calculate how many amount of hours is taking for every single row, to do that I made use of the TIMEVALUE function:

=(TIMEVALUE(E2)-TIMEVALUE(D2))*24

Now you just need to get all the driver's hours and tons and make the quotient total_tons / total_hours. For that they may be some other functions that would do the job, myself I have used QUERY:

=QUERY(Sheet1!A:M, "select C, sum(I), sum(M), sum(I) / sum(M) group by C", 1)

I think pretty straightforward query, group all the data by C (Driver's name) and then sum the column I (tons) and the column M (hours).

With the following result:

The format may be a little off but you can change it as mush as you want. You can copy or play with the sheet

EDIT

After you change your requirements I made a change to my formula to calculate the hours worked:

=IF(
    AND(
        C3=C2,
        A3=A2,
        IFERROR(
               (TIMEVALUE(E3)-TIMEVALUE(D2))*24) <= 1.5,
                TRUE
        ),
    (TIMEVALUE(E3)-TIMEVALUE(D2))*24,
    (TIMEVALUE(E2)-TIMEVALUE(D2))*24
)

Let me explain here, before there was a much simpler formula but now having multiple rows that we need to check makes the formula more lenghty.

First with the IF and AND statement we check if the next row has:

The same day (A3=A2)

The same Driver (C3=C2)

Less than an hour and a half of difference (TIMEVALUE(E3)-TIMEVALUE(D2))*24) <= 1.5)

And also because the last row throws an error trying to TIMEVALUE an empty column I had to add the IFERROR

After that the TRUE condition (same day, same driver, under 1.5h hours difference) will calculate from the current Time in (D2) to the next Time in (D3):

(TIMEVALUE(D3)-TIMEVALUE(D2))*24

And in the FALSE statement we do the same we were doing before:

(TIMEVALUE(E2)-TIMEVALUE(D2))*24

The QUERY function stays the same. And the results have decreased  drastically:

If you have any doubts you can go ahead and see the sheet


问:
Is there a way to get true client's ip address in dns servers?
As much as I'm aware of, when a Dns server gets a request for a name translation, there is a very high chance that it comes from another Dns server delegating (intercepting) a clients request. So the src Ip would not be the address of the real client. Is there a Dns response, something like,

HERE IS THE CNAME FOR THAT DOMAIN, BUT LET THAT CLIENT ASK DIRECTLY THE A RECORD OF THAT CNAME FROM ME

Or any other solutions for DNS, to get the IP of requesting client (NOT OTHER Recursion DNS resolver) for a public Dns like that will be highly appreciated

Thank YOU

答:
There is a DNS extension called (ECS) may satisfy your need.
It contains client IP subnet in DNS query for better resolution.

Also, set DNS query Recursion Desired bit to 0 on client side can do iterative DNS query.
But this is up to the client to set the flag, and it's needed to set TTL to 0 in DNS response to prevent other DNS server from returning cached record.

Neither approach can make client MUSTsend it's true IP to DNS server, maybe there is a better way depends on the actual problem you want to solve.


问:
DateFormField call save from form
the code from this question:
Receive Response from pop navigator in Flutter
with added DateTime picker form field.

If we add DateFormField like this:

maind.dart

```<code>import 'package:flutter/material.dart';
import 'package:date_field/date_field.dart';
import 'answer.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(appTitle),
        ),
        body: ShowData(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>();
  final myController = TextEditingController();
  Data stateData = Data();
  @override
  void dispose() {
    // Clean up the controller when the widget is disposed.
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Scaffold(
      body: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            DateFormField(
              initialDatePickerMode: DatePickerMode.day,
              enabled: true,
            key:_formKey,
            onSaved: (DateTime value)
              {
                stateData.datefield = value;
              },
            validator: (DateTime value){
              return  stateData.datefield != null ? null : 'enter date';
            },
              firstDate: DateTime.now().subtract(Duration(days: 180)),
              lastDate: DateTime.now().add(Duration(days: 365)),

            ),
            TextFormField(
              controller: myController,
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
              onSaved: (value){
                stateData.load = value;
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16.0),
              child: RaisedButton(
                onPressed: () {
                  // Validate returns true if the form is valid, or false
                  // otherwise.
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                    // If the form is valid, display a Snackbar.
                    Navigator.pop(context,stateData);
//                  Scaffold.of(context)
//                      .showSnackBar(SnackBar(content: Text(myController.text)));
//                    myController.text = 'look at me';
                  }
                },
                child: Text('Submit'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class Data {
  String load;
  DateTime datefield;
}
</code>```

when pop happens there is exception that the validator was called on null.
and "The following assertion was thrown while finalizing the widget tree:
Multiple widgets used the same GlobalKey."

if the key field is not used, then the validator is not called upon.
why?
how do you use DateFormField? from package

date_field: "^0.1.2"

adding answer.dart

```<code>import 'package:flutter/material.dart';

import 'main.dart';

class ShowData extends StatefulWidget {

  @override
  _ShowDataState createState() => _ShowDataState();
}

class _ShowDataState extends State<ShowData> {
  String data = 'start';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: FloatingActionButton(onPressed:   () async {
          final holder = await  getFormData(context);
          setState(() {
            data = holder.load;
          });
        },
        elevation: 4,

        ),
        body:Text(data,style: TextStyle(fontSize: 80),));
  }

  Future<Data> getFormData(BuildContext context) async {
    final answer =  await Navigator.push(context,MaterialPageRoute(builder: (context)=>MyCustomForm()));
        return (Future.value(answer));
  }
}
</code>```

答:
You can copy paste run full code below

Step 1: remove key:_formKey

```<code>DateFormField(
          initialDatePickerMode: DatePickerMode.day,
          enabled: true,
          //key:_formKey,
</code>```

Step 2: validator use value != null not stateData.datefield != null

```<code>validator: (DateTime value) {
            //return stateData.datefield != null ? null : 'enter date';
            return value != null ? null : 'enter date';
          },
</code>```

working demo

full code

```<code>import 'package:flutter/material.dart';
import 'package:date_field/date_field.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(appTitle),
        ),
        body: ShowData(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>();
  final myController = TextEditingController();
  Data stateData = Data();
  @override
  void dispose() {
    // Clean up the controller when the widget is disposed.
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Scaffold(
      body: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            DateFormField(
              initialDatePickerMode: DatePickerMode.day,
              enabled: true,
              //key:_formKey,
              onSaved: (DateTime value) {
                stateData.datefield = value;
              },
              validator: (DateTime value) {
                //return stateData.datefield != null ? null : 'enter date';
                return value != null ? null : 'enter date';
              },
              firstDate: DateTime.now().subtract(Duration(days: 180)),
              lastDate: DateTime.now().add(Duration(days: 365)),
            ),
            TextFormField(
              controller: myController,
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
              onSaved: (value) {
                stateData.load = value;
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16.0),
              child: RaisedButton(
                onPressed: () {
                  // Validate returns true if the form is valid, or false
                  // otherwise.
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                    // If the form is valid, display a Snackbar.
                    Navigator.pop(context, stateData);
//                  Scaffold.of(context)
//                      .showSnackBar(SnackBar(content: Text(myController.text)));
//                    myController.text = 'look at me';
                  }
                },
                child: Text('Submit'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class Data {
  String load;
  DateTime datefield;
}

class ShowData extends StatefulWidget {
  @override
  _ShowDataState createState() => _ShowDataState();
}

class _ShowDataState extends State<ShowData> {
  String data = 'start';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            final holder = await getFormData(context);
            print(holder.datefield);
            setState(() {
              data = holder.load;
            });
          },
          elevation: 4,
        ),
        body: Text(
          data,
          style: TextStyle(fontSize: 80),
        ));
  }

  Future<Data> getFormData(BuildContext context) async {
    final answer = await Navigator.push(
        context, MaterialPageRoute(builder: (context) => MyCustomForm()));
    return (Future.value(answer));
  }
}
</code>```

Title: DateFormField call save from form

Body:
the code from this question:
Receive Response from pop navigator in Flutter
with added DateTime picker form field.

If we add DateFormField like this:

maind.dart

import 'package:flutter/material.dart';
import 'package:date_field/date_field.dart';
import 'answer.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(appTitle),
        ),
        body: ShowData(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>();
  final myController = TextEditingController();
  Data stateData = Data();
  @override
  void dispose() {
    // Clean up the controller when the widget is disposed.
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Scaffold(
      body: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            DateFormField(
              initialDatePickerMode: DatePickerMode.day,
              enabled: true,
            key:_formKey,
            onSaved: (DateTime value)
              {
                stateData.datefield = value;
              },
            validator: (DateTime value){
              return  stateData.datefield != null ? null : 'enter date';
            },
              firstDate: DateTime.now().subtract(Duration(days: 180)),
              lastDate: DateTime.now().add(Duration(days: 365)),

            ),
            TextFormField(
              controller: myController,
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
              onSaved: (value){
                stateData.load = value;
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16.0),
              child: RaisedButton(
                onPressed: () {
                  // Validate returns true if the form is valid, or false
                  // otherwise.
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                    // If the form is valid, display a Snackbar.
                    Navigator.pop(context,stateData);
//                  Scaffold.of(context)
//                      .showSnackBar(SnackBar(content: Text(myController.text)));
//                    myController.text = 'look at me';
                  }
                },
                child: Text('Submit'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class Data {
  String load;
  DateTime datefield;
}

when pop happens there is exception that the validator was called on null.
and "The following assertion was thrown while finalizing the widget tree:
Multiple widgets used the same GlobalKey."

if the key field is not used, then the validator is not called upon.
why?
how do you use DateFormField? from package

date_field: "^0.1.2"

adding answer.dart

import 'package:flutter/material.dart';

import 'main.dart';

class ShowData extends StatefulWidget {

  @override
  _ShowDataState createState() => _ShowDataState();
}

class _ShowDataState extends State<ShowData> {
  String data = 'start';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: FloatingActionButton(onPressed:   () async {
          final holder = await  getFormData(context);
          setState(() {
            data = holder.load;
          });
        },
        elevation: 4,

        ),
        body:Text(data,style: TextStyle(fontSize: 80),));
  }

  Future<Data> getFormData(BuildContext context) async {
    final answer =  await Navigator.push(context,MaterialPageRoute(builder: (context)=>MyCustomForm()));
        return (Future.value(answer));
  }
}

Body:
You can copy paste run full code below

Step 1: remove key:_formKey

DateFormField(
          initialDatePickerMode: DatePickerMode.day,
          enabled: true,
          //key:_formKey,

Step 2: validator use value != null not stateData.datefield != null

validator: (DateTime value) {
            //return stateData.datefield != null ? null : 'enter date';
            return value != null ? null : 'enter date';
          },

working demo

full code

import 'package:flutter/material.dart';
import 'package:date_field/date_field.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(appTitle),
        ),
        body: ShowData(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>();
  final myController = TextEditingController();
  Data stateData = Data();
  @override
  void dispose() {
    // Clean up the controller when the widget is disposed.
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Scaffold(
      body: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            DateFormField(
              initialDatePickerMode: DatePickerMode.day,
              enabled: true,
              //key:_formKey,
              onSaved: (DateTime value) {
                stateData.datefield = value;
              },
              validator: (DateTime value) {
                //return stateData.datefield != null ? null : 'enter date';
                return value != null ? null : 'enter date';
              },
              firstDate: DateTime.now().subtract(Duration(days: 180)),
              lastDate: DateTime.now().add(Duration(days: 365)),
            ),
            TextFormField(
              controller: myController,
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
              onSaved: (value) {
                stateData.load = value;
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16.0),
              child: RaisedButton(
                onPressed: () {
                  // Validate returns true if the form is valid, or false
                  // otherwise.
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                    // If the form is valid, display a Snackbar.
                    Navigator.pop(context, stateData);
//                  Scaffold.of(context)
//                      .showSnackBar(SnackBar(content: Text(myController.text)));
//                    myController.text = 'look at me';
                  }
                },
                child: Text('Submit'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class Data {
  String load;
  DateTime datefield;
}

class ShowData extends StatefulWidget {
  @override
  _ShowDataState createState() => _ShowDataState();
}

class _ShowDataState extends State<ShowData> {
  String data = 'start';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            final holder = await getFormData(context);
            print(holder.datefield);
            setState(() {
              data = holder.load;
            });
          },
          elevation: 4,
        ),
        body: Text(
          data,
          style: TextStyle(fontSize: 80),
        ));
  }

  Future<Data> getFormData(BuildContext context) async {
    final answer = await Navigator.push(
        context, MaterialPageRoute(builder: (context) => MyCustomForm()));
    return (Future.value(answer));
  }
}


问:
Regex to search all directories whose name contains one of the two substrings
I'm a actually working on a Bash Script that search the backups directories to delete.

I have a directory ~/test/ that contain some "backups" directories named as follow :

```<code>20200302_000001-daily
20200330_000001-monthly
20200528_000001-weekly
20200529_000001-daily
20200530_000001-daily
20200531_000001-monthly
20200601_000001-daily
20200602_000001-daily
</code>```

With a find command, I'm trying to record all directory's name that contain the string daily or weekly in an array :

BACKUPS=(`find $BACKUP_DIR -maxdepth 1 -regex ".*[daily|weekly]$"`) // where $BACKUP_DIR is the absolute path to the "test" directory.

The problem is, that the regex match all the backups directories and after hours of research, I didn't find why.

It's interesting to know that if I use the regex .*daily$, the regex match all the "daily" backups directories (and .*weekly$ match all the "weekly" backups directories).

I know there are other ways to do it, but I really want to success with a regex.

答:
You may use a regex that will match the whole input and contains a grouping construct rather than a bracket expression:

```<code>BACKUPS=(`find $BACKUP_DIR -maxdepth 1 -regex ".*/.*\(daily\|weekly\)$"`)
</code>```

Here, the POSIX BRE pattern means:

.*/ - match any 0 or more chars up to the last /

.* - any 0 or more chars up to

\(daily\|weekly\) - either  daily or weekly character sequences (note that [day|week] is the same as [adekwy|] since it is a bracket expression)

$ - end of string.

Body:
I'm a actually working on a Bash Script that search the backups directories to delete.

I have a directory ~/test/ that contain some "backups" directories named as follow :

20200302_000001-daily
20200330_000001-monthly
20200528_000001-weekly
20200529_000001-daily
20200530_000001-daily
20200531_000001-monthly
20200601_000001-daily
20200602_000001-daily

With a find command, I'm trying to record all directory's name that contain the string daily or weekly in an array :

BACKUPS=(`find $BACKUP_DIR -maxdepth 1 -regex ".*[daily|weekly]$"`) // where $BACKUP_DIR is the absolute path to the "test" directory.

The problem is, that the regex match all the backups directories and after hours of research, I didn't find why.

It's interesting to know that if I use the regex .*daily$, the regex match all the "daily" backups directories (and .*weekly$ match all the "weekly" backups directories).

I know there are other ways to do it, but I really want to success with a regex.

Body:
You may use a regex that will match the whole input and contains a grouping construct rather than a bracket expression:

BACKUPS=(`find $BACKUP_DIR -maxdepth 1 -regex ".*/.*\(daily\|weekly\)$"`)

Here, the POSIX BRE pattern means:

.*/ - match any 0 or more chars up to the last /

.* - any 0 or more chars up to

\(daily\|weekly\) - either  daily or weekly character sequences (note that [day|week] is the same as [adekwy|] since it is a bracket expression)

$ - end of string.


问:
R Rearrange columns in dataframe based on date values in column names
I've got a dataframe that has monthly survey scores for a certain hospitals. Each month, we store the score obtained by the hospital (_Score column) and the corresponding average score for all hospitals for that month (_Average column).

Here's a short sample of what it looks like -

```<code>df = data.frame(Hospital=c(rep("Hospital A",10),rep("Hospital B",10),rep("Hospital C",10),rep("Hospital D",10)),
                Question=c(rep("Q1",40)),
                key=c(rep(c("2020-01-31_Average","2020-01-31_Score","2020-02-29_Average","2020-02-29_Score",
                      "2020-03-31_Average","2020-03-31_Score","2020-04-30_Average","2020-04-30_Score",
                      "2020-05-31_Average","2020-05-31_Score"),4)),
                value=c(round(runif(40,0,1),2)))

library(tidyr)
df = df %>% spread(key,value)
</code>```

I would like to transform this dataframe such that -

1) The first two columns, Hospital and Question remain the same

2) _Score columns for the three most recent months only are kept

3) _Average column for the most recent month is kept

4) Ideally, the columns need to be reordered from oldest to most recent (i.e. in the following order: Month M-2_Score, Month M-1_Score, Month M_Score, Month M_Average)

5) Calculate a column Variance at the end, which is the difference between Score M and Score M-1

What I'm trying to achieve

Using dplyr, this can be done manually by reordering the columns. But I'm looking for a way to build a logic that automatically reorders columns for the 3 most recent months in the sequence described above. By taking the date values embedded in the column names and reordering according to them.

The resulting table would look like this -

```<code>#Final table
df_transformed = df %>%
  select(1:2,8,10,12,11) %>%
  mutate(Variance=.[[5]]-.[[4]])
</code>```

Any tips on how to do this more efficiently using the date values in the column names would be highly appreciated.

答:
I have used your original df in long format before the spread step.

```<code>library(dplyr)
library(tidyr)

df %>%
  #Bring date and key in separate columns
  separate(key, c('Date', 'key'), sep = '_') %>%
  #Convert date column to date class
  mutate(Date = as.Date(Date)) %>%
  #arrange data according with highest date first
  arrange(Hospital, key, desc(Date)) %>%
  #For each hospital and key
  group_by(Hospital, key) %>%
  #If it is a "score" column select top 3 values and
  #for average column select only 1 value
  slice(if(first(key) == 'Score') 1:3 else 1) %>%
  select(-Question) %>%
  ungroup() %>%
  #Get the data in wide format
  pivot_wider(names_from = c(key, Date), values_from = value) %>%
  #Calculate variance column
  mutate(Variance = .[[3]] - .[[4]])

# A tibble: 4 x 6
#  Hospital   `Average_2020-05-31` `Score_2020-05-31` `Score_2020-04-30` `Score_2020-03-31` Variance
#  <chr>                     <dbl>              <dbl>              <dbl>              <dbl>    <dbl>
#1 Hospital A                 0.45               0.44               0.66               0.97    -0.22
#2 Hospital B                 0.11               0.53               0.68               0.27    -0.15
#3 Hospital C                 1                  0.18               0.56               0.41    -0.38
#4 Hospital D                 0.31               0.83               0.6                0.79     0.23
</code>```

To calculate variance .[[3]] - .[[4]] will be fixed because "Hospital" column is fixed and would always be 1st column. "Average" column would come before "Score" column (alphabetically) and since the data is sorted by Date, we know that highest date would be placed first, then second-highest and so on.

Body:
I've got a dataframe that has monthly survey scores for a certain hospitals. Each month, we store the score obtained by the hospital (_Score column) and the corresponding average score for all hospitals for that month (_Average column).

Here's a short sample of what it looks like -

df = data.frame(Hospital=c(rep("Hospital A",10),rep("Hospital B",10),rep("Hospital C",10),rep("Hospital D",10)),
                Question=c(rep("Q1",40)),
                key=c(rep(c("2020-01-31_Average","2020-01-31_Score","2020-02-29_Average","2020-02-29_Score",
                      "2020-03-31_Average","2020-03-31_Score","2020-04-30_Average","2020-04-30_Score",
                      "2020-05-31_Average","2020-05-31_Score"),4)),
                value=c(round(runif(40,0,1),2)))

library(tidyr)
df = df %>% spread(key,value)

I would like to transform this dataframe such that -

1) The first two columns, Hospital and Question remain the same

2) _Score columns for the three most recent months only are kept

3) _Average column for the most recent month is kept

4) Ideally, the columns need to be reordered from oldest to most recent (i.e. in the following order: Month M-2_Score, Month M-1_Score, Month M_Score, Month M_Average)

5) Calculate a column Variance at the end, which is the difference between Score M and Score M-1

What I'm trying to achieve

Using dplyr, this can be done manually by reordering the columns. But I'm looking for a way to build a logic that automatically reorders columns for the 3 most recent months in the sequence described above. By taking the date values embedded in the column names and reordering according to them.

The resulting table would look like this -

#Final table
df_transformed = df %>%
  select(1:2,8,10,12,11) %>%
  mutate(Variance=.[[5]]-.[[4]])

Any tips on how to do this more efficiently using the date values in the column names would be highly appreciated.

Body:
I have used your original df in long format before the spread step.

library(dplyr)
library(tidyr)

df %>%
  #Bring date and key in separate columns
  separate(key, c('Date', 'key'), sep = '_') %>%
  #Convert date column to date class
  mutate(Date = as.Date(Date)) %>%
  #arrange data according with highest date first
  arrange(Hospital, key, desc(Date)) %>%
  #For each hospital and key
  group_by(Hospital, key) %>%
  #If it is a "score" column select top 3 values and
  #for average column select only 1 value
  slice(if(first(key) == 'Score') 1:3 else 1) %>%
  select(-Question) %>%
  ungroup() %>%
  #Get the data in wide format
  pivot_wider(names_from = c(key, Date), values_from = value) %>%
  #Calculate variance column
  mutate(Variance = .[[3]] - .[[4]])

# A tibble: 4 x 6
#  Hospital   `Average_2020-05-31` `Score_2020-05-31` `Score_2020-04-30` `Score_2020-03-31` Variance
#  <chr>                     <dbl>              <dbl>              <dbl>              <dbl>    <dbl>
#1 Hospital A                 0.45               0.44               0.66               0.97    -0.22
#2 Hospital B                 0.11               0.53               0.68               0.27    -0.15
#3 Hospital C                 1                  0.18               0.56               0.41    -0.38
#4 Hospital D                 0.31               0.83               0.6                0.79     0.23

To calculate variance .[[3]] - .[[4]] will be fixed because "Hospital" column is fixed and would always be 1st column. "Average" column would come before "Score" column (alphabetically) and since the data is sorted by Date, we know that highest date would be placed first, then second-highest and so on.


问:
Problem sending POST variable with C# client
I in a C# client, I have the following code:

```<code>Uri uri = new Uri(@"http://myserver/test.php");
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
request.Method = WebRequestMethods.Http.Post;
//request.ContentType = "application/json";

string req = "er3=12";
Console.WriteLine("Req: " + req);

System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding();

byte[] byteData = encoder.GetBytes(req);
request.ContentLength = byteData.Length;

using (Stream postStream = request.GetRequestStream())
{
  postStream.Write(byteData, 0, byteData.Length);
}
</code>```

That's calling a php test page (soon to be replaced by a rest service):

```<code><?php
  echo "post vars:<br>";
  foreach ($_POST as $key => $value) {
    echo "$key -> $value<br>";
  }
  echo "end post vars:<br>";
?>
</code>```

My problem is that when I run the app, in the response I get "post vars:
end post vars:
", so the variable er3 is not received.

If I run a simple html form, the post variable IS correctly read.

What may be wrong or missing in the C# code ?

Thanks

答:
You'll need to set the content type of your data so that PHP knows how to parse it.

Like this:

```<code>request.ContentType = "application/x-www-form-urlencoded";
</code>```

application/x-www-form-urlencoded is the standard MIME type used by web browsers when posting form data.

Body:
I in a C# client, I have the following code:

Uri uri = new Uri(@"http://myserver/test.php");
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
request.Method = WebRequestMethods.Http.Post;
//request.ContentType = "application/json";

string req = "er3=12";
Console.WriteLine("Req: " + req);

System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding();

byte[] byteData = encoder.GetBytes(req);
request.ContentLength = byteData.Length;

using (Stream postStream = request.GetRequestStream())
{
  postStream.Write(byteData, 0, byteData.Length);
}

That's calling a php test page (soon to be replaced by a rest service):

<?php
  echo "post vars:
";
  foreach ($_POST as $key => $value) {
    echo "$key -> $value
";
  }
  echo "end post vars:
";
?>

My problem is that when I run the app, in the response I get "post vars:
end post vars:
", so the variable er3 is not received.

If I run a simple html form, the post variable IS correctly read.

What may be wrong or missing in the C# code ?

Thanks

Body:
You'll need to set the content type of your data so that PHP knows how to parse it.

Like this:

request.ContentType = "application/x-www-form-urlencoded";

application/x-www-form-urlencoded is the standard MIME type used by web browsers when posting form data.


问:
Change gray overlay background of BottomSheet
Is there a way to change the overlay background color when using showModalBottomSheet?

Right now the color is always a gray color, but I want to use a different color like green as shown below.

Here is the code used in the demo for reference

```<code>        showModalBottomSheet<void>(context: context, builder: (BuildContext context) {
          return Container(
            child: Padding(
              padding: const EdgeInsets.all(32.0),
              child: Text('This is the modal bottom sheet. Tap anywhere to dismiss.',
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: Theme.of(context).accentColor,
                  fontSize: 24.0
                )
              )
            )
          );
        });
</code>```

答:
New Flutter UPDATE allows you to change the barrierColor in showModalBottomSheet()

```<code>showModalBottomSheet(
      barrierColor: Colors.yellow.withOpacity(0.5),
</code>```

Body:
Is there a way to change the overlay background color when using showModalBottomSheet?

Right now the color is always a gray color, but I want to use a different color like green as shown below.

Here is the code used in the demo for reference

        showModalBottomSheet<void>(context: context, builder: (BuildContext context) {
          return Container(
            child: Padding(
              padding: const EdgeInsets.all(32.0),
              child: Text('This is the modal bottom sheet. Tap anywhere to dismiss.',
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: Theme.of(context).accentColor,
                  fontSize: 24.0
                )
              )
            )
          );
        });

Body:
New Flutter UPDATE allows you to change the barrierColor in showModalBottomSheet()

showModalBottomSheet(
      barrierColor: Colors.yellow.withOpacity(0.5),


问:
Node JS | Group Items on basis of name and Date Diff
Problem Statement

I am trying to group work experience on the basis of the company name which I am able to do. However, I want to group them only if they are consecutive jobs. The same logic LinkedIn has implemented.
I think a recursive way of grouping items based on name and date difference is needed.
for example

```<code>const data = [
    {
        Position: '1'
        CompanyName: 'Microsoft',
        StartDate: '2017-01-01',
        EndDate: '2017-04-01'
    },
    {
        Position: '2'
        CompanyName: 'Microsoft',
        StartDate: '2017-04-01',
        EndDate: '2017-10-01'
    },
        {
        Position: '3'
        CompanyName: 'Amazon',
        StartDate: '2017-10-01',
        EndDate: '2018-02-01'
    },
    {
        Position: '4'
        CompanyName: 'Microsoft',
        StartDate: '2018-03-04',
        EndDate: '2018-10-04'
    }
];
</code>```

Currently, I am able to group by company name in node js using the following code

Code

```<code>/** applyGroupByPropName
* @param {Object} data this is the data object
* @param {string} propName This is the property to be grouped
* @returns {Object} returns a grouped object based on prop key
*/
    static applyGroupByPropName(data, propName) {
        if (!_.isNull(data) && !_.isEmpty(data) && data.length > 0) {
            data = _.mapValues(_.groupBy(data, propName),
                clist => clist.map(item => _.omit(item, propName)));
        }
        return data;
 }
</code>```

and currently my output is like

```<code>   [
     CompanyName: 'Microsoft': [
     {
        Position: '1'
        StartDate: '2017-01-01',
        EndDate: '2017-04-01'
    }, {
        Position: '2'
        StartDate: '2017-04-01',
        EndDate: '2017-10-01'
    }, {
        Position: '4'
        StartDate: '2018-03-04',
        EndDate: '2018-10-04'
    }
    ],
      CompanyName: 'Amazon' :
      [
        {
        Position: '3'
        StartDate: '2017-10-01',
        EndDate: '2018-02-01'
       }
      ]
   ]
</code>```

Expected Output

```<code>   [
     CompanyName: 'Microsoft': [
     {
        Position: '1'
        StartDate: '2017-01-01',
        EndDate: '2017-04-01'
    }, {
        Position: '2'
        StartDate: '2017-04-01',
        EndDate: '2017-10-01'
    }
    ],
      CompanyName: 'Amazon' :
      [
        {
        Position: '3'
        StartDate: '2017-10-01',
        EndDate: '2018-02-01'
       }
      ],
      CompanyName: 'Microsoft' :
      [
        {
        Position: '4'
        StartDate: '2018-03-04',
        EndDate: '2018-10-04'
       }
      ]
   ]
</code>```

So Since position 4 is not the consecutive date it should not be grouped, Any ideas for this?
I don't want to group if the date difference is more than a month.

答:
In pure JavaScript, I'll go with reduce to do the task. Also let me know if this do the required task.

var data = [ { Position: '1', CompanyName: 'Microsoft', StartDate: '2017-01-01', EndDate: '2017-04-01' }, { Position: '2', CompanyName: 'Microsoft', StartDate: '2017-04-01', EndDate: '2017-10-01' }, { Position: '3', CompanyName: 'Sapient', StartDate: '2017-10-01', EndDate: '2018-02-01' }, { Position: '4', CompanyName: 'Microsoft', StartDate: '2018-03-04', EndDate: '2018-10-04' }];

var result =
data.reduce((acc,{CompanyName, ...rest})=>{
   acc[CompanyName] = acc[CompanyName] || [];
   if(acc[CompanyName].length>0){
     lastEndDt = acc[CompanyName][acc[CompanyName].length-1].EndDate;
     difference = Math.ceil(Math.abs(new Date(lastEndDt)- new Date(rest.StartDate))/(1000 * 60 * 60 * 24));
     if(difference<31){ acc[CompanyName].push(rest) } else { acc[`${CompanyName}_unordered`] =  [...(acc[`${CompanyName}_unordered`] || [] ), rest]};
     } else {
     acc[CompanyName].push(rest);
    }
  return acc;
},{});
console.log(result);```

Body:
Problem Statement

I am trying to group work experience on the basis of the company name which I am able to do. However, I want to group them only if they are consecutive jobs. The same logic LinkedIn has implemented.
I think a recursive way of grouping items based on name and date difference is needed.
for example

const data = [
    {
        Position: '1'
        CompanyName: 'Microsoft',
        StartDate: '2017-01-01',
        EndDate: '2017-04-01'
    },
    {
        Position: '2'
        CompanyName: 'Microsoft',
        StartDate: '2017-04-01',
        EndDate: '2017-10-01'
    },
        {
        Position: '3'
        CompanyName: 'Amazon',
        StartDate: '2017-10-01',
        EndDate: '2018-02-01'
    },
    {
        Position: '4'
        CompanyName: 'Microsoft',
        StartDate: '2018-03-04',
        EndDate: '2018-10-04'
    }
];

Currently, I am able to group by company name in node js using the following code

Code

/** applyGroupByPropName
* @param {Object} data this is the data object
* @param {string} propName This is the property to be grouped
* @returns {Object} returns a grouped object based on prop key
*/
    static applyGroupByPropName(data, propName) {
        if (!_.isNull(data) && !_.isEmpty(data) && data.length > 0) {
            data = _.mapValues(_.groupBy(data, propName),
                clist => clist.map(item => _.omit(item, propName)));
        }
        return data;
 }

and currently my output is like

   [
     CompanyName: 'Microsoft': [
     {
        Position: '1'
        StartDate: '2017-01-01',
        EndDate: '2017-04-01'
    }, {
        Position: '2'
        StartDate: '2017-04-01',
        EndDate: '2017-10-01'
    }, {
        Position: '4'
        StartDate: '2018-03-04',
        EndDate: '2018-10-04'
    }
    ],
      CompanyName: 'Amazon' :
      [
        {
        Position: '3'
        StartDate: '2017-10-01',
        EndDate: '2018-02-01'
       }
      ]
   ]

Expected Output

   [
     CompanyName: 'Microsoft': [
     {
        Position: '1'
        StartDate: '2017-01-01',
        EndDate: '2017-04-01'
    }, {
        Position: '2'
        StartDate: '2017-04-01',
        EndDate: '2017-10-01'
    }
    ],
      CompanyName: 'Amazon' :
      [
        {
        Position: '3'
        StartDate: '2017-10-01',
        EndDate: '2018-02-01'
       }
      ],
      CompanyName: 'Microsoft' :
      [
        {
        Position: '4'
        StartDate: '2018-03-04',
        EndDate: '2018-10-04'
       }
      ]
   ]

So Since position 4 is not the consecutive date it should not be grouped, Any ideas for this?
I don't want to group if the date difference is more than a month.


问:
TF246017: team foundation server could not connect to the database
I am facing a problem with logging into TFS. I get the following error:

Exception Message: TF246017: Team Foundation Server could not connect
  to the database. Verify that the server that is hosting the database
  is operational, and that network problems are not blocking
  communication with the server. (type SoapException)SoapException
  Details:

答:
Hi the below steps worked for me.

Select Application Tier in the TFS Administration Console.

In the Application Tier Summary which contains the Service Account details.

Click Reapply Account.


问:
android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
The app is crashing when I'm trying to open a file. It works below Android Nougat, but on Android Nougat it crashes. It only crashes when I try to open a file from the SD card, not from the system partition. Some permission problem?

Sample code:

```<code>File file = new File("/storage/emulated/0/test.txt");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); // Crashes on this line
</code>```

Log:

android.os.FileUriExposedException:
  file:///storage/emulated/0/test.txt exposed beyond app through
  Intent.getData()

Edit:

When targeting Android Nougat, file:// URIs are not allowed anymore. We should use content:// URIs instead. However, my app needs to open files in root directories. Any ideas?

答:
I spent almost a day trying to figure out why I was getting this exception. After lots of struggle, this config worked perfectly (Kotlin):

AndroidManifest.xml

```<code><provider
  android:name="androidx.core.content.FileProvider"
  android:authorities="com.lomza.moviesroom.fileprovider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/file_paths" />
</provider>
</code>```

file_paths.xml

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

Intent itself

```<code>fun goToFileIntent(context: Context, file: File): Intent {
    val intent = Intent(Intent.ACTION_VIEW)
    val contentUri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
    val mimeType = context.contentResolver.getType(contentUri)
    intent.setDataAndType(contentUri, mimeType)
    intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION

    return intent
}
</code>```

I explain the whole process here.

Body:
The app is crashing when I'm trying to open a file. It works below Android Nougat, but on Android Nougat it crashes. It only crashes when I try to open a file from the SD card, not from the system partition. Some permission problem?

Sample code:

File file = new File("/storage/emulated/0/test.txt");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); // Crashes on this line

Log:

android.os.FileUriExposedException:
  file:///storage/emulated/0/test.txt exposed beyond app through
  Intent.getData()

Edit:

When targeting Android Nougat, file:// URIs are not allowed anymore. We should use content:// URIs instead. However, my app needs to open files in root directories. Any ideas?

Body:
I spent almost a day trying to figure out why I was getting this exception. After lots of struggle, this config worked perfectly (Kotlin):

AndroidManifest.xml

<provider
  android:name="androidx.core.content.FileProvider"
  android:authorities="com.lomza.moviesroom.fileprovider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/file_paths" />
</provider>

file_paths.xml

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

Intent itself

fun goToFileIntent(context: Context, file: File): Intent {
    val intent = Intent(Intent.ACTION_VIEW)
    val contentUri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
    val mimeType = context.contentResolver.getType(contentUri)
    intent.setDataAndType(contentUri, mimeType)
    intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION

    return intent
}

I explain the whole process here.


问:
Removing the first element from a queue C++
I'm trying to remove the first element of the Queue but, this does not seem to work. Here is my code:</p>

```<code>struct List {
    //string name;
    double price;
    List* next;
};
List* head = NULL; List* tail = NULL;
struct queue
{
    List* head, * tail;
};
void printAll()
{
    cout << "Data in the queue:\t";
    for (List* temp = head; temp != NULL; temp = temp->next)
    {
        cout << temp->price << "\t";

        if (temp->next == NULL)
        {
            delete temp; // here I don’t know how to write it down
        }
}
</code>```

答:
Remember that using existing containers is much easier to get results. In this case, removing the oldest entry in a std::queue would be if (! myQueue.empty()) myQueue.pop(); with added safety that there is actually to delete.

However, to learn programming, it makes sense to make your own containers and there are even circumstances where own containers perform better, so about your question: when changing anything in a linked list, the pointers have to be updated to still have a consistent linked list, so to remove an entry, the pointer to the entry has to point to the next entry and then the selected entry can be deleted. In case of the first entry, that's the one that head is pointing to, so just point to that with a temporary pointer, let the head pointer point to what the first entry is pointing to and then you can safely delete the first entry via the temporary pointer.

If in your example, you actually fill the queue at the head side and remove at the tail side, you would always need to iterate to find the last but one element to set its pointer to null and let tail point to it. This is not a good idea on a singly linked list. Fill at the tail and remove at the head side.

Also, make sure to not change data in "print"-functions. Make functions predictable by not doing more than is announced by the name. A better name for the current function could be "finishExample" or "processQueue" which can do an output and cleanup.

If you feel like cheating, or need some inspiration, this gives an example implementation: https://www.geeksforgeeks.org/queue-linked-list-implementation/ where enQueue() fills and deQueue() removes. (I just googled an example, so I can't say how good it actually is.)

Body:
I'm trying to remove the first element of the Queue but, this does not seem to work. Here is my code:

struct List {
    //string name;
    double price;
    List* next;
};
List* head = NULL; List* tail = NULL;
struct queue
{
    List* head, * tail;
};
void printAll()
{
    cout << "Data in the queue:\t";
    for (List* temp = head; temp != NULL; temp = temp->next)
    {
        cout << temp->price << "\t";

        if (temp->next == NULL)
        {
            delete temp; // here I don’t know how to write it down
        }
}