问:
Find the average values by grouping and sub-grouping variables, and count of the number of times a value occurs within these groups in R
I have a dataset which has four columns of data.

I want to group the rows by two variables, and the columns by one variable

Here is an example of my data

```<code>df <- data.frame(
Price = rnorm(24),
Grouping = rep(c("CD", "NW", "SMK", "ghd"),6),
Sub_grouping = c("CDapple", "NWapple", "SMKapple", "ghdapple",
               "CDPear", "NWpear", "SMKpear", "ghdpear",
               "CDgrape",  "NWgrape", "SMKgrape", "ghdgrape",
               "CDapple", "NWapple", "SMKapple", "ghdapple",
               "CDPear", "NWpear", "SMKpear", "ghdpear",
               "CDgrape",  "NWgrape", "SMKgrape", "ghdgrape"),
SP = rep(c("SP", "OffSP"),12))
</code>```

To get the average of the Price variable for each subgroup, I can run the following:

```<code>df <- melt(df)
df_mean <- dcast(df, Grouping + Sub_grouping ~ SP, value.var = "value",  fun.aggregate = mean)
</code>```

I would also like the average value of Price for each grouping variable. Is this possible?

I also would like to count the number of values for Price which feed into each average Price. So for each Group, by SP and OffSP, the number of prices which feed into this; and for each sub_group, by SP and OffSP, the number of prices which feed into this.

Does anyone know how to do this?

I've seen these questions Create a column with a count of occurrences in R  How can I count the number of instances a value occurs within a subgroup in R?
But their contingency tables are 2x2, and I need a table with grouping and sub-group as rows, with SP / OffSP as columns.

Thanks

答:
We don't need to reshape it to 'long' format to get the mean values

```<code>library(dplyr)
df %>%
   group_by(Grouping) %>% #first grouping
   #create the mean column and the count by 'Grouping'
   mutate(AvgPrice = mean(Price), n1 = n()) %>%
   group_by(Sub_grouping, add= TRUE) %>% #second grouping
   #summarise to get the mean within Sub_grouping and count the values with n()
   summarise(AvgPrice = first(AvgPrice), n1 = first(n1), AvgPrice2 = mean(Price), n2 = n())
</code>```

NOTE: If we also need to group by 'SP', then change the first group_by statement to

```<code>df
  %>%
   group_by(Grouping, SP) %>%
   ...
   ...
</code>```

If we want to get the mean and length for each 'SP' and wants as separate column, one compact option is dcast from data.table which can take multiple functions and multiple value.var columns

```<code>library(data.table)
dcast(setDT(df), Grouping + Sub_grouping ~ SP, value.var = "Price", c(mean, length))
</code>```

Body:
I have a dataset which has four columns of data.

I want to group the rows by two variables, and the columns by one variable

Here is an example of my data

df <- data.frame(
Price = rnorm(24),
Grouping = rep(c("CD", "NW", "SMK", "ghd"),6),
Sub_grouping = c("CDapple", "NWapple", "SMKapple", "ghdapple",
               "CDPear", "NWpear", "SMKpear", "ghdpear",
               "CDgrape",  "NWgrape", "SMKgrape", "ghdgrape",
               "CDapple", "NWapple", "SMKapple", "ghdapple",
               "CDPear", "NWpear", "SMKpear", "ghdpear",
               "CDgrape",  "NWgrape", "SMKgrape", "ghdgrape"),
SP = rep(c("SP", "OffSP"),12))

To get the average of the Price variable for each subgroup, I can run the following:

df <- melt(df)
df_mean <- dcast(df, Grouping + Sub_grouping ~ SP, value.var = "value",  fun.aggregate = mean)

I would also like the average value of Price for each grouping variable. Is this possible?

I also would like to count the number of values for Price which feed into each average Price. So for each Group, by SP and OffSP, the number of prices which feed into this; and for each sub_group, by SP and OffSP, the number of prices which feed into this.

Does anyone know how to do this?

I've seen these questions Create a column with a count of occurrences in R  How can I count the number of instances a value occurs within a subgroup in R?
But their contingency tables are 2x2, and I need a table with grouping and sub-group as rows, with SP / OffSP as columns.

Thanks

Body:
We don't need to reshape it to 'long' format to get the mean values

library(dplyr)
df %>%
   group_by(Grouping) %>% #first grouping
   #create the mean column and the count by 'Grouping'
   mutate(AvgPrice = mean(Price), n1 = n()) %>%
   group_by(Sub_grouping, add= TRUE) %>% #second grouping
   #summarise to get the mean within Sub_grouping and count the values with n()
   summarise(AvgPrice = first(AvgPrice), n1 = first(n1), AvgPrice2 = mean(Price), n2 = n())

NOTE: If we also need to group by 'SP', then change the first group_by statement to

df
  %>%
   group_by(Grouping, SP) %>%
   ...
   ...

If we want to get the mean and length for each 'SP' and wants as separate column, one compact option is dcast from data.table which can take multiple functions and multiple value.var columns

library(data.table)
dcast(setDT(df), Grouping + Sub_grouping ~ SP, value.var = "Price", c(mean, length))


来源: stackexchange

问:
Azure Data Lake Service-to-service authentication client secret, AdalServiceException and WebException
Tyring to use the below docs to get this up and running for my console app that I plan to port to Azure Functions. https://learn.microsoft.com/en-us/azure/data-lake-store/data-lake-store-get-started-net-sdk

The code below is where I'm getting stuck

CODE SNIP

```<code>// Service principal / appplication authentication with client secret / key
// Use the client ID of an existing AAD "Web App" application.
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

var domain = "<AAD-directory-domain>";
var webApp_clientId = "<AAD-application-clientid>";
var clientSecret = "<AAD-application-client-secret>";
var clientCredential = new ClientCredential(webApp_clientId, clientSecret);
var creds = await ApplicationTokenProvider.LoginSilentAsync(domain, clientCredential);
</code>```

MY IMPLEMENTATION

```<code>SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
var domain = "https://microsoft.onmicrosoft.com";
var webApp_clientId = "<my-client-id>";
var clientSecret = "<my-client-secret>";
var clientCredential = new ClientCredential(webApp_clientId, clientSecret);
var creds = await ApplicationTokenProvider.LoginSilentAsync(domain, clientCredential);

SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

_adlsClient = new DataLakeStoreAccountManagementClient(creds) { SubscriptionId = _subId };
_adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(creds);

await _adlsFileSystemClient.FileSystem.MkdirsAsync("<name-of-my-dlstore>", "tempdir");
</code>```

I also made sure to give my app permissions to my specified folder in Azure Data Lake instance:

I also made sure to give all child folders in this directory the same level or permissions:

Assigned permissions to file path

When I run my implementation I get the below errors. Any advice SO?
System.AggregateException: 'One or more errors occurred.'

Inner Exception 1

AdalServiceException: AADSTS90002: Requested tenant identifier 'https:' is not valid.

Trace ID: d1718b0a-0533-4708-a311-4e1622840100

Correlation ID: a1544df2-692e-43d2-8acf-25a847956fb6

Timestamp: 2017-03-29 01:30:18Z

Inner Exception 2

WebException: The remote server returned an error: (400) Bad Request.

AS PART OF SOLUTION
Need to make sure to give root folder read, write, execute permissions, (this will trickle down to the one folder you want to give these permissions for) then remove those permissions from all other folders you don't want these permissions assigned too, making sure you select the option to remove these permissions for that sub folder and all it's kiddos/children.

答:
AdalServiceException: AADSTS90002: Requested tenant identifier 'https:' is not valid.

That is your tenant name ,like "microsoft.onmicrosoft.com" .

WebException: The remote server returned an error: (400) Bad Request.

What is the detail error message , please refer to tutorial :

https://learn.microsoft.com/en-us/azure/data-lake-store/data-lake-store-get-started-net-sdk

I followed the detail steps to use service-to-service authentication with client secret , and successfully create a directory .  Code below is for your reference :

```<code>  public static async Task  CreateDirectory()
    {

        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
        var domain = "microsoft.onmicrosoft.com";
        var webApp_clientId = "client id";
        var clientSecret = "client secret";
        var clientCredential = new ClientCredential(webApp_clientId, clientSecret);
        var creds = ApplicationTokenProvider.LoginSilentAsync(domain, clientCredential).Result;

        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

        _adlsClient = new DataLakeStoreAccountManagementClient(creds) { SubscriptionId = "_subId" };
        _adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(creds);

        await _adlsFileSystemClient.FileSystem.MkdirsAsync("_adlsAccountName", "tempdir");

    }
    static void Main(string[] args)
    {
      CreateDirectory().Wait();
    }
</code>```

EDIT

You need to assign Execute permission to your app if you want to create a directory  . Tenant ID and tenant name are both available ,means :

```<code> var domain = "microsoft.onmicrosoft.com";
 //you could also use tenant id
 var domain = "Your tenant ID";
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Tyring to use the below docs to get this up and running for my console app that I plan to port to Azure Functions. https://learn.microsoft.com/en-us/azure/data-lake-store/data-lake-store-get-started-net-sdk

The code below is where I'm getting stuck

CODE SNIP

// Service principal / appplication authentication with client secret / key
// Use the client ID of an existing AAD "Web App" application.
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

var domain = "<AAD-directory-domain>";
var webApp_clientId = "<AAD-application-clientid>";
var clientSecret = "<AAD-application-client-secret>";
var clientCredential = new ClientCredential(webApp_clientId, clientSecret);
var creds = await ApplicationTokenProvider.LoginSilentAsync(domain, clientCredential);

MY IMPLEMENTATION

SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
var domain = "https://microsoft.onmicrosoft.com";
var webApp_clientId = "<my-client-id>";
var clientSecret = "<my-client-secret>";
var clientCredential = new ClientCredential(webApp_clientId, clientSecret);
var creds = await ApplicationTokenProvider.LoginSilentAsync(domain, clientCredential);

SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

_adlsClient = new DataLakeStoreAccountManagementClient(creds) { SubscriptionId = _subId };
_adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(creds);

await _adlsFileSystemClient.FileSystem.MkdirsAsync("<name-of-my-dlstore>", "tempdir");

I also made sure to give my app permissions to my specified folder in Azure Data Lake instance:

I also made sure to give all child folders in this directory the same level or permissions:

Assigned permissions to file path

When I run my implementation I get the below errors. Any advice SO?
System.AggregateException: 'One or more errors occurred.'

Inner Exception 1

AdalServiceException: AADSTS90002: Requested tenant identifier 'https:' is not valid.

Trace ID: d1718b0a-0533-4708-a311-4e1622840100

Correlation ID: a1544df2-692e-43d2-8acf-25a847956fb6

Timestamp: 2017-03-29 01:30:18Z

Inner Exception 2

WebException: The remote server returned an error: (400) Bad Request.

AS PART OF SOLUTION
Need to make sure to give root folder read, write, execute permissions, (this will trickle down to the one folder you want to give these permissions for) then remove those permissions from all other folders you don't want these permissions assigned too, making sure you select the option to remove these permissions for that sub folder and all it's kiddos/children.

Body:
AdalServiceException: AADSTS90002: Requested tenant identifier 'https:' is not valid.

That is your tenant name ,like "microsoft.onmicrosoft.com" .

WebException: The remote server returned an error: (400) Bad Request.

What is the detail error message , please refer to tutorial :

https://learn.microsoft.com/en-us/azure/data-lake-store/data-lake-store-get-started-net-sdk

I followed the detail steps to use service-to-service authentication with client secret , and successfully create a directory .  Code below is for your reference :

  public static async Task  CreateDirectory()
    {

        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
        var domain = "microsoft.onmicrosoft.com";
        var webApp_clientId = "client id";
        var clientSecret = "client secret";
        var clientCredential = new ClientCredential(webApp_clientId, clientSecret);
        var creds = ApplicationTokenProvider.LoginSilentAsync(domain, clientCredential).Result;

        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

        _adlsClient = new DataLakeStoreAccountManagementClient(creds) { SubscriptionId = "_subId" };
        _adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(creds);

        await _adlsFileSystemClient.FileSystem.MkdirsAsync("_adlsAccountName", "tempdir");

    }
    static void Main(string[] args)
    {
      CreateDirectory().Wait();
    }

EDIT

You need to assign Execute permission to your app if you want to create a directory  . Tenant ID and tenant name are both available ,means :

 var domain = "microsoft.onmicrosoft.com";
 //you could also use tenant id
 var domain = "Your tenant ID";


问:
javaFX: Wrong Merge sort animation result
I am implementing a merge sort animation with some rectangles using javaFX. I use some function of animation to do it. However, The translate route is wrong. I check my code over and over again and do not find the problem. The problem might be in the merge method, but I can not find where the problem is. I use absolute coordinates to locate nodes: javaFX:move shapes with absolute coordinates using translatetransition. Who can help me??

These are code:

```<code>public class Main extends Application {
double speed = 400;

int[] helper;

final ArrayList<Integer> CenterX = new ArrayList();
int listindex = 0;
@Override
public void start(Stage primaryStage) throws Exception {

    Pane pane = new Pane();
    ArrayList<StackPane> list = new ArrayList<>();
    Random random = new Random(5);
    for (int i = 0; i < 13; i++) {
        int num = random.nextInt(10);
        Rectangle rectangle = new Rectangle(40, (num * 10) + 50);
        rectangle.setFill(Color.valueOf("#FF7F50"));
        Text text = new Text(String.valueOf(num));
        StackPane stackPane = new StackPane();
        stackPane.setPrefSize(rectangle.getWidth(), rectangle.getHeight());
        stackPane.setId(String.valueOf(num));
        stackPane.getChildren().addAll(rectangle, text);
        StackPane.setAlignment(text,Pos.TOP_CENTER);
        stackPane.setAlignment(Pos.TOP_CENTER);
        stackPane.setTranslateX(60*i);
        list.add(stackPane);
    }

    pane.getChildren().addAll(list);

    BorderPane borderPane = new BorderPane();
    borderPane.setCenter(pane);
    HBox hBox1 = new HBox();
    Button b = new Button("Sort");

    AnchorPane bottomPane = new AnchorPane();
    hBox1.getChildren().add(b);
    bottomPane.getChildren().add(hBox1);
    borderPane.setBottom(bottomPane);

    b.setOnAction(event -> {
        SequentialTransition sq = new SequentialTransition();
        int[] = arr;
        arr = generateArray(list);
        sq = MergeSort(arr, list,sq);
        b.setDisable(true);
        sq.play();
        sq.setOnFinished(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                b.setDisable(false);
            }
        });
        b.setDisable(false);

    });

    Scene scene = new Scene(borderPane,800, 800);
    primaryStage.setTitle("Sorting");
    primaryStage.setResizable(false);
    primaryStage.setScene(scene);
    primaryStage.show();

    for (int i = 0; i < 13; i++) {
        int centerx = (int) list.get(i).getLayoutX();
        CenterX.add(i,centerx+60*i);
        System.out.println(centerx+60*i);

    }
}

private int[] generateArray(List<StackPane> list) {
    int arr[] = new int[list.size()];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = Integer.parseInt(list.get(i).getId());
    }
    return arr;
}

private TranslateTransition AddtoOriginal(StackPane sp, double speed,int X){
    TranslateTransition t = new TranslateTransition();
    t.setNode(sp);
    t.setDuration(Duration.millis(speed));
    t.setToX(X);
    t.setToY(300);
    return t;

}

public SequentialTransition MergeSort(int arr[],ArrayList<StackPane> list,SequentialTransition sq) {
    int number = arr.length;
    this.helper = new int[number];
    mergesort(0, number - 1,arr,sq,list);
    return sq;
}

private void mergesort(int low, int high,int arr[],SequentialTransition sq,ArrayList<StackPane> list) {
    // check if low is smaller then high, if not then the array is sorted
    if (low < high) {
            // Get the index of the element which is in the middle
            int middle = low + (high - low) / 2;
            // Sort the left side of the array
            mergesort(low, middle,arr,sq,list);
            // Sort the right side of the array
            mergesort(middle + 1, high,arr,sq,list);
            // Combine them both
            merge(low, middle, high,arr,list,sq);
    }

}

private void merge(int low, int middle, int high,int arr[],ArrayList<StackPane> list,SequentialTransition sq) {
// Copy both parts into the helper array
    for (int i = low; i <= high; i++) {
            helper[i] = arr[i];

    }
    int i = low;
    int j = middle + 1;
    int k = low;
    // Copy the smallest values from either the left or the right side back
    // to the original array

    while (i <= middle && j <= high) {
            if (helper[i] <= helper[j]) {
                    arr[k] = helper[i];
                    sq.getChildren().add(AddtoOriginal(list.get(i),speed,CenterX.get(k)));
                    i++;
            } else {
                    arr[k] = helper[j];
                    sq.getChildren().add(AddtoOriginal(list.get(j),speed,CenterX.get(k)));
                    j++;
            }
            k++;
    }
    // Copy the rest of the left side of the array into the target array
    while (i <= middle) {
            arr[k] = helper[i];
            sq.getChildren().add(AddtoOriginal(list.get(i),speed,CenterX.get(k)));
            k++;
            i++;
    }

    ParallelTransition pl = new ParallelTransition();
    ArrayList<TranslateTransition> Transitionlist = new ArrayList<>(high-low);

    for (int z = low; z <= high; z++) {
        TranslateTransition t = new TranslateTransition();
        t.setNode(list.get(z));
        t.setDuration(Duration.millis(speed));
        t.setByY(-300);
        Transitionlist.add(t);
}
pl.getChildren().addAll(Transitionlist);
sq.getChildren().add(pl);

}

public static void main(String[] args) {
    launch(args);
}
}
</code>```

答:
Issues with your code and how to fix them

Your main issue is that when you do something like this:

```<code>arr[k] = helper[j];
sq.getChildren().add(AddtoOriginal(list.get(j),speed,CenterX.get(k)));
</code>```

What you are doing is having some arrays (arr and helper) that represent the values being sorted and you move the values within the positions in the array (in the assignment), but when you run the AddToOriginal routine you are not also moving the values in the list which is representing the visual display.  So what is happening is that the visual display is becoming out of sync with the sorted array.

Also the merge sort algorithm (as you have it implemented) is not an in place sort in memory, there are actually two arrays involved, the arr array and the helper array, the helper is necessary to keep track of original values when you assign arr values so that the original values don't get overwritten.  You need to do the same thing with the visual representation.  For the sample code I implemented below based upon your original code, what I did was add an extra array of helperNodes which keep track of the positional references of the helper array, but in a visual form.

Putting both those things together, whenever you swap a node, you do an extra statement like this, to keep the visual list inline with the value array that you are manipulating:

```<code>arr[k] = helper[j];
list.set(k, helperNodes[j]);
sq.getChildren().add(move(helperNodes[j], k * SPACING));
</code>```

Also, note that the swapping move is based upon the unmutated helperNodes[j] elements and not the list.get(j) elements, which may have already been mutated.  What the above code is doing is mirroring the logic of the value assignment with the manipulation of the visual list array and the animated move in the sq sequential transition.

One additional issue is that the algorithm you have for merge sort doesn't do anything when nodes in the right part of the merge segment to be sorted are already in order.  However, you are performing an animated move of all of the elements in a merge segment back up to their original starting height.  So you need to add a little extra code to do that visual animation even though the value position in the array hasn't changed.

If you found this difficult, don't worry (it's not as easy as it seems IMO :-)

Credit

I am guessing (perhaps wrongly) that your merge sorting algorithm was based on the Vogella Merge Sort Tutorial.  If so, it is nice to acknowledge that in the question as it helps understand the source of inspiration in context (if not, you can just ignore this note).

Unsorted

Sorting In Progress

Sorted

Sample App

```<code>import javafx.animation.*;
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.*;

public class Merge extends Application {
    private static final int N_VALUES = 13;
    private static final int SPACING = 60;
    private static final int SORT_GROUP_MOVE_DELTA = 200;

    private static final Duration SPEED = Duration.millis(400);

    private int[] helper;
    private StackPane[] helperNodes;
    private Random random = new Random(5);

    @Override
    public void start(Stage stage) throws Exception {
        Pane displayPane = new Pane();
        ArrayList<StackPane> list = new ArrayList<>();
        for (int i = 0; i < N_VALUES; i++) {
            StackPane stackPane = createValueNode(i);
            list.add(stackPane);
        }

        displayPane.getChildren().addAll(list);

        Button sortButton = new Button("Sort");
        sortButton.setOnAction(event -> {
            SequentialTransition sq = new SequentialTransition();
            int[] arr = generateArray(list);
            sq = mergeSort(arr, list, sq);
            sortButton.setDisable(true);
            sq.play();
            sq.setOnFinished(event1 -> sortButton.setDisable(false));
            sortButton.setDisable(false);
        });

        BorderPane borderPane = new BorderPane();
        borderPane.setCenter(displayPane);
        borderPane.setBottom(sortButton);
        BorderPane.setAlignment(sortButton, Pos.CENTER);
        BorderPane.setMargin(sortButton, new Insets(10));

        Scene scene = new Scene(borderPane, 800, 400);
        stage.setTitle("Sorting");
        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

    private StackPane createValueNode(int i) {
        int num = random.nextInt(10);
        Rectangle rectangle = new Rectangle(40, (num * 10) + 50);
        rectangle.setFill(Color.valueOf("#FF7F50"));
        Text text = new Text(String.valueOf(num));
        StackPane stackPane = new StackPane();
        stackPane.setPrefSize(rectangle.getWidth(), rectangle.getHeight());
        stackPane.setId(String.valueOf(num));
        stackPane.getChildren().addAll(rectangle, text);
        StackPane.setAlignment(text, Pos.TOP_CENTER);
        stackPane.setAlignment(Pos.TOP_CENTER);
        stackPane.setTranslateX(SPACING * i);
        return stackPane;
    }

    private int[] generateArray(List<StackPane> list) {
        int arr[] = new int[list.size()];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = Integer.parseInt(list.get(i).getId());
        }
        return arr;
    }

    private TranslateTransition move(StackPane sp, int X) {
        TranslateTransition t = new TranslateTransition();
        t.setNode(sp);
        t.setDuration(SPEED);
        t.setToX(X);
        t.setToY(SORT_GROUP_MOVE_DELTA);
        return t;

    }

    public SequentialTransition mergeSort(int arr[], ArrayList<StackPane> list, SequentialTransition sq) {
        int number = arr.length;
        this.helper = new int[number];
        this.helperNodes = new StackPane[number];
        sortRange(0, number - 1, arr, sq, list);
        return sq;
    }

    private void sortRange(int low, int high, int arr[], SequentialTransition sq, ArrayList<StackPane> list) {
        // check if low is smaller then high, if not then the array is sorted
        if (low < high) {
            // Get the index of the element which is in the middle
            int middle = low + (high - low) / 2;
            // Sort the left side of the array
            sortRange(low, middle, arr, sq, list);
            // Sort the right side of the array
            sortRange(middle + 1, high, arr, sq, list);
            // Combine them both
            merge(low, middle, high, arr, list, sq);
        }
    }

    private void merge(int low, int middle, int high, int arr[], ArrayList<StackPane> list, SequentialTransition sq) {
        // Copy both parts into the helper array
        for (int i = low; i <= high; i++) {
            helper[i] = arr[i];
            helperNodes[i] = list.get(i);
        }

        int i = low;
        int j = middle + 1;
        int k = low;
        // Copy the smallest values from either the left or the right side back
        // to the original array

        while (i <= middle && j <= high) {
            if (helper[i] <= helper[j]) {
                arr[k] = helper[i];
                list.set(k, helperNodes[i]);
                sq.getChildren().add(move(helperNodes[i], k * SPACING));
                i++;
            } else {
                arr[k] = helper[j];
                list.set(k, helperNodes[j]);
                sq.getChildren().add(move(helperNodes[j], k * SPACING));
                j++;
            }
            k++;
        }
        // Copy the rest of the left side of the array into the target array
        while (i <= middle) {
            arr[k] = helper[i];
            list.set(k, helperNodes[i]);
            sq.getChildren().add(move(helperNodes[i], k * SPACING));
            k++;
            i++;
        }

        // Even if we didn't move in the array because it was already ordered,
        // move on screen for any remaining nodes in the target array.
        while (j <= high) {
            sq.getChildren().add(move(helperNodes[j], k * SPACING));
            k++;
            j++;
        }

        ParallelTransition moveUp = new ParallelTransition();

        for (int z = low; z <= high; z++) {
            TranslateTransition moveNodeUp = new TranslateTransition();
            moveNodeUp.setNode(helperNodes[z]);
            moveNodeUp.setDuration(SPEED);
            moveNodeUp.setByY(-SORT_GROUP_MOVE_DELTA);
            moveUp.getChildren().add(moveNodeUp);
        }

        sq.getChildren().add(moveUp);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
</code>```

Possible Alternate Implementation

One thing you could do is create a SortableNode class to replace the StackPane that you are defining to hold the values.  The sortable node could keep the value of the node in a field rather than in an ID.  The sortable node could also implement Comparable.  Then your merge sort algorithm could be updated to take a list of comparable objects as input rather than an array of ints.  That way you wouldn't need to keep track of separate arrays for the values and visual representations within the sort
algorithm (and keep them in sync).  That would likely simplify the implementation a little bit.  But I won't add an additional sample here to implement this alternate approach (as the current sample above seems to work just fine ;-)

Body:
I am implementing a merge sort animation with some rectangles using javaFX. I use some function of animation to do it. However, The translate route is wrong. I check my code over and over again and do not find the problem. The problem might be in the merge method, but I can not find where the problem is. I use absolute coordinates to locate nodes: javaFX:move shapes with absolute coordinates using translatetransition. Who can help me??

These are code:

public class Main extends Application {
double speed = 400;

int[] helper;

final ArrayList<Integer> CenterX = new ArrayList();
int listindex = 0;
@Override
public void start(Stage primaryStage) throws Exception {

    Pane pane = new Pane();
    ArrayList<StackPane> list = new ArrayList<>();
    Random random = new Random(5);
    for (int i = 0; i < 13; i++) {
        int num = random.nextInt(10);
        Rectangle rectangle = new Rectangle(40, (num * 10) + 50);
        rectangle.setFill(Color.valueOf("#FF7F50"));
        Text text = new Text(String.valueOf(num));
        StackPane stackPane = new StackPane();
        stackPane.setPrefSize(rectangle.getWidth(), rectangle.getHeight());
        stackPane.setId(String.valueOf(num));
        stackPane.getChildren().addAll(rectangle, text);
        StackPane.setAlignment(text,Pos.TOP_CENTER);
        stackPane.setAlignment(Pos.TOP_CENTER);
        stackPane.setTranslateX(60*i);
        list.add(stackPane);
    }

    pane.getChildren().addAll(list);

    BorderPane borderPane = new BorderPane();
    borderPane.setCenter(pane);
    HBox hBox1 = new HBox();
    Button b = new Button("Sort");

    AnchorPane bottomPane = new AnchorPane();
    hBox1.getChildren().add(b);
    bottomPane.getChildren().add(hBox1);
    borderPane.setBottom(bottomPane);

    b.setOnAction(event -> {
        SequentialTransition sq = new SequentialTransition();
        int[] = arr;
        arr = generateArray(list);
        sq = MergeSort(arr, list,sq);
        b.setDisable(true);
        sq.play();
        sq.setOnFinished(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                b.setDisable(false);
            }
        });
        b.setDisable(false);

    });

    Scene scene = new Scene(borderPane,800, 800);
    primaryStage.setTitle("Sorting");
    primaryStage.setResizable(false);
    primaryStage.setScene(scene);
    primaryStage.show();

    for (int i = 0; i < 13; i++) {
        int centerx = (int) list.get(i).getLayoutX();
        CenterX.add(i,centerx+60*i);
        System.out.println(centerx+60*i);

    }
}

private int[] generateArray(List<StackPane> list) {
    int arr[] = new int[list.size()];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = Integer.parseInt(list.get(i).getId());
    }
    return arr;
}

private TranslateTransition AddtoOriginal(StackPane sp, double speed,int X){
    TranslateTransition t = new TranslateTransition();
    t.setNode(sp);
    t.setDuration(Duration.millis(speed));
    t.setToX(X);
    t.setToY(300);
    return t;

}

public SequentialTransition MergeSort(int arr[],ArrayList<StackPane> list,SequentialTransition sq) {
    int number = arr.length;
    this.helper = new int[number];
    mergesort(0, number - 1,arr,sq,list);
    return sq;
}

private void mergesort(int low, int high,int arr[],SequentialTransition sq,ArrayList<StackPane> list) {
    // check if low is smaller then high, if not then the array is sorted
    if (low < high) {
            // Get the index of the element which is in the middle
            int middle = low + (high - low) / 2;
            // Sort the left side of the array
            mergesort(low, middle,arr,sq,list);
            // Sort the right side of the array
            mergesort(middle + 1, high,arr,sq,list);
            // Combine them both
            merge(low, middle, high,arr,list,sq);
    }

}

private void merge(int low, int middle, int high,int arr[],ArrayList<StackPane> list,SequentialTransition sq) {
// Copy both parts into the helper array
    for (int i = low; i <= high; i++) {
            helper[i] = arr[i];

    }
    int i = low;
    int j = middle + 1;
    int k = low;
    // Copy the smallest values from either the left or the right side back
    // to the original array

    while (i <= middle && j <= high) {
            if (helper[i] <= helper[j]) {
                    arr[k] = helper[i];
                    sq.getChildren().add(AddtoOriginal(list.get(i),speed,CenterX.get(k)));
                    i++;
            } else {
                    arr[k] = helper[j];
                    sq.getChildren().add(AddtoOriginal(list.get(j),speed,CenterX.get(k)));
                    j++;
            }
            k++;
    }
    // Copy the rest of the left side of the array into the target array
    while (i <= middle) {
            arr[k] = helper[i];
            sq.getChildren().add(AddtoOriginal(list.get(i),speed,CenterX.get(k)));
            k++;
            i++;
    }

    ParallelTransition pl = new ParallelTransition();
    ArrayList<TranslateTransition> Transitionlist = new ArrayList<>(high-low);

    for (int z = low; z <= high; z++) {
        TranslateTransition t = new TranslateTransition();
        t.setNode(list.get(z));
        t.setDuration(Duration.millis(speed));
        t.setByY(-300);
        Transitionlist.add(t);
}
pl.getChildren().addAll(Transitionlist);
sq.getChildren().add(pl);

}

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

Body:
Issues with your code and how to fix them

Your main issue is that when you do something like this:

arr[k] = helper[j];
sq.getChildren().add(AddtoOriginal(list.get(j),speed,CenterX.get(k)));

What you are doing is having some arrays (arr and helper) that represent the values being sorted and you move the values within the positions in the array (in the assignment), but when you run the AddToOriginal routine you are not also moving the values in the list which is representing the visual display.  So what is happening is that the visual display is becoming out of sync with the sorted array.

Also the merge sort algorithm (as you have it implemented) is not an in place sort in memory, there are actually two arrays involved, the arr array and the helper array, the helper is necessary to keep track of original values when you assign arr values so that the original values don't get overwritten.  You need to do the same thing with the visual representation.  For the sample code I implemented below based upon your original code, what I did was add an extra array of helperNodes which keep track of the positional references of the helper array, but in a visual form.

Putting both those things together, whenever you swap a node, you do an extra statement like this, to keep the visual list inline with the value array that you are manipulating:

arr[k] = helper[j];
list.set(k, helperNodes[j]);
sq.getChildren().add(move(helperNodes[j], k * SPACING));

Also, note that the swapping move is based upon the unmutated helperNodes[j] elements and not the list.get(j) elements, which may have already been mutated.  What the above code is doing is mirroring the logic of the value assignment with the manipulation of the visual list array and the animated move in the sq sequential transition.

One additional issue is that the algorithm you have for merge sort doesn't do anything when nodes in the right part of the merge segment to be sorted are already in order.  However, you are performing an animated move of all of the elements in a merge segment back up to their original starting height.  So you need to add a little extra code to do that visual animation even though the value position in the array hasn't changed.

If you found this difficult, don't worry (it's not as easy as it seems IMO :-)

Credit

I am guessing (perhaps wrongly) that your merge sorting algorithm was based on the Vogella Merge Sort Tutorial.  If so, it is nice to acknowledge that in the question as it helps understand the source of inspiration in context (if not, you can just ignore this note).

Unsorted

Sorting In Progress

Sorted

Sample App

import javafx.animation.*;
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.*;

public class Merge extends Application {
    private static final int N_VALUES = 13;
    private static final int SPACING = 60;
    private static final int SORT_GROUP_MOVE_DELTA = 200;

    private static final Duration SPEED = Duration.millis(400);

    private int[] helper;
    private StackPane[] helperNodes;
    private Random random = new Random(5);

    @Override
    public void start(Stage stage) throws Exception {
        Pane displayPane = new Pane();
        ArrayList<StackPane> list = new ArrayList<>();
        for (int i = 0; i < N_VALUES; i++) {
            StackPane stackPane = createValueNode(i);
            list.add(stackPane);
        }

        displayPane.getChildren().addAll(list);

        Button sortButton = new Button("Sort");
        sortButton.setOnAction(event -> {
            SequentialTransition sq = new SequentialTransition();
            int[] arr = generateArray(list);
            sq = mergeSort(arr, list, sq);
            sortButton.setDisable(true);
            sq.play();
            sq.setOnFinished(event1 -> sortButton.setDisable(false));
            sortButton.setDisable(false);
        });

        BorderPane borderPane = new BorderPane();
        borderPane.setCenter(displayPane);
        borderPane.setBottom(sortButton);
        BorderPane.setAlignment(sortButton, Pos.CENTER);
        BorderPane.setMargin(sortButton, new Insets(10));

        Scene scene = new Scene(borderPane, 800, 400);
        stage.setTitle("Sorting");
        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

    private StackPane createValueNode(int i) {
        int num = random.nextInt(10);
        Rectangle rectangle = new Rectangle(40, (num * 10) + 50);
        rectangle.setFill(Color.valueOf("#FF7F50"));
        Text text = new Text(String.valueOf(num));
        StackPane stackPane = new StackPane();
        stackPane.setPrefSize(rectangle.getWidth(), rectangle.getHeight());
        stackPane.setId(String.valueOf(num));
        stackPane.getChildren().addAll(rectangle, text);
        StackPane.setAlignment(text, Pos.TOP_CENTER);
        stackPane.setAlignment(Pos.TOP_CENTER);
        stackPane.setTranslateX(SPACING * i);
        return stackPane;
    }

    private int[] generateArray(List<StackPane> list) {
        int arr[] = new int[list.size()];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = Integer.parseInt(list.get(i).getId());
        }
        return arr;
    }

    private TranslateTransition move(StackPane sp, int X) {
        TranslateTransition t = new TranslateTransition();
        t.setNode(sp);
        t.setDuration(SPEED);
        t.setToX(X);
        t.setToY(SORT_GROUP_MOVE_DELTA);
        return t;

    }

    public SequentialTransition mergeSort(int arr[], ArrayList<StackPane> list, SequentialTransition sq) {
        int number = arr.length;
        this.helper = new int[number];
        this.helperNodes = new StackPane[number];
        sortRange(0, number - 1, arr, sq, list);
        return sq;
    }

    private void sortRange(int low, int high, int arr[], SequentialTransition sq, ArrayList<StackPane> list) {
        // check if low is smaller then high, if not then the array is sorted
        if (low < high) {
            // Get the index of the element which is in the middle
            int middle = low + (high - low) / 2;
            // Sort the left side of the array
            sortRange(low, middle, arr, sq, list);
            // Sort the right side of the array
            sortRange(middle + 1, high, arr, sq, list);
            // Combine them both
            merge(low, middle, high, arr, list, sq);
        }
    }

    private void merge(int low, int middle, int high, int arr[], ArrayList<StackPane> list, SequentialTransition sq) {
        // Copy both parts into the helper array
        for (int i = low; i <= high; i++) {
            helper[i] = arr[i];
            helperNodes[i] = list.get(i);
        }

        int i = low;
        int j = middle + 1;
        int k = low;
        // Copy the smallest values from either the left or the right side back
        // to the original array

        while (i <= middle && j <= high) {
            if (helper[i] <= helper[j]) {
                arr[k] = helper[i];
                list.set(k, helperNodes[i]);
                sq.getChildren().add(move(helperNodes[i], k * SPACING));
                i++;
            } else {
                arr[k] = helper[j];
                list.set(k, helperNodes[j]);
                sq.getChildren().add(move(helperNodes[j], k * SPACING));
                j++;
            }
            k++;
        }
        // Copy the rest of the left side of the array into the target array
        while (i <= middle) {
            arr[k] = helper[i];
            list.set(k, helperNodes[i]);
            sq.getChildren().add(move(helperNodes[i], k * SPACING));
            k++;
            i++;
        }

        // Even if we didn't move in the array because it was already ordered,
        // move on screen for any remaining nodes in the target array.
        while (j <= high) {
            sq.getChildren().add(move(helperNodes[j], k * SPACING));
            k++;
            j++;
        }

        ParallelTransition moveUp = new ParallelTransition();

        for (int z = low; z <= high; z++) {
            TranslateTransition moveNodeUp = new TranslateTransition();
            moveNodeUp.setNode(helperNodes[z]);
            moveNodeUp.setDuration(SPEED);
            moveNodeUp.setByY(-SORT_GROUP_MOVE_DELTA);
            moveUp.getChildren().add(moveNodeUp);
        }

        sq.getChildren().add(moveUp);
    }

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

Possible Alternate Implementation

One thing you could do is create a SortableNode class to replace the StackPane that you are defining to hold the values.  The sortable node could keep the value of the node in a field rather than in an ID.  The sortable node could also implement Comparable.  Then your merge sort algorithm could be updated to take a list of comparable objects as input rather than an array of ints.  That way you wouldn't need to keep track of separate arrays for the values and visual representations within the sort
algorithm (and keep them in sync).  That would likely simplify the implementation a little bit.  But I won't add an additional sample here to implement this alternate approach (as the current sample above seems to work just fine ;-)


问:
Making getContentResolver() to work in class extending Fragment class

What I have in mind is to use two fragments, first one to show the contacts list and second one to show the details of contact which is being selected in the upper fragment.

The class that I'm using to extend the Fragment class does not allow me to use getContentResolver() method due to the context issue. Now I'm trying to fetch the contact in the same class which is extending Fragment class and use it to show in the list view and its details. After going through some older solution I found the way to create a function and pass Context to it as a parameter but the problem is I don't have to call it from any other class which is extending Activity. I want to do it from that same class extending Fragment.

How should I do this?

Any help will be highly appreciated.

答:
I had similar problem with a fragment, but tried </p>

```<code>(getContext().getContentResolver(), filePath);
</code>```

Body:
I had similar problem with a fragment, but tried

(getContext().getContentResolver(), filePath);


问:
Grep in partial matching in R
I can match my input ex with vector str with following code

here "exp" matches with str

```<code>str <- c("Regular", "expression", "examples of R language")
x <- grep("exp",str,value=F)
</code>```

But Instead I want to match  "expression" with str like this

Input is "expression" and it should match str "exp" in below example

```<code>str <- c("Regular", "exp", "examples of R language")`
x <- grep("expression",str,value=F)
x

#exp
</code>```

My x = "expression" should match with str "exp"and result should give "exp"

Is there a way to achieve this?

答:
We need to extract the substring.  In base R, this can be done with regexpr/regmatches

```<code>regmatches(str, regexpr("exp", str))
#[1] "exp"
</code>```

Or using stringr/stringi

```<code>library(stringr)
na.omit(str_extract(str, 'exp'))
#[1] "exp"
</code>```

Using grep we can find whether there is a partical match or not.  It returns the numeric index of the element or a logical vector (by using grepl).  With value = TRUE, it returns the element that is matched and not the partial substring

Title: Grep in partial matching in R

Body:
I can match my input ex with vector str with following code

here "exp" matches with str

str <- c("Regular", "expression", "examples of R language")
x <- grep("exp",str,value=F)

But Instead I want to match  "expression" with str like this

Input is "expression" and it should match str "exp" in below example

str <- c("Regular", "exp", "examples of R language")`
x <- grep("expression",str,value=F)
x

#exp

My x = "expression" should match with str "exp"and result should give "exp"

Is there a way to achieve this?

Body:
We need to extract the substring.  In base R, this can be done with regexpr/regmatches

regmatches(str, regexpr("exp", str))
#[1] "exp"

Or using stringr/stringi

library(stringr)
na.omit(str_extract(str, 'exp'))
#[1] "exp"

Using grep we can find whether there is a partical match or not.  It returns the numeric index of the element or a logical vector (by using grepl).  With value = TRUE, it returns the element that is matched and not the partial substring


问:
Tracking a Core Animation animation
I have two circles which move around the screen.  The circles are both UIViews which contain other UIViews.  The area outside each circle is transparent.

I have written a function to create a CGPath which connects the two circles with a quadrilateral shape.  I fill this path in a transparent CALayer which spans the entire screen.  Since the layer is behind the two circular UIViews, it appears to connect them.

Finally, the two UIViews are animated using Core Animation.  The position and size of both circles change during this animation.

So far the only method that I have had any success with is to interrupt the animation at regular intervals using an NSTimer, then recompute and draw the beam based on the location of the circle's presentationLayer.  However, the quadrilateral lags behind the circles when the animation speeds up.

Is there a better way to accomplish this using Core Animation?  Or should I avoid Core Animation and implement my own animation using an NSTimer?

答: If you need to find the current visible state of the layers, you can call -presentationLayer on the CALayer in question, and this will give you a layer that approximates the one used for rendering. Note I said approximates - it's not guaranteed to be fully accurate. However it may be good enough for your purposes.

ContentLicense: CC BY-SA 2.5

Title: Tracking a Core Animation animation


问:
Android N - Download Manager Notification Cancel Button
Android N has a new Cancel Button in the Download Manager Notification.

I would like to excecute some code in my app to stop a progressbar when the user presses this button. If any, which method is called?

Please also note that the Intent filter action  DownloadManager.ACTION_NOTIFICATION_CLICKED is triggered only when the user clicks on the notification itself, not when he/she clicks of the Cancel button.

```<code> if_downloadManager = new IntentFilter();
    if_downloadManager.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    if_downloadManager.addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED);

    br_downloadManager = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                ....
            }

            if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) {
                // This code is not executed when the user presses the Cancel Button in the Download Manager Notification
            }
        }
    };
</code>```

Thanks in advance.

答:
Malko, I did not find a solution but I am using the following workaround meanwhile.
I use the Android Handler to run every 10 seconds  resetProgressIfNoOngoingDMRequest() below :

```<code>public int numberOfOngoingDMRequest() {
    cursor = downloadManager.query(new Query());
    int res = cursor.getCount();
    cursor.close();
    return res;
}

public boolean resetProgressIfNoOngoingDMRequest() {
    if (numberOfOngoingDMRequest() == 0) {
        refreshUpdateAllButton(false);
        resetEpisodesDownloadIds();
        act.misc.notifyEpisodesDataSetChanged();
        return true;
    }
    return false;
}
</code>```

Not so nice but it does the job. And I do this only if the app is in the foreground.

Body:
Android N has a new Cancel Button in the Download Manager Notification.

I would like to excecute some code in my app to stop a progressbar when the user presses this button. If any, which method is called?

Please also note that the Intent filter action  DownloadManager.ACTION_NOTIFICATION_CLICKED is triggered only when the user clicks on the notification itself, not when he/she clicks of the Cancel button.

 if_downloadManager = new IntentFilter();
    if_downloadManager.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    if_downloadManager.addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED);

    br_downloadManager = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                ....
            }

            if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) {
                // This code is not executed when the user presses the Cancel Button in the Download Manager Notification
            }
        }
    };

Thanks in advance.

Body:
Malko, I did not find a solution but I am using the following workaround meanwhile.
I use the Android Handler to run every 10 seconds  resetProgressIfNoOngoingDMRequest() below :

public int numberOfOngoingDMRequest() {
    cursor = downloadManager.query(new Query());
    int res = cursor.getCount();
    cursor.close();
    return res;
}

public boolean resetProgressIfNoOngoingDMRequest() {
    if (numberOfOngoingDMRequest() == 0) {
        refreshUpdateAllButton(false);
        resetEpisodesDownloadIds();
        act.misc.notifyEpisodesDataSetChanged();
        return true;
    }
    return false;
}

Not so nice but it does the job. And I do this only if the app is in the foreground.


问:
Incorrect time saved during event execution
I have an event which saves data to table:

```<code>CREATE DEFINER=`root`@`i2` EVENT `AcrhiveData` ON SCHEDULE EVERY 5
                MINUTE STARTS '2017-03-13 10:45:00' ON COMPLETION NOT PRESERVE ENABLE DO
INSERT INTO `archived`(`projectNo`, `staff_id`, `longname`, `username`, `title`, `process`, `creation_time`)
SELECT a.*
FROM
(
    (
        SELECT p.projectNo,
               usr.staff_id,
               usr.longname,
               usr.username,
               p.title,
               CONCAT(upr.process, " (", upr.role, ")" ) AS process,
               NOW() AS creation_time
        FROM project p
        INNER JOIN user_project upr
            ON p.projectNo = upr.projectNo
        INNER JOIN user usr
            ON upr.username = usr.username
        WHERE EXISTS (SELECT status FROM check_change WHERE status = "1" )
    )
) AS a
ORDER BY a.projectNo
</code>```

it works but the problem is incorrect time in NOW(). if i save it at 2017-03-29-10:50:00 on my pc event will save it as 2017-03-29 02:50:00
What is the problem and how can I solve this?

答:
I think you should reset your timezone for mysql:

```<code>mysql> SET GLOBAL time_zone = '+08:00';
</code>```

Edit:

Try this:

```<code>SET time_zone = '+08:00';
INSERT INTO `archived`(`projectNo`, `staff_id`, `longname`, `username`, `title`, `process`, `creation_time`)
SELECT a.*
......
</code>```

Body:
I have an event which saves data to table:

CREATE DEFINER=`root`@`i2` EVENT `AcrhiveData` ON SCHEDULE EVERY 5
                MINUTE STARTS '2017-03-13 10:45:00' ON COMPLETION NOT PRESERVE ENABLE DO
INSERT INTO `archived`(`projectNo`, `staff_id`, `longname`, `username`, `title`, `process`, `creation_time`)
SELECT a.*
FROM
(
    (
        SELECT p.projectNo,
               usr.staff_id,
               usr.longname,
               usr.username,
               p.title,
               CONCAT(upr.process, " (", upr.role, ")" ) AS process,
               NOW() AS creation_time
        FROM project p
        INNER JOIN user_project upr
            ON p.projectNo = upr.projectNo
        INNER JOIN user usr
            ON upr.username = usr.username
        WHERE EXISTS (SELECT status FROM check_change WHERE status = "1" )
    )
) AS a
ORDER BY a.projectNo

it works but the problem is incorrect time in NOW(). if i save it at 2017-03-29-10:50:00 on my pc event will save it as 2017-03-29 02:50:00
What is the problem and how can I solve this?

Body:
I think you should reset your timezone for mysql:

mysql> SET GLOBAL time_zone = '+08:00';

Edit:

Try this:

SET time_zone = '+08:00';
INSERT INTO `archived`(`projectNo`, `staff_id`, `longname`, `username`, `title`, `process`, `creation_time`)
SELECT a.*
......


问:
Char Array to Lambda Expression
I am now learning lambda expression used in Java.
In this case, I have a problem in changing char[] array to lambda expression.
So, I would like to ask some help.
My sample code is below.

```<code>    Map<String, String> tempMap = new HashMap<String, String>();
    tempMap.put("a", "A");
    tempMap.put("b", "B");
    tempMap.put("c", "C");
    tempMap.put("d", "D");
    tempMap.put("e", "E");
    String tempStr = "abcdef";
    StringBuilder tempBuilder = new StringBuilder();
    char[] tempArray = tempStr.toCharArray();
    for(char c : tempArray) {
    tempBuilder.append(tempMap.getOrDefault(String.ValueOf(c),
    String.ValueOf(c));
    }
</code>```

Result should be "ABCDEf". Thanks.

答:
```<code>Stream.of('a','b','c','d','e','f')
      .map(String::valueOf)
      .map(c -> tempMap.getOrDefault(c,c))
      .forEach(tempBuilder::append);
</code>```

Do you mean using stream like this?

Title: Char Array to Lambda Expression

Body:
I am now learning lambda expression used in Java.
In this case, I have a problem in changing char[] array to lambda expression.
So, I would like to ask some help.
My sample code is below.

    Map<String, String> tempMap = new HashMap<String, String>();
    tempMap.put("a", "A");
    tempMap.put("b", "B");
    tempMap.put("c", "C");
    tempMap.put("d", "D");
    tempMap.put("e", "E");
    String tempStr = "abcdef";
    StringBuilder tempBuilder = new StringBuilder();
    char[] tempArray = tempStr.toCharArray();
    for(char c : tempArray) {
    tempBuilder.append(tempMap.getOrDefault(String.ValueOf(c),
    String.ValueOf(c));
    }

Result should be "ABCDEf". Thanks.

Body:
Stream.of('a','b','c','d','e','f')
      .map(String::valueOf)
      .map(c -> tempMap.getOrDefault(c,c))
      .forEach(tempBuilder::append);

Do you mean using stream like this?


问:
For loop overwriting text in HTML
My array called myEmployees has 5 names in it, yet when I run the code it only prints out 3 of them. I believe this is happening because the for loop in the script is overwriting the previous line that it wrote in the HTML document. How can I fix this?

Yearly Bulletin Board Announcements!

Congratulations to Taylor, you have been here for 9 years and you meet the magic number! You get 2 extra weeks of PTO!

Derek, thank you for your service over the past 8 years. I look forward to many more years working with you!

Tyler, no longer works here.

The above  is what shows on my screen when I run the code, there should be two other statements to appear. Any suggestions would be greatly appreciated!

```<code><body>

  <h1>Yearly Buttetin Board Announcements!</h1>
  <h2 id='win'></h2>
  <h3 id='here'></h3>
  <h4 id='notHere'></h4>

  <script src='app.js'></script>
</body>
</code>```

TypeScript

```<code>for( i = 0; i < myEmployees.length; i++ ) {
    const employee = myEmployees[i];
    let magicNumber   = employee.extraVacay;
    let stillEmployed = employee.stillEmployed;
    let timeInJob     = employee.timeInJob;
    let name          = employee.name;

    if( magicNumber > 30 && timeInJob > 5 && stillEmployed == true ) {

        document.getElementById('win').innerHTML = (`Congratulations to ${name}, you have been here for ${timeInJob} years and you meet the magic number! You get 2 extra weeks of PTO!`);

    }
    else if (stillEmployed == true) {

        document.getElementById('here').innerHTML = (`${name}, thank you for your service over the past ${timeInJob} years. I look forward to many more years working with you!`);

    }
    else {

        document.getElementById('notHere').innerHTML = (`${name}, no longer works here.`)
    }
};
</code>```

答:
The below statement is overriding the existing HTML.

```<code> document.getElementById('here').innerHTML = (`${name}, thank you for your service over the past ${timeInJob} years. I look forward to many more years working with you!`);
</code>```

You have to append the previous value to the new text. Updated code should look something like below

```<code>var prevText =  document.getElementById('here').innerHTML;
document.getElementById('here').innerHTML = prevText + (`${name}, thank you for your service over the past ${timeInJob} years. I look forward to many more years working with you!`);
</code>```

Title: For loop overwriting text in HTML

Body:
My array called myEmployees has 5 names in it, yet when I run the code it only prints out 3 of them. I believe this is happening because the for loop in the script is overwriting the previous line that it wrote in the HTML document. How can I fix this?

Yearly Bulletin Board Announcements!

Congratulations to Taylor, you have been here for 9 years and you meet the magic number! You get 2 extra weeks of PTO!

Derek, thank you for your service over the past 8 years. I look forward to many more years working with you!

Tyler, no longer works here.

The above  is what shows on my screen when I run the code, there should be two other statements to appear. Any suggestions would be greatly appreciated!

Yearly Buttetin Board Announcements!

TypeScript

for( i = 0; i < myEmployees.length; i++ ) {
    const employee = myEmployees[i];
    let magicNumber   = employee.extraVacay;
    let stillEmployed = employee.stillEmployed;
    let timeInJob     = employee.timeInJob;
    let name          = employee.name;

    if( magicNumber > 30 && timeInJob > 5 && stillEmployed == true ) {

        document.getElementById('win').innerHTML = (`Congratulations to ${name}, you have been here for ${timeInJob} years and you meet the magic number! You get 2 extra weeks of PTO!`);

    }
    else if (stillEmployed == true) {

        document.getElementById('here').innerHTML = (`${name}, thank you for your service over the past ${timeInJob} years. I look forward to many more years working with you!`);

    }
    else {

        document.getElementById('notHere').innerHTML = (`${name}, no longer works here.`)
    }
};

Body:
The below statement is overriding the existing HTML.

 document.getElementById('here').innerHTML = (`${name}, thank you for your service over the past ${timeInJob} years. I look forward to many more years working with you!`);

You have to append the previous value to the new text. Updated code should look something like below

var prevText =  document.getElementById('here').innerHTML;
document.getElementById('here').innerHTML = prevText + (`${name}, thank you for your service over the past ${timeInJob} years. I look forward to many more years working with you!`);


问:
How can I run `git diff --staged` with Fugitive?
The command :Gdiff is equivalent to running git diff on that file.

What's the equivalent for git diff --staged or git diff --cached?

答:
Update: 3/28/2017,

Current version of fugitive will do this automatically when you press D on a file.

if the file is staged, only staged changes will be showed in the diff.
If the file is not staged, then only change that are not staged will be visible.


问:
Angular formly - Set watcher on templateOptions variable
I want to set a watcher that will run a function for that field when a specific value changes in the templateOptions. The normal formly watcher can be used when you want to know that the input has been changed, so that does not work in my case. I have tried expressionProperties to but i cant get that to work eater.

I made a js Bin as an example.
There are two input fields when you mouse over one field templateOptions.mouseOver becomes true and on mouse leave the mouseOver boolean becomes false. What can i do so that when mouseOver changes a function is run?

答:
You simply can put a controller on the field if you want to do it for each individual field, or you can put it in the template itself if the function will be the same for each field, after specifying a function to run in ng-mouseOver.  Like This:

```<code>formlyConfigProvider.setWrapper([

      {
        template: [
                    'editorEnabled: {{to.editorEnabled}}',
                    '<div ng-mouseover="to.editorEnabled=true; Update()" ng-mouseleave="to.editorEnabled=false; Update()">',
                        '<formly-transclude></formly-transclude>',
                    '</div>'
                ].join(' '),
        controller: function($scope) {
           $scope.Update = function() {
              //Code to run when value changes
           }
        }
      }
    ]);
</code>```

Of if you are doing it in each individual field(if the functions you are going to be calling are going to be different for each field) you would do:

```<code>vm.fields = [
      {
        key: 'textField1',
        type: 'input',
        templateOptions: {
          label: 'Input1',
          type: 'text',
          value:vm.model.textField1,
          editorEnabled: false
        },
        controller: function($scope) {
          $scope.Run = function() {
             alert('Changed!');
          }
        }
      },
</code>```

Body:
You simply can put a controller on the field if you want to do it for each individual field, or you can put it in the template itself if the function will be the same for each field, after specifying a function to run in ng-mouseOver.  Like This:

formlyConfigProvider.setWrapper([

      {
        template: [
                    'editorEnabled: {{to.editorEnabled}}',
                    '<div ng-mouseover="to.editorEnabled=true; Update()" ng-mouseleave="to.editorEnabled=false; Update()">',
                        '<formly-transclude></formly-transclude>',
                    '</div>'
                ].join(' '),
        controller: function($scope) {
           $scope.Update = function() {
              //Code to run when value changes
           }
        }
      }
    ]);

Of if you are doing it in each individual field(if the functions you are going to be calling are going to be different for each field) you would do:

vm.fields = [
      {
        key: 'textField1',
        type: 'input',
        templateOptions: {
          label: 'Input1',
          type: 'text',
          value:vm.model.textField1,
          editorEnabled: false
        },
        controller: function($scope) {
          $scope.Run = function() {
             alert('Changed!');
          }
        }
      },


答:
You are indeed overwriting what you inserted in earlier. Instead of using a series of header tags, I would use an
 tag for 'win,' 'here,' and 'notHere', and append elements from the array when they meet the necessary conditions.

Title: For loop overwriting text in HTML

Body: You are indeed overwriting what you inserted in earlier. Instead of using a series of header tags, I would use an <ol> tag for 'win,' 'here,' and 'notHere', and append elements from the array when they meet the necessary conditions.


问:
How to zip a file while writing to it?
Does anyone know of a way to zip a stream that you are writing to? I'm trying to avoid writing the file to the disk, and was wondering if I can just compress data as you are writing it to the stream.

The use case behind this is that the raw file is going to be very large and we want to avoid having to write the entire thing unzipped onto the disk.

答:
This is commonly done for web applications using filters:

http://tim.oreilly.com/pub/a/onjava/2003/11/19/filters.html

Title: How to zip a file while writing to it?


问:
using sed or awk to remove a "checkbox" character
I have a script that has a variable that might contain some weird characters:  ✔. I need to remove them but, honestly, I don't even know where to begin to match those characters. I can't copy and paste them into my script, they just show up as ?? ?. How can a match those characters with sed or awk? I don't have the ability to use perl or php or anything much beyond sed or awk due to system availability.

答:
First, put some flag strings around your special chars and then hexdump -C so you can easily see them. Then use HEX code to write the sed command. For example:

[STEP 118] # cat file
>>> ✔<<<
[STEP 119] # hexdump -C file
00000000  3e 3e 3e f0 9f 8d bf 20  e2 9c 94 3c 3c 3c 0a     |>>>.... ...<<<.|
                   ^^^^^^^^^^^^^^^^^^^^^^^^
[STEP 120] # sed -e $'s/\xf0\x9f\x8d\xbf\x20\xe2\x9c\x94//g' file # need to use the $'...'
>>><<<
[STEP 121] #
```

Then remove the added flag strings when all is done.

Body:
First, put some flag strings around your special chars and then hexdump -C so you can easily see them. Then use HEX code to write the sed command. For example:

[STEP 118] # cat file
>>> ✔<<<
[STEP 119] # hexdump -C file
00000000  3e 3e 3e f0 9f 8d bf 20  e2 9c 94 3c 3c 3c 0a     |>>>.... ...<<<.|
                   ^^^^^^^^^^^^^^^^^^^^^^^^
[STEP 120] # sed -e $'s/\xf0\x9f\x8d\xbf\x20\xe2\x9c\x94//g' file # need to use the $'...'
>>><<<
[STEP 121] #

Then remove the added flag strings when all is done.


问:
Infer rules that have missing facts
Suppose I have a medical rule: A man is healthy, he has insomnia syndrome, he is advised to take sleeping pills and meet a doctor. This rule has a certainty factor 0.9 (degree of subjective belief that a particular rule is true, range [0; 1]).

```<code>Status(Fatigue) ^ Syndrone(Insomnia)
-> Treatment(TakeSleepingPills) ^ Treatment(MeetDoctor) {CF = 0.9}
</code>```

If I has a known fact Status(Fatigue), how can I infer Treatment(TakeSleepingPills) and Treatment(MeetDoctor) without a missing fact Syndrone(Insomnia)?

There are many machine learning approaches, such as Probabilistic Mention Model, Sampling distribution inference, Bayesian inference,... But are there other ways without using machine learning?

答:
You can try to use answer set programming to derive rules and outcomes. Basically, you have to represent your problem in a form of logical equations and run a special program to solve given problem even in case of missing information. However, in my opinion it will not be simpler than machine learning.

You can read the following:

What is Answer Set Programming

Answer Set Programming via Examples

Solvers:

Potassco

SModels

Title: Infer rules that have missing facts

Body:
Suppose I have a medical rule: A man is healthy, he has insomnia syndrome, he is advised to take sleeping pills and meet a doctor. This rule has a certainty factor 0.9 (degree of subjective belief that a particular rule is true, range [0; 1]).

Status(Fatigue) ^ Syndrone(Insomnia)
-> Treatment(TakeSleepingPills) ^ Treatment(MeetDoctor) {CF = 0.9}

If I has a known fact Status(Fatigue), how can I infer Treatment(TakeSleepingPills) and Treatment(MeetDoctor) without a missing fact Syndrone(Insomnia)?

There are many machine learning approaches, such as Probabilistic Mention Model, Sampling distribution inference, Bayesian inference,... But are there other ways without using machine learning?


问:
What is the difference between applying, running and calling of celery task?
What is the difference between mytask.apply(), mytask.run() and mytask()? Which way is preferable?

答:
In my understanding:

apply: is to call task and execute locally

run:   never seen before

mytask(): just like call func

If you want to send message and execute remote,you should use apply_async or delay, referring call_task.


问:
php error Warning - implode() [function.implode]: Invalid arguments passed

/var/www/html/development/cross/doli/www/app/service/class.order_management.php(2955) : Warning - implode() [function.implode]: Invalid arguments passed

my following code looks like this -

```<code>$campaign_id = (empty($param_array['CampaignID']))?$split['campaign_sku']:$param_array['CampaignID'];
        $campaign_array = $this->get_campaign($job_type, $campaign_id, $split['skus'], $split['client_skus']);
        $job_type_array[] = $job_type;
        $this->client_obj_guid = $split['client_obj_guid'];
        $avail_param = array('client' => $this->client_obj_guid,
            'campaign' => $campaign_array[0],
            'digiSku' => $split['primary'],
            'skus' => implode(',', $split['secondary']),**The error is happening here, so I figure I would need to check $split to see if it is a array. Any help on this would be greatly appreciated.**
            'zip' => $customer_zip,
            'pos' => $pos_guid,
            'pos_sku' => $param_array['StoreID'],
            'inst' => $this->default_inst_obj_guid,
            'offer_count'=>(isset($param_array['NumberOfOfferings']))?$param_array['NumberOfOfferings']:'24',
            'job_type'=>$routing_job_type,
            'job_skus' => implode(',', $split['skus']),
            'total_capacity_units'=>$sku_array[$job_type]['capacity_units']);
</code>```

答:
The function implode is expecting an array, but the parameter passed to it may be not an array. So, you have to check if $split['secondary'] is an array or not. You can check this as below:

'skus' => is_array($split['secondary']) ? implode(',', $split['secondary']) : ''

This code will put empty string '' into skus if $split['secondary'] is not an array.

Body:
/var/www/html/development/cross/doli/www/app/service/class.order_management.php(2955) : Warning - implode() [function.implode]: Invalid arguments passed

my following code looks like this -

$campaign_id = (empty($param_array['CampaignID']))?$split['campaign_sku']:$param_array['CampaignID'];
        $campaign_array = $this->get_campaign($job_type, $campaign_id, $split['skus'], $split['client_skus']);
        $job_type_array[] = $job_type;
        $this->client_obj_guid = $split['client_obj_guid'];
        $avail_param = array('client' => $this->client_obj_guid,
            'campaign' => $campaign_array[0],
            'digiSku' => $split['primary'],
            'skus' => implode(',', $split['secondary']),**The error is happening here, so I figure I would need to check $split to see if it is a array. Any help on this would be greatly appreciated.**
            'zip' => $customer_zip,
            'pos' => $pos_guid,
            'pos_sku' => $param_array['StoreID'],
            'inst' => $this->default_inst_obj_guid,
            'offer_count'=>(isset($param_array['NumberOfOfferings']))?$param_array['NumberOfOfferings']:'24',
            'job_type'=>$routing_job_type,
            'job_skus' => implode(',', $split['skus']),
            'total_capacity_units'=>$sku_array[$job_type]['capacity_units']);


问:
Angular 2 fill variable with return JSON info from HTTP Request
I'm pretty new on Angular2, and I'm trying to obtain the key/value pair from a JSON file returned by a Http request. I want to store them on the objectResource property so I can retrieve them on the template.

This is my component.ts:

```<code>export class ResourceDetailComponent implements OnInit {

    objectResource: any = Array();
    id:any;
    sub:any;

    constructor(private contentService: ContentService, private route: ActivatedRoute) {

        this.sub = this.route.params.subscribe(params => {
            this.id = +params['id'];
        });

        this.getResource(this.id);
     }

    ngOnInit(){}

    private getResource(id:number) {
        return this.contentService.getSpecificResource(id).then(res => this.objectResource.push(res));
    }

}
</code>```

and this is mi service.ts:

```<code>public getSpecificResource(id:number) {
        return this.http.get(`http://resources.dev/v1/resources/show/${id}`)
        .toPromise()
        .then(res => res.json());
    }
</code>```

when I do console.log on res I obtain this log, which mean the service is doing the request as expected:

```<code>Object {
    id: 1,
    name: "quisquam",
    image: "http://lorempixel.com/480/480/?88330",
    description: "Consequuntur quo provident alias aut rerum.",
    author: "Marc Mann Sr."
}
</code>```

I've tried to retrieve these values on the template using {{objectResource.name}} but isn't working, and I don't know how can I access this values from the template.

答:
Try using subscribe which will auto update the object when value is resolved.

component.ts

```<code>private getResource(id:number) {
    return this.contentService.getSpecificResource(id)
        .subscribe(res => this.objectResource = res,
                   err => console.log(err));
</code>```

template.html

```<code> <div *ngIf='objectResource'>
    {{objectResource.name}}
 </div>
</code>```

OR

Use async pipe that can receive a Promise or Observable as input and subscribe to the input automatically, eventually returning the emitted value(s).

component.ts

```<code>private getResource(id:number) {
   this.objectResource = this.contentService.getSpecificResource(id);
   return this.objectResource;
}
</code>```

template.html

```<code> <div *ngIf='objectResource | async'>
    {{objectResource.name}}
 </div>
</code>```

Body:
I'm pretty new on Angular2, and I'm trying to obtain the key/value pair from a JSON file returned by a Http request. I want to store them on the objectResource property so I can retrieve them on the template.

This is my component.ts:

export class ResourceDetailComponent implements OnInit {

    objectResource: any = Array();
    id:any;
    sub:any;

    constructor(private contentService: ContentService, private route: ActivatedRoute) {

        this.sub = this.route.params.subscribe(params => {
            this.id = +params['id'];
        });

        this.getResource(this.id);
     }

    ngOnInit(){}

    private getResource(id:number) {
        return this.contentService.getSpecificResource(id).then(res => this.objectResource.push(res));
    }

}

and this is mi service.ts:

public getSpecificResource(id:number) {
        return this.http.get(`http://resources.dev/v1/resources/show/${id}`)
        .toPromise()
        .then(res => res.json());
    }

when I do console.log on res I obtain this log, which mean the service is doing the request as expected:

Object {
    id: 1,
    name: "quisquam",
    image: "http://lorempixel.com/480/480/?88330",
    description: "Consequuntur quo provident alias aut rerum.",
    author: "Marc Mann Sr."
}

I've tried to retrieve these values on the template using {{objectResource.name}} but isn't working, and I don't know how can I access this values from the template.

Body:
Try using subscribe which will auto update the object when value is resolved.

component.ts

private getResource(id:number) {
    return this.contentService.getSpecificResource(id)
        .subscribe(res => this.objectResource = res,
                   err => console.log(err));

template.html

 <div *ngIf='objectResource'>
    {{objectResource.name}}
 </div>

OR

Use async pipe that can receive a Promise or Observable as input and subscribe to the input automatically, eventually returning the emitted value(s).

component.ts

private getResource(id:number) {
   this.objectResource = this.contentService.getSpecificResource(id);
   return this.objectResource;
}

template.html

 <div *ngIf='objectResource | async'>
    {{objectResource.name}}
 </div>


问:
Removing all whitespace in Bootstrap panel containing select list
This has been bothering me for ever now. I've tried removing the padding from the bottom, setting the size of the select field to be the same height as the inner height of the panel, etc.

Here's my jsfiddle so you can just see what I'm talking about: jsfiddle

I'm just trying to have that select list span the whole height of the panel with no white space at the bottom.

I've tried playing around with JQuery as well, but no success. If I resize the select menu, everything just becomes larger and the whitespace remains. A javascript solution would be fine too.

Here is my html:

```<code><div class="panel panel-default" id="obs-list">
  <div class="panel-heading">
    <h3 class="panel-title">Observations</h3>
  </div>
  <div class="panel-body scroll-list" id="list-panel">
    <div class="form-group">
      <select class="form-control patient-list noglow" id="observation" name="observation" size="7">
        <option value="1">2017-03-23 04:40:36</option>
        <option value="2">2017-03-23 04:50:32</option>
        <option value="4">2017-03-28 04:18:55</option>
        <option value="5">2017-03-28 19:01:34</option>
        <option value="11">2017-03-28 22:06:25</option>
        <option value="12">2017-03-28 22:37:32</option>
        <option value="13">2017-03-28 23:10:19</option>
        <option value="14">2017-03-29 02:17:57</option>
      </select>
    </div>
  </div>
</div>
</code>```

And my css:

```<code>.patient-list {
    font-size: 20px;
    border: none;
}

.panel-body.scroll-list {
    padding: 0px 0px 0px 0px;
}
</code>```

And below is that ugly looking whitespace in my list:

答:
Right-click -> Inspect helps alot.

You will see that the element form-group has margin-bottom on it

```<code>.form-group {
  margin-bottom: 0;
}
</code>```

Body:
This has been bothering me for ever now. I've tried removing the padding from the bottom, setting the size of the select field to be the same height as the inner height of the panel, etc.

Here's my jsfiddle so you can just see what I'm talking about: jsfiddle

I'm just trying to have that select list span the whole height of the panel with no white space at the bottom.

I've tried playing around with JQuery as well, but no success. If I resize the select menu, everything just becomes larger and the whitespace remains. A javascript solution would be fine too.

Here is my html:

Observations

      <select class="form-control patient-list noglow" id="observation" name="observation" size="7">
        <option value="1">2017-03-23 04:40:36</option>
        <option value="2">2017-03-23 04:50:32</option>
        <option value="4">2017-03-28 04:18:55</option>
        <option value="5">2017-03-28 19:01:34</option>
        <option value="11">2017-03-28 22:06:25</option>
        <option value="12">2017-03-28 22:37:32</option>
        <option value="13">2017-03-28 23:10:19</option>
        <option value="14">2017-03-29 02:17:57</option>
      </select>

And my css:

.patient-list {
    font-size: 20px;
    border: none;
}

.panel-body.scroll-list {
    padding: 0px 0px 0px 0px;
}

And below is that ugly looking whitespace in my list:

Body:
Right-click -> Inspect helps alot.

You will see that the element form-group has margin-bottom on it

.form-group {
  margin-bottom: 0;
}


问:
Resolve html helper
I am using Razor Engine to dynamically compiling my razor view from the database. Now im using Razor Engine 3.7.3. I saw few posting about how to read html helper and compile it, but it was for the old version of razor engine.

I have read about ITemplateServiceConfiguration, but i cant really understand how it works either.

My question is, how can I runcompile() razorengine (v3.7.3) successfully with @Html (Html helper), @Url (Url Helper), and @section (like @Section Scripts, @Section featured) in the html content from my database?

The things i have done so far. I tried to implement a code that i got from another post. The code was intended for older version of razor engine. He suggested that we create our own helper class:

```<code>public class RazorHtmlHelper
{
    public IEncodedString Partial(string viewName)
    {
        ITemplate template = RazorEngine.Razor.Resolve(viewName);

        ExecuteContext ec = new ExecuteContext();

        RawString result = new RawString(template.Run(ec));

        return result;
    }
}

public class RazorUrlHelper
{
    public string Encode(string url)
    {
        return System.Uri.EscapeUriString(url);
    }
}
</code>```

And then he suggested to create our own templating:

```<code>public class RazorTemplateBase<T> : TemplateBase<T>
{
    private RazorUrlHelper _urlHelper = new RazorUrlHelper();

    private RazorHtmlHelper _htmlHelper = new RazorHtmlHelper();

    public RazorUrlHelper Url
    {
        get
        {
            return this._urlHelper;
        }
    }

    public RazorHtmlHelper Html
    {
        get
        {
            return this._htmlHelper;
        }
    }
}
</code>```

And before parsing, we need to set our config:

```<code>Razor.SetTemplateService(new TemplateService( new TemplateServiceConfiguration()
{
    BaseTemplateType = typeof(RazorTemplateBase<>)
};
));

result = RazorEngine.Razor.Parse(templateText, model);
</code>```

There is no problem with the RazorUrlHelper, but the RazorHtmlHelper cannot properly read these codes because it is deprecated:

```<code>ITemplate template = RazorEngine.Razor.Resolve(viewName);
ExecuteContext ec = new ExecuteContext();
RawString result = new RawString(template.Run(ec));
</code>```

The codes above are from this post

答:
I'm not entirely sure that my suggestions will directly solve your problem.  In my professional experience trying to leverage deprecated classes does not yield positive results.  I personally would not try to render views directly from a database. If i was in your position leveraging razor view engine with MVC4 i would abandon your approach follow these steps.

Right click on your project and update MVC4 and all included js/dll/libraries to the latest version using nuget.

Create sets of Model objects that contain variables to house all information that you will be pulling from the database.  Leverage inheritance or design them in such a way that they are efficiently used on a request per request basis.

Build your main master and partial views for your MVC project that most efficiently prevent any duplicate front end code.  If these views are mainly going to return HTML responses, set your controller actions to an ActionResult() pointing to the master views for your application. Fill your model object with all of the data that it needs from the database in these controller actions and pass the filled model objects to your master view.

In your partial and master views, you can define this model object as the main model at the top of the view and pass the model variables as parameters to your HTMLHelpers.

Create your HTML Helper objects that take these model variables as parameters, and define their namespaces in your Views/web.config file.  In this example i used the namespace System.Web.HtmlHelpers. If you do not do this, you will not be able to leverage any custom helpers outside of the base namespaces in your views.

```<code><system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <pages pageBaseType="System.Web.Mvc.WebViewPage">
   <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Optimization"/>
    <add namespace="System.Web.Routing" />
    <add namespace="System.Web.HtmlHelpers" />
   </namespaces>
  </pages>
</system.web.webPages.razor>
</code>```

In your HTMLHelpers namespace classes, create MVCHtmlString or other MVC methods that take your database model parameters and translate them into working and functioning HTML/JSON or XML.  Reference these custom HTML helpers in your partial and master views.

If you implement your HTMLHelpers in this way, you are abstracting away your JIT compiled code (all view code) with the logic that accesses data and translates structured database data into viewable HTML. In the above example that you are presenting you will be JIT compiling most of the logic for your views at runtime which is very expensive in terms of performance.  MVC was designed in such a way so that you can prevent taking on all of that overhead.  If you create powerful HTML helpers that exist within pre-compiled libraries, you can make your view code extremely small and simple.

Title: Resolve html helper

Body:
I am using Razor Engine to dynamically compiling my razor view from the database. Now im using Razor Engine 3.7.3. I saw few posting about how to read html helper and compile it, but it was for the old version of razor engine.

I have read about ITemplateServiceConfiguration, but i cant really understand how it works either.

My question is, how can I runcompile() razorengine (v3.7.3) successfully with @Html (Html helper), @Url (Url Helper), and @section (like @Section Scripts, @Section featured) in the html content from my database?

The things i have done so far. I tried to implement a code that i got from another post. The code was intended for older version of razor engine. He suggested that we create our own helper class:

public class RazorHtmlHelper
{
    public IEncodedString Partial(string viewName)
    {
        ITemplate template = RazorEngine.Razor.Resolve(viewName);

        ExecuteContext ec = new ExecuteContext();

        RawString result = new RawString(template.Run(ec));

        return result;
    }
}

public class RazorUrlHelper
{
    public string Encode(string url)
    {
        return System.Uri.EscapeUriString(url);
    }
}

And then he suggested to create our own templating:

public class RazorTemplateBase<T> : TemplateBase<T>
{
    private RazorUrlHelper _urlHelper = new RazorUrlHelper();

    private RazorHtmlHelper _htmlHelper = new RazorHtmlHelper();

    public RazorUrlHelper Url
    {
        get
        {
            return this._urlHelper;
        }
    }

    public RazorHtmlHelper Html
    {
        get
        {
            return this._htmlHelper;
        }
    }
}

And before parsing, we need to set our config:

Razor.SetTemplateService(new TemplateService( new TemplateServiceConfiguration()
{
    BaseTemplateType = typeof(RazorTemplateBase<>)
};
));

result = RazorEngine.Razor.Parse(templateText, model);

There is no problem with the RazorUrlHelper, but the RazorHtmlHelper cannot properly read these codes because it is deprecated:

ITemplate template = RazorEngine.Razor.Resolve(viewName);
ExecuteContext ec = new ExecuteContext();
RawString result = new RawString(template.Run(ec));

The codes above are from this post

Body:
I'm not entirely sure that my suggestions will directly solve your problem.  In my professional experience trying to leverage deprecated classes does not yield positive results.  I personally would not try to render views directly from a database. If i was in your position leveraging razor view engine with MVC4 i would abandon your approach follow these steps.

Right click on your project and update MVC4 and all included js/dll/libraries to the latest version using nuget.

Create sets of Model objects that contain variables to house all information that you will be pulling from the database.  Leverage inheritance or design them in such a way that they are efficiently used on a request per request basis.

Build your main master and partial views for your MVC project that most efficiently prevent any duplicate front end code.  If these views are mainly going to return HTML responses, set your controller actions to an ActionResult() pointing to the master views for your application. Fill your model object with all of the data that it needs from the database in these controller actions and pass the filled model objects to your master view.

In your partial and master views, you can define this model object as the main model at the top of the view and pass the model variables as parameters to your HTMLHelpers.

Create your HTML Helper objects that take these model variables as parameters, and define their namespaces in your Views/web.config file.  In this example i used the namespace System.Web.HtmlHelpers. If you do not do this, you will not be able to leverage any custom helpers outside of the base namespaces in your views.

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <pages pageBaseType="System.Web.Mvc.WebViewPage">
   <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Optimization"/>
    <add namespace="System.Web.Routing" />
    <add namespace="System.Web.HtmlHelpers" />
   </namespaces>
  </pages>
</system.web.webPages.razor>

In your HTMLHelpers namespace classes, create MVCHtmlString or other MVC methods that take your database model parameters and translate them into working and functioning HTML/JSON or XML.  Reference these custom HTML helpers in your partial and master views.

If you implement your HTMLHelpers in this way, you are abstracting away your JIT compiled code (all view code) with the logic that accesses data and translates structured database data into viewable HTML. In the above example that you are presenting you will be JIT compiling most of the logic for your views at runtime which is very expensive in terms of performance.  MVC was designed in such a way so that you can prevent taking on all of that overhead.  If you create powerful HTML helpers that exist within pre-compiled libraries, you can make your view code extremely small and simple.


问:
How do I package a website to be served by tomcat?
First, let me apologize, I'm new at web development, so I'm not quite sure how this works, but it's a simple proof of concept, so I don't think it needs to be too advanced.

I have a jar that accesses a server and pulls information that needs to be displayed for the user, I also have a local site that is set up to display this information to the user via html and javascript (but obviously doesn't connect to the server or that jar).  I plan on using tomcat to act as a middleware server that will display the web page and handle the code that accesses the server.

I've seen it done before, but I'm not quite sure how to set it up.  Can somebody just give me the basics on where things need to go to make this work?  I think I'd be ok after that.

My Google-Fu has failed me in finding this, so really any help is appreciated.

Thanks!

答:
Here are a few things you need to learn :

Your Java web application project must have folder structure of a webapp project. This is normally automatically created by your IDE when you choose to create a webapp project. For me, I am using maven to organise my webapp project so it slightly different from ant project.

You will need to learn where to put you Java classes, JSP pages, resources in your webapp project folders.

Try creating a HelloWorld page in your webapp, then learn how to config your web.xml

Most IDEs can create war file for you. One war file is created you will have to deploy it in tomcat webapp folder. I don't think many people packing war file manually.

Let me know if you want me to explain it in more detail.


问:
Web Server Installation Error (RHEL)
my friend has been trying to install web server via RHEL, but this error has pop out, can anybody explain why does this happens? Is it because of the firewall/ports has not been open or am i using the wrong command?

答:
Follow these steps.

Step 1: yum install httpd -y

This will install Apache

Step 2: systemctl enable httpd.service

Step 3: systemctl start httpd.service

Step 4: firewall-cmd --permanent --add-port=80/tcp

Step 5: firewall-cmd --reload

After all this steps are done open your web browser and goto http://localhost or http://127.0.0.1

Your commands looks OK. But it's weird it's not recognizing systemctl.

Can I know the what is this system is. Is it a test RHEL setup ?

Title: Web Server Installation Error (RHEL)