问:
Set labels and text field alignment in JavaFX
I realize that this is a very basic question, but I am just starting to learn GUI and JavaFX specifically. I have a list of labels and their appropriate text input fields and a button to calculate results. I want to align them all like this:

label..........text field

label..........text field

label..........text field

label..........text field

.........button..........

centered aligned on the pane itself. I've tried setting the alignment to center but it only works on the horizontal axis. I've tried using VBox as well as HBox but they give the same output. I have even tried setPadding(0,0,0,0) with different values but I don't get the result I desire. I've found similar questions (that didn't answer my queston) and have even been to https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/FlowPane.html
but to no avail. I realize the calculate button only adds the values, but I haven't gotten that far and I think I know what to do to make it do what I want, just having trouble with the GUI layout. Any help would be appreciated. Below is the code I have so far after playing around with it for a couple hours:

```<code> package javafxfincalc;

 import javafx.application.Application;
 import javafx.geometry.Pos;
 import javafx.scene.Scene;
 import javafx.scene.control.Button;
 import javafx.scene.control.Label;
 import javafx.scene.control.TextField;
 import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.FlowPane;
 import javafx.scene.layout.HBox;   // may not need
 import javafx.scene.layout.VBox;
 import javafx.stage.Stage;
 import javafx.geometry.Insets;
 import javafx.geometry.Orientation;
 // a lot of classes must be imported from Java FX to make this all work correctly

 public class JavaFXFinCalc extends Application {
// all applications will be a child class of Application when made with Java FX

 public static void main(String[] args) {

Application.launch(args);
// this allows the program to start
 }@Override

public void start(Stage primaryStage) throws Exception {
// this will use a standard exception handler

FlowPane pane = new FlowPane(Orientation.VERTICAL);
 pane.setHgap(5);
 pane.setAlignment(Pos.CENTER);
 pane.setPadding(new Insets(0,0,0,0)); // set top, right, bottom, left
 // this allows input fields to be placed in the window

 TextField tf1 = new TextField("00.00");
 TextField tf2 = new TextField("0");
 TextField tf3 = new TextField("0.00%");
 TextField my_result = new TextField("You cannot type here");
 // these are the individual fields for input, you can set the default text

 my_result.setEditable(false);
 // keeps user from changing this text field

 tf1.setPrefColumnCount(14);
 tf2.setPrefColumnCount(14);
 tf3.setPrefColumnCount(14);
 my_result.setPrefColumnCount(14);
 // this sets the number of spaces in the text fields

 Label l1 = new Label("Money used in investment: ");
 Label l2 = new Label("Years: ");
 Label l3 = new Label("Annual Interest Rate: ");
 Label l4 = new Label("Final Financial Worth: ");
 // these labels are set and used before the text fields as show below

 pane.getChildren().addAll(l1, tf1, l2, tf2, l3, tf3, l4, my_result);
 // call on the labels and text fields to be placed into the window

 VBox vBox = new VBox();
 Button calc_button = new Button("Calculate it!");
 // create a box to put the button in and name the button

 vBox.setAlignment(Pos.CENTER);
 vBox.getChildren().addAll(calc_button);

 BorderPane borderPane = new BorderPane();
 borderPane.setCenter(pane);
 borderPane.setBottom(vBox);
 BorderPane.setAlignment(vBox,Pos.CENTER);

 Scene scene = new Scene(borderPane, 500, 500);
 primaryStage.setTitle("Financial Calculator");
 primaryStage.setScene(scene);
 primaryStage.show();

 calc_button.setOnAction(e -> {
 my_result.setText(Double.parseDouble(tf1.getText()) +
 Double.parseDouble(tf2.getText()) + "");
 });

 }}
</code>```

This is the current output, all lines centered

答:
Here is the end result! Thanks again Sedrick! https://docs.oracle.com/javafx/2/get_started/form.htm</p>

```<code>public void start(Stage primaryStage) throws Exception {
// this will use a standard exception handler

GridPane pane = new GridPane();
 pane.setAlignment(Pos.CENTER);
 pane.setHgap(5);
 pane.setVgap(5);
 pane.setPadding(new Insets(25,25,25,25)); // set top, right, bottom, left
 // this allows input fields to be placed in the window

 TextField tf1 = new TextField("00.00");
 TextField tf2 = new TextField("0");
 TextField tf3 = new TextField("0.00%");
 TextField my_result = new TextField("You cannot type here");
 // these are the individual fields for input, you can set the default text

 my_result.setEditable(false);
 // keeps user from changing this text field

 tf1.setPrefColumnCount(14);
 tf2.setPrefColumnCount(14);
 tf3.setPrefColumnCount(14);
 my_result.setPrefColumnCount(14);
 // this sets the number of spaces in the text fields

 Label l1 = new Label("Money used in investment: ");
 Label l2 = new Label("Years: ");
 Label l3 = new Label("Annual Interest Rate: ");
 Label l4 = new Label("Final Financial Worth: ");
 // these labels are set and used before the text fields as show below

 pane.add(l1, 0, 1);
 pane.add(tf1, 1, 1);
 pane.add(l2, 0, 2);
 pane.add(tf2, 1, 2);
 pane.add(l3, 0, 3);
 pane.add(tf3, 1, 3);
 pane.add(l4, 0, 4);
 pane.add(my_result, 1, 4);
 // call on the labels and text fields to be placed into the window
 // must be done individually so that location and order can be set by column/row

 Button calc_button = new Button("Calculate it!");
 pane.add(calc_button, 1, 5);
 // make a button and put it in the Gridpane

 BorderPane borderPane = new BorderPane();
 borderPane.setCenter(pane);

 Scene scene = new Scene(borderPane, 500, 500);
 primaryStage.setTitle("Financial Calculator");
 primaryStage.setScene(scene);
 primaryStage.show();

 calc_button.setOnAction(e -> {
 my_result.setText("");
 });

}
</code>```

Body:
I realize that this is a very basic question, but I am just starting to learn GUI and JavaFX specifically. I have a list of labels and their appropriate text input fields and a button to calculate results. I want to align them all like this:

label..........text field

label..........text field

label..........text field

label..........text field

.........button..........

centered aligned on the pane itself. I've tried setting the alignment to center but it only works on the horizontal axis. I've tried using VBox as well as HBox but they give the same output. I have even tried setPadding(0,0,0,0) with different values but I don't get the result I desire. I've found similar questions (that didn't answer my queston) and have even been to https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/FlowPane.html
but to no avail. I realize the calculate button only adds the values, but I haven't gotten that far and I think I know what to do to make it do what I want, just having trouble with the GUI layout. Any help would be appreciated. Below is the code I have so far after playing around with it for a couple hours:

 package javafxfincalc;

 import javafx.application.Application;
 import javafx.geometry.Pos;
 import javafx.scene.Scene;
 import javafx.scene.control.Button;
 import javafx.scene.control.Label;
 import javafx.scene.control.TextField;
 import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.FlowPane;
 import javafx.scene.layout.HBox;   // may not need
 import javafx.scene.layout.VBox;
 import javafx.stage.Stage;
 import javafx.geometry.Insets;
 import javafx.geometry.Orientation;
 // a lot of classes must be imported from Java FX to make this all work correctly

 public class JavaFXFinCalc extends Application {
// all applications will be a child class of Application when made with Java FX

 public static void main(String[] args) {

Application.launch(args);
// this allows the program to start
 }@Override

public void start(Stage primaryStage) throws Exception {
// this will use a standard exception handler

FlowPane pane = new FlowPane(Orientation.VERTICAL);
 pane.setHgap(5);
 pane.setAlignment(Pos.CENTER);
 pane.setPadding(new Insets(0,0,0,0)); // set top, right, bottom, left
 // this allows input fields to be placed in the window

 TextField tf1 = new TextField("00.00");
 TextField tf2 = new TextField("0");
 TextField tf3 = new TextField("0.00%");
 TextField my_result = new TextField("You cannot type here");
 // these are the individual fields for input, you can set the default text

 my_result.setEditable(false);
 // keeps user from changing this text field

 tf1.setPrefColumnCount(14);
 tf2.setPrefColumnCount(14);
 tf3.setPrefColumnCount(14);
 my_result.setPrefColumnCount(14);
 // this sets the number of spaces in the text fields

 Label l1 = new Label("Money used in investment: ");
 Label l2 = new Label("Years: ");
 Label l3 = new Label("Annual Interest Rate: ");
 Label l4 = new Label("Final Financial Worth: ");
 // these labels are set and used before the text fields as show below

 pane.getChildren().addAll(l1, tf1, l2, tf2, l3, tf3, l4, my_result);
 // call on the labels and text fields to be placed into the window

 VBox vBox = new VBox();
 Button calc_button = new Button("Calculate it!");
 // create a box to put the button in and name the button

 vBox.setAlignment(Pos.CENTER);
 vBox.getChildren().addAll(calc_button);

 BorderPane borderPane = new BorderPane();
 borderPane.setCenter(pane);
 borderPane.setBottom(vBox);
 BorderPane.setAlignment(vBox,Pos.CENTER);

 Scene scene = new Scene(borderPane, 500, 500);
 primaryStage.setTitle("Financial Calculator");
 primaryStage.setScene(scene);
 primaryStage.show();

 calc_button.setOnAction(e -> {
 my_result.setText(Double.parseDouble(tf1.getText()) +
 Double.parseDouble(tf2.getText()) + "");
 });

 }}

This is the current output, all lines centered

Body:
Here is the end result! Thanks again Sedrick! https://docs.oracle.com/javafx/2/get_started/form.htm

public void start(Stage primaryStage) throws Exception {
// this will use a standard exception handler

GridPane pane = new GridPane();
 pane.setAlignment(Pos.CENTER);
 pane.setHgap(5);
 pane.setVgap(5);
 pane.setPadding(new Insets(25,25,25,25)); // set top, right, bottom, left
 // this allows input fields to be placed in the window

 TextField tf1 = new TextField("00.00");
 TextField tf2 = new TextField("0");
 TextField tf3 = new TextField("0.00%");
 TextField my_result = new TextField("You cannot type here");
 // these are the individual fields for input, you can set the default text

 my_result.setEditable(false);
 // keeps user from changing this text field

 tf1.setPrefColumnCount(14);
 tf2.setPrefColumnCount(14);
 tf3.setPrefColumnCount(14);
 my_result.setPrefColumnCount(14);
 // this sets the number of spaces in the text fields

 Label l1 = new Label("Money used in investment: ");
 Label l2 = new Label("Years: ");
 Label l3 = new Label("Annual Interest Rate: ");
 Label l4 = new Label("Final Financial Worth: ");
 // these labels are set and used before the text fields as show below

 pane.add(l1, 0, 1);
 pane.add(tf1, 1, 1);
 pane.add(l2, 0, 2);
 pane.add(tf2, 1, 2);
 pane.add(l3, 0, 3);
 pane.add(tf3, 1, 3);
 pane.add(l4, 0, 4);
 pane.add(my_result, 1, 4);
 // call on the labels and text fields to be placed into the window
 // must be done individually so that location and order can be set by column/row

 Button calc_button = new Button("Calculate it!");
 pane.add(calc_button, 1, 5);
 // make a button and put it in the Gridpane

 BorderPane borderPane = new BorderPane();
 borderPane.setCenter(pane);

 Scene scene = new Scene(borderPane, 500, 500);
 primaryStage.setTitle("Financial Calculator");
 primaryStage.setScene(scene);
 primaryStage.show();

 calc_button.setOnAction(e -> {
 my_result.setText("");
 });

}


来源: stackexchange

问:
Font size based on container
I have a Symbol to display in a ZxZ px container:

.symbol {
 width: 32px;
 height: 32px;
 border: 1px dotted;
 text-align: center;
}

.symbol>span {
color: darkred;
font-size: 3em;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div>Some Text
<div class="symbol"><span>☎</span></div>
</div></code>```

I would like to adjust the font-size always to fit the dotted square, whatever the Z size is...

Please read the question before making it duplicate! I don't need to fit it to viewport, or in any way the question is linked with responsiveness, mobile tablets etc.

I just need a letter to adjust to its container's rectangle/div.

答:
Something I need:

.a {
width: 25px;
height: 25px;
border: 1px dotted;
}

.b {
width: 200px;
height: 100px;
border: 1px dotted;
color: red;
}

.c {
width: 800px;
height: 800px;
border: 1px dotted;
color: blue;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="a">
<svg width="100%" height="100%" viewBox="0 -100 100 100">
  <text font-size="138" fill="currentColor" x="50" text-anchor="middle">☯</text>
</svg>
</div>
<div class="b">
<svg width="100%" height="100%" viewBox="0 -100 100 100">
  <text font-size="138" fill="currentColor" x="50" text-anchor="middle">☯</text>
</svg>
</div>
<div class="c">
<svg width="100%" height="100%" viewBox="0 -100 100 100">
  <text font-size="138" fill="currentColor" x="50" text-anchor="middle">☯</text>
</svg>
</div></code>```

the JSFiddle here

ContentLicense: CC BY-SA 3.0

Title: Font size based on container

Body:
I have a Symbol to display in a ZxZ px container:

.symbol {
 width: 32px;
 height: 32px;
 border: 1px dotted;
 text-align: center;
}

.symbol>span {
color: darkred;
font-size: 3em;
}

Some Text

☎

I would like to adjust the font-size always to fit the dotted square, whatever the Z size is...

Please read the question before making it duplicate! I don't need to fit it to viewport, or in any way the question is linked with responsiveness, mobile tablets etc.

I just need a letter to adjust to its container's rectangle/div.

Body:
Something I need:

.a {
width: 25px;
height: 25px;
border: 1px dotted;
}

.b {
width: 200px;
height: 100px;
border: 1px dotted;
color: red;
}

.c {
width: 800px;
height: 800px;
border: 1px dotted;
color: blue;
}

<div class="a">
<svg width="100%" height="100%" viewBox="0 -100 100 100">
  <text font-size="138" fill="currentColor" x="50" text-anchor="middle">☯</text>
</svg>
</div>
<div class="b">
<svg width="100%" height="100%" viewBox="0 -100 100 100">
  <text font-size="138" fill="currentColor" x="50" text-anchor="middle">☯</text>
</svg>
</div>
<div class="c">
<svg width="100%" height="100%" viewBox="0 -100 100 100">
  <text font-size="138" fill="currentColor" x="50" text-anchor="middle">☯</text>
</svg>
</div>

the JSFiddle here


问:
Cost for Clound Foundry on AWS
I have seen instructions for installing Bosh Lite on AWS. It's a similar process to installing it on a local VM. Then I can utilize Bosh to deploy OSS Cloud Foundry to the bosh-lite VM. Here are those instructions:

https://github.com/cloudfoundry/bosh-lite/blob/master/docs/aws-provider.md

My question is how can I estimate how much this would cost?  I want to charge this on my company credit card, but I need to estimate the cost first.  I know I can get a plain EC2 instance free for a year (I assume there's some limit to how much I use it), but from the looks of the instructions above, I think I'll need several, along with other instances.

So, if I just set up Cloud Foundry, write a simple "Hello World" web app using Spring, deploy my app and test it, and then tear everything down, how can I estimate the cost?

答:
AWS costs vary with the services, regions, data in/out etc.

So list down the aws region you want to use, list all the number of resources & their types (Ex. EC2 - t2.medium) and approximate storage etc everything.

Then go to AWS calculator and feed all those entries and it will show you the costs.

Here is calculator link: https://calculator.s3.amazonaws.com/index.html

Title: Cost for Clound Foundry on AWS


问:
How do I change the following from_str macro to from_json?
I have the following macro. Note that StringContent is an enum item.

```<code>#[macro_export]
macro_rules! from_str {
    ($json:expr) => {
        StringContent(String::from($json))
    }
}
</code>```

which allows me to write code like

```<code>from_str!(r#"{
    "appName": "Demo App",
    "appVersion": "1.0",
    "database": {
        "host": "dev.database.com",
        "port": 3000
    }
}"#)
</code>```

Now I want another macro from_json! which allows me to do get rid of the r#""# like so

```<code>from_json!({
    "appName": "Demo App",
    "appVersion": "1.0",
    "database": {
        "host": "dev.database.com",
        "port": 3000
    }
})
</code>```

I've tried the following which does not seem to work

```<code>#[macro_export]
macro_rules! from_json {
    ($t:tt) => {
        StringContent(String::from(concat!(r#"r#""#, stringify!($t), r#"""# , r#"#"#)))
    }
}
</code>```

How can I get from_json to work?

答:
Your macro doesn't work because concat! cannot be used to append identifiers to each other in a syntactically sound way. It instead concatenates identifiers into a string. Yours now looks like "r#\" ~your JSON~ \"#", with the r# and # being literal characters in it.

Your approach won't work until a stabilized, extended concat_idents! is implemented.

You will have to parse the JSON syntax by hand in your macro. For inspiration, take a look at how Serde does it.

serde_json in general seems to fit your use case quite well. If possible, I suggest removing custom implementations of any JSON parsing and use serde_json instead, as it is the de-facto standard choice for all things JSON in Rust.

This is a minimal example of how to convert your JSON into a raw string with serde_json:

```<code>#[macro_use]
extern crate serde_json;

fn main() {
    let as_json_value = json!({
        "appName": "Demo App",
        "appVersion": "1.0",
        "database": {
            "host": "dev.database.com",
            "port": 3000
        }
    });
    let as_string = format!("{}", as_json_value);
    println!("{}", as_string);
}
</code>```

Although you probably will want to rewrite your StringContent enum to be built from a serde_json::Value, as it is already neatly parsed for you.

Body:
I have the following macro. Note that StringContent is an enum item.

#[macro_export]
macro_rules! from_str {
    ($json:expr) => {
        StringContent(String::from($json))
    }
}

which allows me to write code like

from_str!(r#"{
    "appName": "Demo App",
    "appVersion": "1.0",
    "database": {
        "host": "dev.database.com",
        "port": 3000
    }
}"#)

Now I want another macro from_json! which allows me to do get rid of the r#""# like so

from_json!({
    "appName": "Demo App",
    "appVersion": "1.0",
    "database": {
        "host": "dev.database.com",
        "port": 3000
    }
})

I've tried the following which does not seem to work

#[macro_export]
macro_rules! from_json {
    ($t:tt) => {
        StringContent(String::from(concat!(r#"r#""#, stringify!($t), r#"""# , r#"#"#)))
    }
}

How can I get from_json to work?

Body:
Your macro doesn't work because concat! cannot be used to append identifiers to each other in a syntactically sound way. It instead concatenates identifiers into a string. Yours now looks like "r#\" ~your JSON~ \"#", with the r# and # being literal characters in it.

Your approach won't work until a stabilized, extended concat_idents! is implemented.

You will have to parse the JSON syntax by hand in your macro. For inspiration, take a look at how Serde does it.

serde_json in general seems to fit your use case quite well. If possible, I suggest removing custom implementations of any JSON parsing and use serde_json instead, as it is the de-facto standard choice for all things JSON in Rust.

This is a minimal example of how to convert your JSON into a raw string with serde_json:

#[macro_use]
extern crate serde_json;

fn main() {
    let as_json_value = json!({
        "appName": "Demo App",
        "appVersion": "1.0",
        "database": {
            "host": "dev.database.com",
            "port": 3000
        }
    });
    let as_string = format!("{}", as_json_value);
    println!("{}", as_string);
}

Although you probably will want to rewrite your StringContent enum to be built from a serde_json::Value, as it is already neatly parsed for you.


问:
v-model and child components?
I have a form and bind an input using v-model:

```<code><input type="text" name="name" v-model="form.name">
</code>```

Now I want to extract the input and make it it's own component, how do you then bind the values of the child component to the parents object form.name?

答:
As stated in the documentation,

v-model is syntactic sugar for:

```<code><input
 v-bind:value="something"
 v-on:input="something = $event.target.value">
</code>```

To implement the v-model directive for a custom component:

specify a value prop for the component

make a computed property with a computed setter for the inner value (since you should not modify the value of a prop from within a component)

define a get method for the computed property which returns the value prop's value

define a set method for the computed property which emits an input event with the updated value whenever the property changes

Here's a simple example:

Vue.component('my-input', {
  template: `

      My Input:
      <input v-model="inputVal">

  `,
  props: ['value'],
  computed: {
    inputVal: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      }
    }
  }
})

new Vue({
  el: '#app',
  data() {
    return {
      foo: 'bar'
    }
  }
})```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <!-- using v-model... -->
  <my-input v-model="foo"></my-input>

  <!-- is the same as this... -->
  <my-input :value="foo" @input="foo = $event"></my-input>

  {{ foo }}
</div></code>```

Thanks to @kthornbloom for spotting an issue with the previous implementation.

Breaking changes in Vue 3

Per the documentation, there are breaking changes to the v-model implementation in Vue 3:

value -> modelValue

input -> update:modelValue

Title: v-model and child components?

Body:
I have a form and bind an input using v-model:

<input type="text" name="name" v-model="form.name">

Now I want to extract the input and make it it's own component, how do you then bind the values of the child component to the parents object form.name?

Body:
As stated in the documentation,

v-model is syntactic sugar for:

<input
 v-bind:value="something"
 v-on:input="something = $event.target.value">

To implement the v-model directive for a custom component:

specify a value prop for the component

make a computed property with a computed setter for the inner value (since you should not modify the value of a prop from within a component)

define a get method for the computed property which returns the value prop's value

define a set method for the computed property which emits an input event with the updated value whenever the property changes

Here's a simple example:

Vue.component('my-input', {
  template: `
    <div>
      My Input:
      <input v-model="inputVal">
    </div>
  `,
  props: ['value'],
  computed: {
    inputVal: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      }
    }
  }
})

new Vue({
  el: '#app',
  data() {
    return {
      foo: 'bar'
    }
  }
})

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <!-- using v-model... -->
  <my-input v-model="foo"></my-input>

  <!-- is the same as this... -->
  <my-input :value="foo" @input="foo = $event"></my-input>

  {{ foo }}
</div>

Thanks to @kthornbloom for spotting an issue with the previous implementation.

Breaking changes in Vue 3

Per the documentation, there are breaking changes to the v-model implementation in Vue 3:

value -> modelValue

input -> update:modelValue

ContentLicense: CC BY-SA 4.0


问:
Static variable shadowing global
I am trying to create an object using placement new (I know to use smart pointers, this is just to learn). My code is as follows:

```<code>#include <vector>
#include <iostream>
#include <memory>

using namespace std; // please excuse this

// if you change like 19 to arr1 (or any other var name) instead of arr and line 40 to arr1 then it works

struct A
{
    int in = 999;
    A()
    {cout << "A ctor\n";}
    ~A()
    {cout << "A dtor\n";}
};

char arr[sizeof(A)];

class B
{
    public:
    static char arr[sizeof(A)];

    const static A* a_obj;

    B()
    {
        cout << "B ctor\n";
        //cout << (a_obj->in) << endl;
    }
    ~B()
    {
        cout << "B dtor\n";
    }
};

const A* B::a_obj = new(arr) A;

int main()
{
    B g;
}
</code>```

I have created a global array named arr and another array named arrin B. It seems like when I do my placement new the arr being used is from the class as I get what I think are linker errors.

Why is this happening? why isn't the global arr being used? If i change the placement new to use my renamed global array it works. I think it has to do something with lookups but I don't have a concrete answer.

答:
From the C++ 2017 Standard (12.2.3.2 Static data members)

2 The declaration of a non-inline static data member in its class
  definition is not a definition and may be of an incomplete type other
  than cv void. The definition for a static data member that is not
  defined inline in the class definition shall appear in a namespace
  scope enclosing the member’s class definition. In the definition at
  namespace scope, the name of the static data member shall be qualified
  by its class name using the :: operator. The initializer expression
  in the definition of a static data member is in the scope of its
  class (6.3.7).

So in this definition of the static data member

```<code>const A* B::a_obj = new(arr) A;
</code>```

the unqualified name arr is at first searched in the scope of the class B. And the class B indeed declares such a name

```<code>static char arr[sizeof(A)];
</code>```

If you want to use the name from the global namespace then use the qualified name

```<code>const A* B::a_obj = new(::arr) A;
</code>```

Here is a demonstrative program

```<code>#include <iostream>

struct A
{
    const static int N = 10;
    static int n1;
    static int n2;
};

const int N = 20;

int A::n1 = N;
int A::n2 = ::N;

int main()
{
    std::cout << "A::n1 = " << A::n1 << std::endl;
    std::cout << "A::n2 = " << A::n2 << std::endl;

    return 0;
}
</code>```

Its output is

```<code>A::n1 = 10
A::n2 = 20
</code>```

Title: Static variable shadowing global

Body:
I am trying to create an object using placement new (I know to use smart pointers, this is just to learn). My code is as follows:

#include <vector>
#include <iostream>
#include <memory>

using namespace std; // please excuse this

// if you change like 19 to arr1 (or any other var name) instead of arr and line 40 to arr1 then it works

struct A
{
    int in = 999;
    A()
    {cout << "A ctor\n";}
    ~A()
    {cout << "A dtor\n";}
};

char arr[sizeof(A)];

class B
{
    public:
    static char arr[sizeof(A)];

    const static A* a_obj;

    B()
    {
        cout << "B ctor\n";
        //cout << (a_obj->in) << endl;
    }
    ~B()
    {
        cout << "B dtor\n";
    }
};

const A* B::a_obj = new(arr) A;

int main()
{
    B g;
}

I have created a global array named arr and another array named arrin B. It seems like when I do my placement new the arr being used is from the class as I get what I think are linker errors.

Why is this happening? why isn't the global arr being used? If i change the placement new to use my renamed global array it works. I think it has to do something with lookups but I don't have a concrete answer.

Body:
From the C++ 2017 Standard (12.2.3.2 Static data members)

2 The declaration of a non-inline static data member in its class
  definition is not a definition and may be of an incomplete type other
  than cv void. The definition for a static data member that is not
  defined inline in the class definition shall appear in a namespace
  scope enclosing the member’s class definition. In the definition at
  namespace scope, the name of the static data member shall be qualified
  by its class name using the :: operator. The initializer expression
  in the definition of a static data member is in the scope of its
  class (6.3.7).

So in this definition of the static data member

const A* B::a_obj = new(arr) A;

the unqualified name arr is at first searched in the scope of the class B. And the class B indeed declares such a name

static char arr[sizeof(A)];

If you want to use the name from the global namespace then use the qualified name

const A* B::a_obj = new(::arr) A;

Here is a demonstrative program

#include <iostream>

struct A
{
    const static int N = 10;
    static int n1;
    static int n2;
};

const int N = 20;

int A::n1 = N;
int A::n2 = ::N;

int main()
{
    std::cout << "A::n1 = " << A::n1 << std::endl;
    std::cout << "A::n2 = " << A::n2 << std::endl;

    return 0;
}

Its output is

A::n1 = 10
A::n2 = 20


问:
Take separate time and timezone strings, and convert into UTC
I know a bunch of ways to convert local times into UTC time with Ruby, but I'm not sure how to do this when the time and the zone are separate pieces of data.  If I have something like "12:00 PM -0500", I can easily convert this into UTC with .getutc().  However, what if I have "12:00 PM" and "Eastern Time (US & Canada)"?  How can I combine these two to find the UTC time?

答:
If you are using Rails, or if you don't mind requiring ActiveSupport, you can use ActiveSupport::TimeZone to do this.</p>

```<code>>> time_zone = "Eastern Time (US & Canada)"
>> time_without_zone = "12:00 PM"
>> ActiveSupport::TimeZone[time_zone].parse(time_without_zone)
#=> Wed, 15 Nov 2017 12:00:00 EST -05:00
</code>```

Body:
If you are using Rails, or if you don't mind requiring ActiveSupport, you can use ActiveSupport::TimeZone to do this.

>> time_zone = "Eastern Time (US & Canada)"
>> time_without_zone = "12:00 PM"
>> ActiveSupport::TimeZone[time_zone].parse(time_without_zone)
#=> Wed, 15 Nov 2017 12:00:00 EST -05:00


问:
How to create schema for Spark SQL for Array of struct?
How to create a schema for the below json to read schema. I am using hiveContext.read.schema().json("input.json"), and I want to ignore the first two "ErrorMessage" and "IsError" read only Report.
Below is the JSON:

```<code> {
  "ErrorMessage": null,
  "IsError": false,
   "Report":{
      "tl":[
         {
            "TlID":"F6",
            "CID":"mo"
         },
         {
            "TlID":"Fk",
            "CID":"mo"
         }
      ]
   }
}
</code>```

I created the below schema :

```<code>val schema = StructType(
            Array(
                   StructField("Report", StructType(
                     Array(
                                                     StructField
                                                     ("tl",ArrayType(StructType(Array(
                                                                    StructField("TlID", StringType),
                                                                    StructField("CID", IntegerType)
                                                                  )))))))))

Below is my json.printSchema() :
root
 |-- Report: struct (nullable = true)
 |    |-- tl: array (nullable = true)
 |    |    |-- element: struct (containsNull = true)
 |    |    |    |-- TlID: string (nullable = true)
 |    |    |    |-- CID: integer (nullable = true)
</code>```

答:
The schema is incorrect. CID in your data is clearly not String ("mo"). Use

```<code>val schema = StructType(Array(
  StructField("Report", StructType(
    Array(
        StructField
        ("tl",ArrayType(StructType(Array(
                       StructField("CID", StringType),
                       StructField("TlID", StringType)
                          )))))))))
</code>```

and:

```<code>val df = Seq("""{
  "ErrorMessage": null,
  "IsError": false,
   "Report":{
      "tl":[
         {
            "TlID":"F6",
            "CID":"mo"
         },
         {
            "TlID":"Fk",
            "CID":"mo"
         }
      ]
   }
}""").toDS

spark.read.schema(schema).json(df).show(false)
+--------------------------------+
|Report                          |
+--------------------------------+
|[WrappedArray([mo,F6], [mo,Fk])]|
+--------------------------------+
</code>```

Body:
How to create a schema for the below json to read schema. I am using hiveContext.read.schema().json("input.json"), and I want to ignore the first two "ErrorMessage" and "IsError" read only Report.
Below is the JSON:

 {
  "ErrorMessage": null,
  "IsError": false,
   "Report":{
      "tl":[
         {
            "TlID":"F6",
            "CID":"mo"
         },
         {
            "TlID":"Fk",
            "CID":"mo"
         }
      ]
   }
}

I created the below schema :

val schema = StructType(
            Array(
                   StructField("Report", StructType(
                     Array(
                                                     StructField
                                                     ("tl",ArrayType(StructType(Array(
                                                                    StructField("TlID", StringType),
                                                                    StructField("CID", IntegerType)
                                                                  )))))))))

Below is my json.printSchema() :
root
 |-- Report: struct (nullable = true)
 |    |-- tl: array (nullable = true)
 |    |    |-- element: struct (containsNull = true)
 |    |    |    |-- TlID: string (nullable = true)
 |    |    |    |-- CID: integer (nullable = true)

Body:
The schema is incorrect. CID in your data is clearly not String ("mo"). Use

val schema = StructType(Array(
  StructField("Report", StructType(
    Array(
        StructField
        ("tl",ArrayType(StructType(Array(
                       StructField("CID", StringType),
                       StructField("TlID", StringType)
                          )))))))))

and:

val df = Seq("""{
  "ErrorMessage": null,
  "IsError": false,
   "Report":{
      "tl":[
         {
            "TlID":"F6",
            "CID":"mo"
         },
         {
            "TlID":"Fk",
            "CID":"mo"
         }
      ]
   }
}""").toDS

spark.read.schema(schema).json(df).show(false)
+--------------------------------+
|Report                          |
+--------------------------------+
|[WrappedArray([mo,F6], [mo,Fk])]|
+--------------------------------+


问:
Adding detailed information / child rows to some entries in datatables
From the docs of datatables we see how one can add child rows or detailed information to every line in our data (JSON/CSV file). However I don't want an expand button the extension is empty like the first two data entries. This is what I work with:

Javascript

```<code>function format ( d ) {
    // `d` is the original data object for the row
    return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
        '<tr>'+
            '<td>Full name:</td>'+
            '<td>'+d.name+'</td>'+
        '</tr>'+
        '<tr>'+
            '<td>Extension number:</td>'+
            '<td>'+d.extn+'</td>'+
        '</tr>'+
        '<tr>'+
            '<td>Extra info:</td>'+
            '<td>And any further details here (images etc)...</td>'+
        '</tr>'+
    '</table>';
}

$(document).ready(function() {
    var table = $('#example').DataTable( {
        "ajax": "../ajax/data/objects.txt",
        "columns": [
            {
                "className":      'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent": ''
            },
            { "data": "name" },
            { "data": "position" },
            { "data": "office" },
            { "data": "salary" }
        ],
        "order": [[1, 'asc']]
    } );

    // Add event listener for opening and closing details
    $('#example tbody').on('click', 'td.details-control', function () {
        var tr = $(this).closest('tr');
        var row = table.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
        }
        else {
            // Open this row
            row.child( format(row.data()) ).show();
            tr.addClass('shown');
        }
    } );
} );
</code>```

HTML

```<code><table id="example" class="display" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th></th>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <th></th>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Salary</th>
            </tr>
        </tfoot>
    </table>
</code>```

JSON

```<code>{
  "data": [
    {
      "id": "1",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "$320,800",
      "start_date": "2011/04/25",
      "office": "Edinburgh",
      "extn": ""
    },
    {
      "id": "2",
      "name": "Garrett Winters",
      "position": "Accountant",
      "salary": "$170,750",
      "start_date": "2011/07/25",
      "office": "Tokyo",
      "extn": ""
    },
    {
      "id": "3",
      "name": "Ashton Cox",
      "position": "Junior Technical Author",
      "salary": "$86,000",
      "start_date": "2009/01/12",
      "office": "San Francisco",
      "extn": "1562"
    },
    {
      "id": "4",
      "name": "Cedric Kelly",
      "position": "Senior Javascript Developer",
      "salary": "$433,060",
      "start_date": "2012/03/29",
      "office": "Edinburgh",
      "extn": "6224"
    },
  ]
</code>```

As you can see both entry 1 and 2 has empty extension, and here I don't want the expand button to show up at all, just blank space. The other two where the extension is non-empty should still have the button to show this information.

答:
You can use createdRow() to check the content of the detail cell (or cells), and conditionally add the details-control class if that cell is not empty.

For example, this checks to see if the extn field has a non-empty value

```<code>$(document).ready(function() {
  var table = $('#example').DataTable({
    "data": data.data,
    "columns": [{
      "orderable": false,
      "data": null,
      "defaultContent": ''
    }, {
      "data": "name"
    }, {
      "data": "position"
    }, {
      "data": "office"
    }, {
      "data": "salary"
    }],
    "order": [
      [1, 'asc']
    ],
    "createdRow": function(row, data, dataIndex) {
      if (data.extn !== "") {
      $(row).find("td:eq(0)").addClass('details-control');
      }
    }
  });
</code>```

Here is a Fiddle Demo:  https://jsfiddle.net/zephyr_hex/rhgL0294/20/

Body:
From the docs of datatables we see how one can add child rows or detailed information to every line in our data (JSON/CSV file). However I don't want an expand button the extension is empty like the first two data entries. This is what I work with:

Javascript

function format ( d ) {
    // `d` is the original data object for the row
    return '
'+
        '
'+
            'Full name:	'+
            ''+d.name+'	'+
        '
'+
        '
'+
            'Extension number:	'+
            ''+d.extn+'	'+
        '
'+
        '
'+
            'Extra info:	'+
            'And any further details here (images etc)...	'+
        '
'+
    '
';
}

$(document).ready(function() {
    var table = $('#example').DataTable( {
        "ajax": "../ajax/data/objects.txt",
        "columns": [
            {
                "className":      'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent": ''
            },
            { "data": "name" },
            { "data": "position" },
            { "data": "office" },
            { "data": "salary" }
        ],
        "order": [[1, 'asc']]
    } );

    // Add event listener for opening and closing details
    $('#example tbody').on('click', 'td.details-control', function () {
        var tr = $(this).closest('tr');
        var row = table.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
        }
        else {
            // Open this row
            row.child( format(row.data()) ).show();
            tr.addClass('shown');
        }
    } );
} );

HTML

                Name
                Position
                Office
                Salary

                Name
                Position
                Office
                Salary

JSON

{
  "data": [
    {
      "id": "1",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "$320,800",
      "start_date": "2011/04/25",
      "office": "Edinburgh",
      "extn": ""
    },
    {
      "id": "2",
      "name": "Garrett Winters",
      "position": "Accountant",
      "salary": "$170,750",
      "start_date": "2011/07/25",
      "office": "Tokyo",
      "extn": ""
    },
    {
      "id": "3",
      "name": "Ashton Cox",
      "position": "Junior Technical Author",
      "salary": "$86,000",
      "start_date": "2009/01/12",
      "office": "San Francisco",
      "extn": "1562"
    },
    {
      "id": "4",
      "name": "Cedric Kelly",
      "position": "Senior Javascript Developer",
      "salary": "$433,060",
      "start_date": "2012/03/29",
      "office": "Edinburgh",
      "extn": "6224"
    },
  ]

As you can see both entry 1 and 2 has empty extension, and here I don't want the expand button to show up at all, just blank space. The other two where the extension is non-empty should still have the button to show this information.

Body:
You can use createdRow() to check the content of the detail cell (or cells), and conditionally add the details-control class if that cell is not empty.

For example, this checks to see if the extn field has a non-empty value

$(document).ready(function() {
  var table = $('#example').DataTable({
    "data": data.data,
    "columns": [{
      "orderable": false,
      "data": null,
      "defaultContent": ''
    }, {
      "data": "name"
    }, {
      "data": "position"
    }, {
      "data": "office"
    }, {
      "data": "salary"
    }],
    "order": [
      [1, 'asc']
    ],
    "createdRow": function(row, data, dataIndex) {
      if (data.extn !== "") {
      $(row).find("td:eq(0)").addClass('details-control');
      }
    }
  });

Here is a Fiddle Demo:  https://jsfiddle.net/zephyr_hex/rhgL0294/20/


问:
View is not found after adding a context
I'm trying to add an ACL to a view in a Pyramid project

I've got a working minimal test:

```<code>config.add_route('foo', '/foo')
</code>```

view:

```<code>@view_config(route_name='foo', renderer='../templates/foo.jinja2',
             permission='view', context=Foo)
def foo(request):
    return {}
</code>```

context:

```<code>class Foo:
    __acl__ = [
        (Allow, Everyone, 'view'),
    ]
</code>```

Which works great without the permission and context set, but after adding them, I get pyramid.httpexceptions.HTTPNotFound: /foo.

Why is this route suddenly not found? This is almost exactly copied from the tutorial.

答:
You should not specify the context in the view_config, but specify a factory in your route.

```<code>config.add_route('foo', '/foo', factory=lambda r: Foo(r))
</code>```

Also, you may have to accept the request in your __init__:

```<code>class Foo:
    def __init__(self, request):
        pass

    __acl__ = [
        (Allow, Everyone, 'view'),
    ]
</code>```

The way you did it (using context in the view_config) means "if the context is Foo, use that view function". It's a predicate.

Body:
I'm trying to add an ACL to a view in a Pyramid project

I've got a working minimal test:

config.add_route('foo', '/foo')

view:

@view_config(route_name='foo', renderer='../templates/foo.jinja2',
             permission='view', context=Foo)
def foo(request):
    return {}

context:

class Foo:
    __acl__ = [
        (Allow, Everyone, 'view'),
    ]

Which works great without the permission and context set, but after adding them, I get pyramid.httpexceptions.HTTPNotFound: /foo.

Why is this route suddenly not found? This is almost exactly copied from the tutorial.

Body:
You should not specify the context in the view_config, but specify a factory in your route.

config.add_route('foo', '/foo', factory=lambda r: Foo(r))

Also, you may have to accept the request in your __init__:

class Foo:
    def __init__(self, request):
        pass

    __acl__ = [
        (Allow, Everyone, 'view'),
    ]

The way you did it (using context in the view_config) means "if the context is Foo, use that view function". It's a predicate.


问:
Add suffix to comma-separated strings in bash ecosystem
Is there a way of transforming a comma-delimited variable to add a suffix to each token using standard gnu tools? e.g.

```<code>VARIABLE=`aaa,bbb,ccc`
suffix=`-foo`
Expected output = `aaa-foo,bbb-foo,ccc-foo`
</code>```

Additionally, if I have only one token, the transformation should behave in the same way

e.g. aaa -> aaa-foo

答:
```<code>echo $VARIBLE | tr "," "\n" | awk '{print $1"-foo"}' | paste -sd "," -
</code>```

explanation:

put each token on single line

```<code>tr "," "\n"
</code>```

append "-foo" to each token

```<code>awk '{print $1"-foo"}'
</code>```

join back up with the original comma

```<code>paste -sd "," -
</code>```

Body:
Is there a way of transforming a comma-delimited variable to add a suffix to each token using standard gnu tools? e.g.

VARIABLE=`aaa,bbb,ccc`
suffix=`-foo`
Expected output = `aaa-foo,bbb-foo,ccc-foo`

Additionally, if I have only one token, the transformation should behave in the same way

e.g. aaa -> aaa-foo

Body:
echo $VARIBLE | tr "," "\n" | awk '{print $1"-foo"}' | paste -sd "," -

explanation:

put each token on single line

tr "," "\n"

append "-foo" to each token

awk '{print $1"-foo"}'

join back up with the original comma

paste -sd "," -


问:
Match charactes and whitespaces, but not numbers
I am trying to create a regex that will match characters, whitespaces, but not numbers.

So hello 123 will not match, but hell o will.

I tried this:

```<code>[^\d\w]
</code>```

but, I cannot find a way to add whitespaces here. I have to use \w, because my strings can contain Unicode characters.

答:
Brief

It's unclear what exactly characters refers to, but, assuming you mean alpha characters (based on your input), this regex should work for you.

Code

See regex in use here

```<code>^(?:(?!\d)[\w ])+$
</code>```

Note: This regex uses the mu flags for multiline and Unicode (multiline only necessary if input is separated by newline characters)

Results

Input

```<code>ÀÇÆ some words
ÀÇÆ some words 123
</code>```

Output

This only shows matches

```<code>ÀÇÆ some words
</code>```

Explanation

^ Assert position at the start of the line

(?:(?!\d)[\w ])+ Match the following one or more times (tempered greedy token)

(?!\d) Negative lookahead ensuring what follows doesn't match a digit. You can change this to (?![\d_]) if you want to ensure _ is also not used.

[\w ] Match any word character or space (matches Unicode word characters with u flag)`

$ Assert position at the end of the line

Body:
I am trying to create a regex that will match characters, whitespaces, but not numbers.

So hello 123 will not match, but hell o will.

I tried this:

[^\d\w]

but, I cannot find a way to add whitespaces here. I have to use \w, because my strings can contain Unicode characters.

Body:
Brief

It's unclear what exactly characters refers to, but, assuming you mean alpha characters (based on your input), this regex should work for you.

Code

See regex in use here

^(?:(?!\d)[\w ])+$

Note: This regex uses the mu flags for multiline and Unicode (multiline only necessary if input is separated by newline characters)

Results

Input

ÀÇÆ some words
ÀÇÆ some words 123

Output

This only shows matches

ÀÇÆ some words

Explanation

^ Assert position at the start of the line

(?:(?!\d)[\w ])+ Match the following one or more times (tempered greedy token)

(?!\d) Negative lookahead ensuring what follows doesn't match a digit. You can change this to (?![\d_]) if you want to ensure _ is also not used.

[\w ] Match any word character or space (matches Unicode word characters with u flag)`

$ Assert position at the end of the line


答:
Try:

```<code>answer = `echo $VARIABLE | sed "s/,/-foo,/g" | sed "s/$/-foo/"`
</code>```

If you need to  have the suffix as a variable then try:

```<code>answer = `echo $VARIABLE | sed "s/,/${suffix},/g" | sed "s/$/${suffix}/"`
</code>```

I don't have access to a Unix box at the moment to prove this works.

Title: Add suffix to comma-separated strings in bash ecosystem

Body:
Try:

answer = `echo $VARIABLE | sed "s/,/-foo,/g" | sed "s/$/-foo/"`

If you need to  have the suffix as a variable then try:

answer = `echo $VARIABLE | sed "s/,/${suffix},/g" | sed "s/$/${suffix}/"`

I don't have access to a Unix box at the moment to prove this works.


问:
python code throw Exception in new environment but works fine without it
So when I debug my code in pycharm I caught an exception in urllib2.urlopen:

```<code>#!/usr/bin/python
req = urllib2.Request(urlname)
urllib2.urlopen(req)
</code>```

This is an error I caught:

```<code>'Exception Error in Token:RequestToken : (<class
\\'urllib2.URLError\\'>, URLError(SSLError(1, u\\'[SSL:
CERTIFICATE_VERIFY_FAILED] certificate verify failed
(_ssl.c:661)\\'),), <traceback object at 0x7fbcfbfb1a70>)'
</code>```

I should did like this actually:

```<code>#!/usr/bin/python
context = ssl._create_unverified_context()
req = urllib2.Request(urlname)
urllib2.urlopen(req, context=context)
</code>```

答:
Workaround could be:

```<code>import ssl
ssl._create_default_https_context = ssl._create_unverified_context
</code>```

But it is not good anyway.

Body:
So when I debug my code in pycharm I caught an exception in urllib2.urlopen:

#!/usr/bin/python
req = urllib2.Request(urlname)
urllib2.urlopen(req)

This is an error I caught:

'Exception Error in Token:RequestToken : (<class
\\'urllib2.URLError\\'>, URLError(SSLError(1, u\\'[SSL:
CERTIFICATE_VERIFY_FAILED] certificate verify failed
(_ssl.c:661)\\'),), <traceback object at 0x7fbcfbfb1a70>)'

I should did like this actually:

#!/usr/bin/python
context = ssl._create_unverified_context()
req = urllib2.Request(urlname)
urllib2.urlopen(req, context=context)

Body:
Workaround could be:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

But it is not good anyway.


Title: Python/Pandas - remove not duplicated rows

Body:
I have DataFrame like this:

        product_id          dt  stock_qty
226870     2948259  2017-11-11     17.000
233645     2948259  2017-11-12     17.000
240572     2948260  2017-11-13      5.000
247452     2948260  2017-11-14      5.000
233644     2948260  2017-11-12      5.000
226869     2948260  2017-11-11      5.000
247451     2948262  2017-11-14     -2.000
226868     2948262  2017-11-11     -1.000  <- not duplicated
240571     2948262  2017-11-13     -2.000
240570     2948264  2017-11-13      5.488
233643     2948264  2017-11-12      5.488
244543     2948269  2017-11-11      2.500
247450     2948276  2017-11-14      3.250
226867     2948276  2017-11-11      3.250

I have to remove rows where stock_qty are different but product_id values are the same. So I should get DataFrame like this:

        product_id          dt  stock_qty
226870     2948259  2017-11-11     17.000
233645     2948259  2017-11-12     17.000
240572     2948260  2017-11-13      5.000
247452     2948260  2017-11-14      5.000
233644     2948260  2017-11-12      5.000
226869     2948260  2017-11-11      5.000
240570     2948264  2017-11-13      5.488
233643     2948264  2017-11-12      5.488
244543     2948269  2017-11-11      2.500
247450     2948276  2017-11-14      3.250
226867     2948276  2017-11-11      3.250

Thanks for help!

Body:
@jezrael solution is optimal, but another way is using groupby and filter:

df.groupby(['product_id','stock_qty']).filter(lambda x: len(x)>1)

Output:

        product_id          dt  stock_qty
226870     2948259  2017-11-11     17.000
233645     2948259  2017-11-12     17.000
240572     2948260  2017-11-13      5.000
247452     2948260  2017-11-14      5.000
233644     2948260  2017-11-12      5.000
226869     2948260  2017-11-11      5.000
247451     2948262  2017-11-14     -2.000
240571     2948262  2017-11-13     -2.000
240570     2948264  2017-11-13      5.488
233643     2948264  2017-11-12      5.488
247450     2948276  2017-11-14      3.250
226867     2948276  2017-11-11      3.250


问:
position a svg at the bottom of full screen image div
I am trying to position an svg separator at bottom part of an image div.
Here is css for the latter:

```<code>.second-content {
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    background-color: #999;
    height: 100%;
    background-image: url("https://us-east.manta.joyent.com/condenast/public/cnt-services/production/2015/08/25/55dc9569f073f4db64845993_eiffel-tower-paris.jpg");
    background-color: #cccccc;
}
</code>```

Here is the relevant html part:

```<code><div class="second-content">
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 0 L70 100 L100 0 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M70 100 L100 40 L100 0 Z" />
    </svg>
    <svg  xmlns="http://www.w3.org/2000/svg" width="100%" style="bottom:0" height="100"  viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 100 L30 0 L100 100 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M30 0 L100 40 L100 100 Z" />
    </svg>
</div>
</code>```

I've tried some ways to fix the content at the bottom of the div but none of them worked for me.

Result:

答:
You should set the .second-content as relative
And then add {position: absolute} to the other two elements.
Then to the first one add {top: 0} and to the other {bottom: 0}

body,html,.second-content {height: 100%; margin: 0}
.second-content {
   background-color: #cccccc;
   position: relative
}
.second-content svg:first-child,
.second-content svg:last-child {
  position: absolute;
  top: 0;
  left: 0;
}
.second-content svg:last-child {
  top: auto;
  bottom: 0;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="second-content" style="background-color: #369">
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 0 L70 100 L100 0 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M70 100 L100 40 L100 0 Z" />
    </svg>
    <svg  xmlns="http://www.w3.org/2000/svg" width="100%" style="bottom:0" height="100"  viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 100 L30 0 L100 100 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M30 0 L100 40 L100 100 Z" />
    </svg>
</div>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<div class="second-content" style="background-color: #396">
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 0 L70 100 L100 0 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M70 100 L100 40 L100 0 Z" />
    </svg>
    <svg  xmlns="http://www.w3.org/2000/svg" width="100%" style="bottom:0" height="100"  viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 100 L30 0 L100 100 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M30 0 L100 40 L100 100 Z" />
    </svg>
</div></code>```

Body:
I am trying to position an svg separator at bottom part of an image div.
Here is css for the latter:

.second-content {
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    background-color: #999;
    height: 100%;
    background-image: url("https://us-east.manta.joyent.com/condenast/public/cnt-services/production/2015/08/25/55dc9569f073f4db64845993_eiffel-tower-paris.jpg");
    background-color: #cccccc;
}

Here is the relevant html part:

    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 0 L70 100 L100 0 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M70 100 L100 40 L100 0 Z" />
    </svg>
    <svg  xmlns="http://www.w3.org/2000/svg" width="100%" style="bottom:0" height="100"  viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 100 L30 0 L100 100 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M30 0 L100 40 L100 100 Z" />
    </svg>

I've tried some ways to fix the content at the bottom of the div but none of them worked for me.

Result:

Body:
You should set the .second-content as relative
And then add {position: absolute} to the other two elements.
Then to the first one add {top: 0} and to the other {bottom: 0}

body,html,.second-content {height: 100%; margin: 0}
.second-content {
   background-color: #cccccc;
   position: relative
}
.second-content svg:first-child,
.second-content svg:last-child {
  position: absolute;
  top: 0;
  left: 0;
}
.second-content svg:last-child {
  top: auto;
  bottom: 0;
}

<div class="second-content" style="background-color: #369">
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 0 L70 100 L100 0 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M70 100 L100 40 L100 0 Z" />
    </svg>
    <svg  xmlns="http://www.w3.org/2000/svg" width="100%" style="bottom:0" height="100"  viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 100 L30 0 L100 100 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M30 0 L100 40 L100 100 Z" />
    </svg>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="second-content" style="background-color: #396">
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 0 L70 100 L100 0 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M70 100 L100 40 L100 0 Z" />
    </svg>
    <svg  xmlns="http://www.w3.org/2000/svg" width="100%" style="bottom:0" height="100"  viewBox="0 0 100 100" preserveAspectRatio="none">
        <path stroke="white" fill="white" d="M0 100 L30 0 L100 100 Z" />
        <path stroke="#f4f4f4" fill="#f4f4f4" d="M30 0 L100 40 L100 100 Z" />
    </svg>
</div>


答:
I'd just use the json macro provided by serde_json, which works with your exact syntax:

```<code>#[macro_use]
extern crate serde_json;
extern crate serde;

fn main() {
    let x = json!({
        "appName": "Demo App",
        "appVersion": "1.0",
        "database": {
            "host": "dev.database.com",
            "port": 3000
        }
    });
}
</code>```

This creates a Value struct. If for some reason you really needed it back as a string, you'd need to re-serialize it using it's Display implementation:

```<code>extern crate serde;
#[macro_use]
extern crate serde_json;

struct StringContent(String);

macro_rules! from_json {
    ($x:tt) => {{
        StringContent(json!($x).to_string())
    }}
}

fn main() {
    let x = from_json!({
            "appName": "Demo App",
            "appVersion": "1.0",
            "database": {
                "host": "dev.database.com",
                "port": 3000
            }
        });

    println!("{}", x.0)
}
</code>```

Title: How do I change the following from_str macro to from_json?

Body:
I have the following macro. Note that StringContent is an enum item.

#[macro_export]
macro_rules! from_str {
    ($json:expr) => {
        StringContent(String::from($json))
    }
}

which allows me to write code like

from_str!(r#"{
    "appName": "Demo App",
    "appVersion": "1.0",
    "database": {
        "host": "dev.database.com",
        "port": 3000
    }
}"#)

Now I want another macro from_json! which allows me to do get rid of the r#""# like so

from_json!({
    "appName": "Demo App",
    "appVersion": "1.0",
    "database": {
        "host": "dev.database.com",
        "port": 3000
    }
})

I've tried the following which does not seem to work

#[macro_export]
macro_rules! from_json {
    ($t:tt) => {
        StringContent(String::from(concat!(r#"r#""#, stringify!($t), r#"""# , r#"#"#)))
    }
}

How can I get from_json to work?

Body:
I'd just use the json macro provided by serde_json, which works with your exact syntax:

#[macro_use]
extern crate serde_json;
extern crate serde;

fn main() {
    let x = json!({
        "appName": "Demo App",
        "appVersion": "1.0",
        "database": {
            "host": "dev.database.com",
            "port": 3000
        }
    });
}

This creates a Value struct. If for some reason you really needed it back as a string, you'd need to re-serialize it using it's Display implementation:

extern crate serde;
#[macro_use]
extern crate serde_json;

struct StringContent(String);

macro_rules! from_json {
    ($x:tt) => {{
        StringContent(json!($x).to_string())
    }}
}

fn main() {
    let x = from_json!({
            "appName": "Demo App",
            "appVersion": "1.0",
            "database": {
                "host": "dev.database.com",
                "port": 3000
            }
        });

    println!("{}", x.0)
}


问:
Up-counter in Javascript from a date
Hey I'm new here and never worked with JavaScript.
So maybe you can help me a little bit.
I wanna make an Up-counter that counts up from a date.
Everything works fine but I want to add month to the counter. Here is the Code:

window.onload=function() {
  // Month,Day,Year,Hour,Minute,Second
  upTime('jan,01,2013,00:00:00'); // ****** Change this line!
};
function upTime(countTo) {
  now = new Date();
  countTo = new Date(countTo);
  difference = (now-countTo);
  days=Math.floor(difference/(60*60*1000*24)*1);
  years = Math.floor(days / 365);
  if (years > 1){ days = days - (years * 365)}
  hours=Math.floor((difference%(60*60*1000*24))/(60*60*1000)*1);
  mins=Math.floor(((difference%(60*60*1000*24))%(60*60*1000))/(60*1000)*1);
  secs=Math.floor((((difference%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1);
  document.getElementById('years').firstChild.nodeValue = years;
  document.getElementById('days').firstChild.nodeValue = days;
  document.getElementById('hours').firstChild.nodeValue = hours;
  document.getElementById('minutes').firstChild.nodeValue = mins;
  document.getElementById('seconds').firstChild.nodeValue = secs;

  clearTimeout(upTime.to);
  upTime.to=setTimeout(function(){ upTime(countTo); },1000);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="countup">
  It's been
  <p id="years">00</p>
  <p class="timeRefYears">years</p>
  <p id="days">00</p>
  <p class="timeRefDays">days</p>
  <p id="hours">00</p>
  <p class="timeRefHours">hours</p>
  <p id="minutes">00</p>
  <p class="timeRefMinutes">minutes</p>
  <p id="seconds">00</p>
  <p class="timeRefSeconds">second</p>
</div></code>```

Maybe you can help me and I am trying to understand.
Thank you

答:
Your script cannot easily and certainly not accurately get months added

Have a look at this.

I have not fully tested it so it might need some tweaking.

When it works it should be more accurate than yours

window.onload = function() {
  // Month,Day,Year,Hour,Minute,Second
  upTime('jan,16,2013,19:30:00'); // ****** Change this line!
};

function upTime(countTo) {
  var now = new Date(), countTo = new Date(countTo),
    years  = now.getFullYear()-countTo.getFullYear(),
    months = now.getMonth()   -countTo.getMonth(),
    days   = now.getDate()    -countTo.getDate(),
    hours  = now.getHours()   -countTo.getHours(),
    mins   = now.getMinutes() -countTo.getMinutes(),
    secs   = now.getSeconds() -countTo.getSeconds();
  if (months<0) {
    years--;
    months += 12;
  }
  if (days<0) {
    months--;
    var daysOfMonth = new Date(now.getTime())
    daysOfMonth.setMonth(now.getMonth()+1)
    daysOfMonth.setDate(0);
    days+=daysOfMonth.getDate();
  }
  if (hours<0) {
    days--;
    hours+=24;
  }
  if (mins<0) {
    hours--;
    mins+=60;
  }
  if (secs<0) {
    mins--;
    secs+=60;
  }
  if (months<0) months = 0;

  document.getElementById('years'  ).innerHTML = years;
  document.getElementById('months' ).innerHTML = months;
  document.getElementById('days'   ).innerHTML = days;
  document.getElementById('hours'  ).innerHTML = hours;
  document.getElementById('minutes').innerHTML = mins;
  document.getElementById('seconds').innerHTML = secs;

  clearTimeout(upTime.to);
  upTime.to = setTimeout(function() {
    upTime(countTo);
  }, 1000);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="countup">
  It's been
  <p id="years">00</p>
  <p class="timeRefYears">years</p>
  <p id="months">00</p>
  <p class="timeRefMonths">months</p>
  <p id="days">00</p>
  <p class="timeRefDays">days</p>
  <p id="hours">00</p>
  <p class="timeRefHours">hours</p>
  <p id="minutes">00</p>
  <p class="timeRefMinutes">minutes</p>
  <p id="seconds">00</p>
  <p class="timeRefSeconds">seconds</p>
</div></code>```

Title: Up-counter in Javascript from a date

Body:
Hey I'm new here and never worked with JavaScript.
So maybe you can help me a little bit.
I wanna make an Up-counter that counts up from a date.
Everything works fine but I want to add month to the counter. Here is the Code:

window.onload=function() {
  // Month,Day,Year,Hour,Minute,Second
  upTime('jan,01,2013,00:00:00'); // ****** Change this line!
};
function upTime(countTo) {
  now = new Date();
  countTo = new Date(countTo);
  difference = (now-countTo);
  days=Math.floor(difference/(60*60*1000*24)*1);
  years = Math.floor(days / 365);
  if (years > 1){ days = days - (years * 365)}
  hours=Math.floor((difference%(60*60*1000*24))/(60*60*1000)*1);
  mins=Math.floor(((difference%(60*60*1000*24))%(60*60*1000))/(60*1000)*1);
  secs=Math.floor((((difference%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1);
  document.getElementById('years').firstChild.nodeValue = years;
  document.getElementById('days').firstChild.nodeValue = days;
  document.getElementById('hours').firstChild.nodeValue = hours;
  document.getElementById('minutes').firstChild.nodeValue = mins;
  document.getElementById('seconds').firstChild.nodeValue = secs;

  clearTimeout(upTime.to);
  upTime.to=setTimeout(function(){ upTime(countTo); },1000);
}

  It's been

00

years

00

days

00

hours

00

minutes

00

second

Maybe you can help me and I am trying to understand.
Thank you

Body:
Your script cannot easily and certainly not accurately get months added

Have a look at this.

I have not fully tested it so it might need some tweaking.

When it works it should be more accurate than yours

window.onload = function() {
  // Month,Day,Year,Hour,Minute,Second
  upTime('jan,16,2013,19:30:00'); // ****** Change this line!
};

function upTime(countTo) {
  var now = new Date(), countTo = new Date(countTo),
    years  = now.getFullYear()-countTo.getFullYear(),
    months = now.getMonth()   -countTo.getMonth(),
    days   = now.getDate()    -countTo.getDate(),
    hours  = now.getHours()   -countTo.getHours(),
    mins   = now.getMinutes() -countTo.getMinutes(),
    secs   = now.getSeconds() -countTo.getSeconds();
  if (months<0) {
    years--;
    months += 12;
  }
  if (days<0) {
    months--;
    var daysOfMonth = new Date(now.getTime())
    daysOfMonth.setMonth(now.getMonth()+1)
    daysOfMonth.setDate(0);
    days+=daysOfMonth.getDate();
  }
  if (hours<0) {
    days--;
    hours+=24;
  }
  if (mins<0) {
    hours--;
    mins+=60;
  }
  if (secs<0) {
    mins--;
    secs+=60;
  }
  if (months<0) months = 0;

  document.getElementById('years'  ).innerHTML = years;
  document.getElementById('months' ).innerHTML = months;
  document.getElementById('days'   ).innerHTML = days;
  document.getElementById('hours'  ).innerHTML = hours;
  document.getElementById('minutes').innerHTML = mins;
  document.getElementById('seconds').innerHTML = secs;

  clearTimeout(upTime.to);
  upTime.to = setTimeout(function() {
    upTime(countTo);
  }, 1000);
}

<div id="countup">
  It's been
  <p id="years">00</p>
  <p class="timeRefYears">years</p>
  <p id="months">00</p>
  <p class="timeRefMonths">months</p>
  <p id="days">00</p>
  <p class="timeRefDays">days</p>
  <p id="hours">00</p>
  <p class="timeRefHours">hours</p>
  <p id="minutes">00</p>
  <p class="timeRefMinutes">minutes</p>
  <p id="seconds">00</p>
  <p class="timeRefSeconds">seconds</p>
</div>


问:
String Benchmarks in C# - Refactoring for Speed/Maintainability
I've been tinkering with small functions on my own time, trying to find ways to refactor them (I recently read Martin Fowler's book Refactoring: Improving the Design of Existing Code).  I found the following function MakeNiceString() while updating another part of the codebase near it, and it looked like a good candidate to mess with.  As it is, there's no real reason to replace it, but it's small enough and does something small so it's easy to follow and yet still get a 'good' experience from.

```<code>private static string MakeNiceString(string str)
        {
            char[] ca = str.ToCharArray();
            string result = null;
            int i = 0;
            result += System.Convert.ToString(ca[0]);
            for (i = 1; i <= ca.Length - 1; i++)
            {
                if (!(char.IsLower(ca[i])))
                {
                    result += " ";
                }
                result += System.Convert.ToString(ca[i]);
            }
            return result;
        }

static string SplitCamelCase(string str)
    {
        string[] temp = Regex.Split(str, @"(?<!^)(?=[A-Z])");
        string result = String.Join(" ", temp);
        return result;
    }
</code>```

The first function MakeNiceString() is the function I found in some code I was updating at work.  The purpose of the function is to translate ThisIsAString to This Is A String.  It's used in a half-dozen places in the code, and is pretty insignificant in the whole scheme of things.

I built the second function purely as an academic exercise to see if using a regular expression would take longer or not.

Well, here are the results:

With 10 Iterations:

```
MakeNiceString took 2649 ticks
SplitCamelCase took 2502 ticks
```

However, it changes drastically over the longhaul:

With 10,000 Iterations:

```
MakeNiceString took 121625 ticks
SplitCamelCase took 443001 ticks
```

Refactoring MakeNiceString()

The process of refactoring MakeNiceString() started with simply removing the conversions that were taking place.  Doing that yielded the following results:

```
MakeNiceString took 124716 ticks
ImprovedMakeNiceString took 118486
```

Here's the code after Refactor #1:

```<code>private static string ImprovedMakeNiceString(string str)
        { //Removed Convert.ToString()
            char[] ca = str.ToCharArray();
            string result = null;
            int i = 0;
            result += ca[0];
            for (i = 1; i <= ca.Length - 1; i++)
            {
                if (!(char.IsLower(ca[i])))
                {
                    result += " ";
                }
                result += ca[i];
            }
            return result;
        }
</code>```

Refactor#2 - Use StringBuilder

My second task was to use StringBuilder instead of String.  Since String is immutable, unnecessary copies were being created throughout the loop.  The benchmark for using that is below, as is the code:

```<code>static string RefactoredMakeNiceString(string str)
        {
            char[] ca = str.ToCharArray();
            StringBuilder sb = new StringBuilder((str.Length * 5 / 4));
            int i = 0;
            sb.Append(ca[0]);
            for (i = 1; i <= ca.Length - 1; i++)
            {
                if (!(char.IsLower(ca[i])))
                {
                    sb.Append(" ");
                }
                sb.Append(ca[i]);
            }
            return sb.ToString();
        }
</code>```

This results in the following Benchmark:

```
MakeNiceString Took:           124497 Ticks   //Original
SplitCamelCase Took:           464459 Ticks   //Regex
ImprovedMakeNiceString Took:   117369 Ticks   //Remove Conversion
RefactoredMakeNiceString Took:  38542 Ticks   //Using StringBuilder
```

Changing the for loop to a foreach loop resulted in the following benchmark result:

```<code>static string RefactoredForEachMakeNiceString(string str)
        {
            char[] ca = str.ToCharArray();
            StringBuilder sb1 = new StringBuilder((str.Length * 5 / 4));
            sb1.Append(ca[0]);
            foreach (char c in ca)
            {
                if (!(char.IsLower(c)))
                {
                    sb1.Append(" ");
                }
                sb1.Append(c);
            }
            return sb1.ToString();
        }
</code>```

```
RefactoredForEachMakeNiceString    Took:  45163 Ticks
```

As you can see, maintenance-wise, the foreach loop will be the easiest to maintain and have the 'cleanest' look.  It is slightly slower than the for loop, but infinitely easier to follow.

Alternate Refactor: Use Compiled Regex

I moved the Regex to right before the loop is begun, in hopes that since it only compiles it once, it'll execute faster.  What I found out (and I'm sure I have a bug somewhere) is that that doesn't happen like it ought to:

```<code>static void runTest5()
        {
            Regex rg = new Regex(@"(?<!^)(?=[A-Z])", RegexOptions.Compiled);
            for (int i = 0; i < 10000; i++)
            {
                CompiledRegex(rg, myString);
            }
        }
 static string CompiledRegex(Regex regex, string str)
    {
        string result = null;
        Regex rg1 = regex;
        string[] temp = rg1.Split(str);
        result = String.Join(" ", temp);
        return result;
    }
</code>```

Final Benchmark Results:

```
MakeNiceString took 2649 ticks
SplitCamelCase took 2502 ticks
```0

Or, if you prefer milliseconds:

```
MakeNiceString took 2649 ticks
SplitCamelCase took 2502 ticks
```1

So the percentage gains are:

```
MakeNiceString took 2649 ticks
SplitCamelCase took 2502 ticks
```2

(Please check my math)

In the end, I'm going to replace what's there with the RefactoredForEachMakeNiceString() and while I'm at it, I'm going to rename it to something useful, like SplitStringOnUpperCase.

Benchmark Test:

To benchmark, I simply invoke a new Stopwatch for each method call:

```<code>       string myString = "ThisIsAUpperCaseString";
       Stopwatch sw = new Stopwatch();
       sw.Start();
       runTest();
       sw.Stop();

     static void runTest()
        {

            for (int i = 0; i < 10000; i++)
            {
                MakeNiceString(myString);
            }

        }
</code>```

Questions

What causes these functions to be so different 'over the long haul', and

How can I improve this function
a) to be more maintainable or
b) to run faster?

How would I do memory benchmarks on these to see which used less memory?

Thank you for your responses thus far. I've inserted all of the suggestions made by @Jon Skeet, and would like feedback on the updated questions I've asked as a result.

NB: This question is meant to explore ways to refactor string handling functions in C#. I copied/pasted the first code as is.  I'm well aware you can remove the System.Convert.ToString() in the first method, and I did just that.  If anyone is aware of any implications of removing the System.Convert.ToString(), that would also be helpful to know.

答:
1) Use a StringBuilder, preferrably set with a reasonable initial capacity (e.g. string length * 5/4, to allow one extra space per four characters).

2) Try using a foreach loop instead of a for loop - it may well be simpler

3) You don't need to convert the string into a char array first - foreach will work over a string already, or use the indexer.

4) Don't do extra string conversions everywhere - calling Convert.ToString(char) and then appending that string is pointless; there's no need for the single character string

5) For the second option, just build the regex once, outside the method. Try it with RegexOptions.Compiled as well.

EDIT: Okay, full benchmark results. I've tried a few more things, and also executed the code with rather more iterations to get a more accurate result. This is only running on an Eee PC, so no doubt it'll run faster on "real" PCs, but I suspect the broad results are appropriate. First the code:

```<code>using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

class Benchmark
{
    const string TestData = "ThisIsAUpperCaseString";
    const string ValidResult = "This Is A Upper Case String";
    const int Iterations = 1000000;

    static void Main(string[] args)
    {
        Test(BenchmarkOverhead);
        Test(MakeNiceString);
        Test(ImprovedMakeNiceString);
        Test(RefactoredMakeNiceString);
        Test(MakeNiceStringWithStringIndexer);
        Test(MakeNiceStringWithForeach);
        Test(MakeNiceStringWithForeachAndLinqSkip);
        Test(MakeNiceStringWithForeachAndCustomSkip);
        Test(SplitCamelCase);
        Test(SplitCamelCaseCachedRegex);
        Test(SplitCamelCaseCompiledRegex);
    }

    static void Test(Func<string,string> function)
    {
        Console.Write("{0}... ", function.Method.Name);
        Stopwatch sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            string result = function(TestData);
            if (result.Length != ValidResult.Length)
            {
                throw new Exception("Bad result: " + result);
            }
        }
        sw.Stop();
        Console.WriteLine(" {0}ms", sw.ElapsedMilliseconds);
        GC.Collect();
    }

    private static string BenchmarkOverhead(string str)
    {
        return ValidResult;
    }

    private static string MakeNiceString(string str)
    {
        char[] ca = str.ToCharArray();
        string result = null;
        int i = 0;
        result += System.Convert.ToString(ca[0]);
        for (i = 1; i <= ca.Length - 1; i++)
        {
            if (!(char.IsLower(ca[i])))
            {
                result += " ";
            }
            result += System.Convert.ToString(ca[i]);
        }
        return result;
    }

    private static string ImprovedMakeNiceString(string str)
    { //Removed Convert.ToString()
        char[] ca = str.ToCharArray();
        string result = null;
        int i = 0;
        result += ca[0];
        for (i = 1; i <= ca.Length - 1; i++)
        {
            if (!(char.IsLower(ca[i])))
            {
                result += " ";
            }
            result += ca[i];
        }
        return result;
    }

    private static string RefactoredMakeNiceString(string str)
    {
        char[] ca = str.ToCharArray();
        StringBuilder sb = new StringBuilder((str.Length * 5 / 4));
        int i = 0;
        sb.Append(ca[0]);
        for (i = 1; i <= ca.Length - 1; i++)
        {
            if (!(char.IsLower(ca[i])))
            {
                sb.Append(" ");
            }
            sb.Append(ca[i]);
        }
        return sb.ToString();
    }

    private static string MakeNiceStringWithStringIndexer(string str)
    {
        StringBuilder sb = new StringBuilder((str.Length * 5 / 4));
        sb.Append(str[0]);
        for (int i = 1; i < str.Length; i++)
        {
            char c = str[i];
            if (!(char.IsLower(c)))
            {
                sb.Append(" ");
            }
            sb.Append(c);
        }
        return sb.ToString();
    }

    private static string MakeNiceStringWithForeach(string str)
    {
        StringBuilder sb = new StringBuilder(str.Length * 5 / 4);
        bool first = true;
        foreach (char c in str)
        {
            if (!first && char.IsUpper(c))
            {
                sb.Append(" ");
            }
            sb.Append(c);
            first = false;
        }
        return sb.ToString();
    }

    private static string MakeNiceStringWithForeachAndLinqSkip(string str)
    {
        StringBuilder sb = new StringBuilder(str.Length * 5 / 4);
        sb.Append(str[0]);
        foreach (char c in str.Skip(1))
        {
            if (char.IsUpper(c))
            {
                sb.Append(" ");
            }
            sb.Append(c);
        }
        return sb.ToString();
    }

    private static string MakeNiceStringWithForeachAndCustomSkip(string str)
    {
        StringBuilder sb = new StringBuilder(str.Length * 5 / 4);
        sb.Append(str[0]);
        foreach (char c in new SkipEnumerable<char>(str, 1))
        {
            if (char.IsUpper(c))
            {
                sb.Append(" ");
            }
            sb.Append(c);
        }
        return sb.ToString();
    }

    private static string SplitCamelCase(string str)
    {
        string[] temp = Regex.Split(str, @"(?<!^)(?=[A-Z])");
        string result = String.Join(" ", temp);
        return result;
    }

    private static readonly Regex CachedRegex = new Regex("(?<!^)(?=[A-Z])");
    private static string SplitCamelCaseCachedRegex(string str)
    {
        string[] temp = CachedRegex.Split(str);
        string result = String.Join(" ", temp);
        return result;
    }

    private static readonly Regex CompiledRegex =
        new Regex("(?<!^)(?=[A-Z])", RegexOptions.Compiled);
    private static string SplitCamelCaseCompiledRegex(string str)
    {
        string[] temp = CompiledRegex.Split(str);
        string result = String.Join(" ", temp);
        return result;
    }

    private class SkipEnumerable<T> : IEnumerable<T>
    {
        private readonly IEnumerable<T> original;
        private readonly int skip;

        public SkipEnumerable(IEnumerable<T> original, int skip)
        {
            this.original = original;
            this.skip = skip;
        }

        public IEnumerator<T> GetEnumerator()
        {
            IEnumerator<T> ret = original.GetEnumerator();
            for (int i=0; i < skip; i++)
            {
                ret.MoveNext();
            }
            return ret;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}
</code>```

Now the results:

```<code>BenchmarkOverhead...  22ms
MakeNiceString...  10062ms
ImprovedMakeNiceString...  12367ms
RefactoredMakeNiceString...  3489ms
MakeNiceStringWithStringIndexer...  3115ms
MakeNiceStringWithForeach...  3292ms
MakeNiceStringWithForeachAndLinqSkip...  5702ms
MakeNiceStringWithForeachAndCustomSkip...  4490ms
SplitCamelCase...  68267ms
SplitCamelCaseCachedRegex...  52529ms
SplitCamelCaseCompiledRegex...  26806ms
</code>```

As you can see, the string indexer version is the winner - it's also pretty simple code.

Hope this helps... and don't forget, there are bound to be other options I haven't thought of!

OwnerDisplayName: Gortok

ContentLicense: CC BY-SA 2.5

Body:
I've been tinkering with small functions on my own time, trying to find ways to refactor them (I recently read Martin Fowler's book Refactoring: Improving the Design of Existing Code).  I found the following function MakeNiceString() while updating another part of the codebase near it, and it looked like a good candidate to mess with.  As it is, there's no real reason to replace it, but it's small enough and does something small so it's easy to follow and yet still get a 'good' experience from.

private static string MakeNiceString(string str)
        {
            char[] ca = str.ToCharArray();
            string result = null;
            int i = 0;
            result += System.Convert.ToString(ca[0]);
            for (i = 1; i <= ca.Length - 1; i++)
            {
                if (!(char.IsLower(ca[i])))
                {
                    result += " ";
                }
                result += System.Convert.ToString(ca[i]);
            }
            return result;
        }

static string SplitCamelCase(string str)
    {
        string[] temp = Regex.Split(str, @"(?<!^)(?=[A-Z])");
        string result = String.Join(" ", temp);
        return result;
    }

The first function MakeNiceString() is the function I found in some code I was updating at work.  The purpose of the function is to translate ThisIsAString to This Is A String.  It's used in a half-dozen places in the code, and is pretty insignificant in the whole scheme of things.

I built the second function purely as an academic exercise to see if using a regular expression would take longer or not.

Well, here are the results:

With 10 Iterations:

MakeNiceString took 2649 ticks
SplitCamelCase took 2502 ticks

However, it changes drastically over the longhaul:

With 10,000 Iterations:

MakeNiceString took 121625 ticks
SplitCamelCase took 443001 ticks

Refactoring MakeNiceString()

The process of refactoring MakeNiceString() started with simply removing the conversions that were taking place.  Doing that yielded the following results:

MakeNiceString took 124716 ticks
ImprovedMakeNiceString took 118486

Here's the code after Refactor #1:

private static string ImprovedMakeNiceString(string str)
        { //Removed Convert.ToString()
            char[] ca = str.ToCharArray();
            string result = null;
            int i = 0;
            result += ca[0];
            for (i = 1; i <= ca.Length - 1; i++)
            {
                if (!(char.IsLower(ca[i])))
                {
                    result += " ";
                }
                result += ca[i];
            }
            return result;
        }

Refactor#2 - Use StringBuilder

My second task was to use StringBuilder instead of String.  Since String is immutable, unnecessary copies were being created throughout the loop.  The benchmark for using that is below, as is the code:

static string RefactoredMakeNiceString(string str)
        {
            char[] ca = str.ToCharArray();
            StringBuilder sb = new StringBuilder((str.Length * 5 / 4));
            int i = 0;
            sb.Append(ca[0]);
            for (i = 1; i <= ca.Length - 1; i++)
            {
                if (!(char.IsLower(ca[i])))
                {
                    sb.Append(" ");
                }
                sb.Append(ca[i]);
            }
            return sb.ToString();
        }

This results in the following Benchmark:

MakeNiceString Took:           124497 Ticks   //Original
SplitCamelCase Took:           464459 Ticks   //Regex
ImprovedMakeNiceString Took:   117369 Ticks   //Remove Conversion
RefactoredMakeNiceString Took:  38542 Ticks   //Using StringBuilder

Changing the for loop to a foreach loop resulted in the following benchmark result:

static string RefactoredForEachMakeNiceString(string str)
        {
            char[] ca = str.ToCharArray();
            StringBuilder sb1 = new StringBuilder((str.Length * 5 / 4));
            sb1.Append(ca[0]);
            foreach (char c in ca)
            {
                if (!(char.IsLower(c)))
                {
                    sb1.Append(" ");
                }
                sb1.Append(c);
            }
            return sb1.ToString();
        }

RefactoredForEachMakeNiceString    Took:  45163 Ticks

As you can see, maintenance-wise, the foreach loop will be the easiest to maintain and have the 'cleanest' look.  It is slightly slower than the for loop, but infinitely easier to follow.

Alternate Refactor: Use Compiled Regex

I moved the Regex to right before the loop is begun, in hopes that since it only compiles it once, it'll execute faster.  What I found out (and I'm sure I have a bug somewhere) is that that doesn't happen like it ought to:

static void runTest5()
        {
            Regex rg = new Regex(@"(?<!^)(?=[A-Z])", RegexOptions.Compiled);
            for (int i = 0; i < 10000; i++)
            {
                CompiledRegex(rg, myString);
            }
        }
 static string CompiledRegex(Regex regex, string str)
    {
        string result = null;
        Regex rg1 = regex;
        string[] temp = rg1.Split(str);
        result = String.Join(" ", temp);
        return result;
    }

Final Benchmark Results:

MakeNiceString Took                   139363 Ticks
SplitCamelCase Took                   489174 Ticks
ImprovedMakeNiceString Took           115478 Ticks
RefactoredMakeNiceString Took          38819 Ticks
RefactoredForEachMakeNiceString Took   44700 Ticks
CompiledRegex Took                    227021 Ticks

Or, if you prefer milliseconds:

MakeNiceString Took                  38 ms
SplitCamelCase Took                 123 ms
ImprovedMakeNiceString Took          33 ms
RefactoredMakeNiceString Took        11 ms
RefactoredForEachMakeNiceString Took 12 ms
CompiledRegex Took                   63 ms

So the percentage gains are:

MakeNiceString                   38 ms   Baseline
SplitCamelCase                  123 ms   223% slower
ImprovedMakeNiceString           33 ms   13.15% faster
RefactoredMakeNiceString         11 ms   71.05% faster
RefactoredForEachMakeNiceString  12 ms   68.42% faster
CompiledRegex                    63 ms   65.79% slower

(Please check my math)

In the end, I'm going to replace what's there with the RefactoredForEachMakeNiceString() and while I'm at it, I'm going to rename it to something useful, like SplitStringOnUpperCase.

Benchmark Test:

To benchmark, I simply invoke a new Stopwatch for each method call:

       string myString = "ThisIsAUpperCaseString";
       Stopwatch sw = new Stopwatch();
       sw.Start();
       runTest();
       sw.Stop();

     static void runTest()
        {

            for (int i = 0; i < 10000; i++)
            {
                MakeNiceString(myString);
            }

        }

Questions

What causes these functions to be so different 'over the long haul', and

How can I improve this function
a) to be more maintainable or
b) to run faster?

How would I do memory benchmarks on these to see which used less memory?

Thank you for your responses thus far. I've inserted all of the suggestions made by @Jon Skeet, and would like feedback on the updated questions I've asked as a result.

NB: This question is meant to explore ways to refactor string handling functions in C#. I copied/pasted the first code as is.  I'm well aware you can remove the System.Convert.ToString() in the first method, and I did just that.  If anyone is aware of any implications of removing the System.Convert.ToString(), that would also be helpful to know.

LastEditorDisplayName: Gortok

Body:
1) Use a StringBuilder, preferrably set with a reasonable initial capacity (e.g. string length * 5/4, to allow one extra space per four characters).

2) Try using a foreach loop instead of a for loop - it may well be simpler

3) You don't need to convert the string into a char array first - foreach will work over a string already, or use the indexer.

4) Don't do extra string conversions everywhere - calling Convert.ToString(char) and then appending that string is pointless; there's no need for the single character string

5) For the second option, just build the regex once, outside the method. Try it with RegexOptions.Compiled as well.

EDIT: Okay, full benchmark results. I've tried a few more things, and also executed the code with rather more iterations to get a more accurate result. This is only running on an Eee PC, so no doubt it'll run faster on "real" PCs, but I suspect the broad results are appropriate. First the code:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

class Benchmark
{
    const string TestData = "ThisIsAUpperCaseString";
    const string ValidResult = "This Is A Upper Case String";
    const int Iterations = 1000000;

    static void Main(string[] args)
    {
        Test(BenchmarkOverhead);
        Test(MakeNiceString);
        Test(ImprovedMakeNiceString);
        Test(RefactoredMakeNiceString);
        Test(MakeNiceStringWithStringIndexer);
        Test(MakeNiceStringWithForeach);
        Test(MakeNiceStringWithForeachAndLinqSkip);
        Test(MakeNiceStringWithForeachAndCustomSkip);
        Test(SplitCamelCase);
        Test(SplitCamelCaseCachedRegex);
        Test(SplitCamelCaseCompiledRegex);
    }

    static void Test(Func<string,string> function)
    {
        Console.Write("{0}... ", function.Method.Name);
        Stopwatch sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            string result = function(TestData);
            if (result.Length != ValidResult.Length)
            {
                throw new Exception("Bad result: " + result);
            }
        }
        sw.Stop();
        Console.WriteLine(" {0}ms", sw.ElapsedMilliseconds);
        GC.Collect();
    }

    private static string BenchmarkOverhead(string str)
    {
        return ValidResult;
    }

    private static string MakeNiceString(string str)
    {
        char[] ca = str.ToCharArray();
        string result = null;
        int i = 0;
        result += System.Convert.ToString(ca[0]);
        for (i = 1; i <= ca.Length - 1; i++)
        {
            if (!(char.IsLower(ca[i])))
            {
                result += " ";
            }
            result += System.Convert.ToString(ca[i]);
        }
        return result;
    }

    private static string ImprovedMakeNiceString(string str)
    { //Removed Convert.ToString()
        char[] ca = str.ToCharArray();
        string result = null;
        int i = 0;
        result += ca[0];
        for (i = 1; i <= ca.Length - 1; i++)
        {
            if (!(char.IsLower(ca[i])))
            {
                result += " ";
            }
            result += ca[i];
        }
        return result;
    }

    private static string RefactoredMakeNiceString(string str)
    {
        char[] ca = str.ToCharArray();
        StringBuilder sb = new StringBuilder((str.Length * 5 / 4));
        int i = 0;
        sb.Append(ca[0]);
        for (i = 1; i <= ca.Length - 1; i++)
        {
            if (!(char.IsLower(ca[i])))
            {
                sb.Append(" ");
            }
            sb.Append(ca[i]);
        }
        return sb.ToString();
    }

    private static string MakeNiceStringWithStringIndexer(string str)
    {
        StringBuilder sb = new StringBuilder((str.Length * 5 / 4));
        sb.Append(str[0]);
        for (int i = 1; i < str.Length; i++)
        {
            char c = str[i];
            if (!(char.IsLower(c)))
            {
                sb.Append(" ");
            }
            sb.Append(c);
        }
        return sb.ToString();
    }

    private static string MakeNiceStringWithForeach(string str)
    {
        StringBuilder sb = new StringBuilder(str.Length * 5 / 4);
        bool first = true;
        foreach (char c in str)
        {
            if (!first && char.IsUpper(c))
            {
                sb.Append(" ");
            }
            sb.Append(c);
            first = false;
        }
        return sb.ToString();
    }

    private static string MakeNiceStringWithForeachAndLinqSkip(string str)
    {
        StringBuilder sb = new StringBuilder(str.Length * 5 / 4);
        sb.Append(str[0]);
        foreach (char c in str.Skip(1))
        {
            if (char.IsUpper(c))
            {
                sb.Append(" ");
            }
            sb.Append(c);
        }
        return sb.ToString();
    }

    private static string MakeNiceStringWithForeachAndCustomSkip(string str)
    {
        StringBuilder sb = new StringBuilder(str.Length * 5 / 4);
        sb.Append(str[0]);
        foreach (char c in new SkipEnumerable<char>(str, 1))
        {
            if (char.IsUpper(c))
            {
                sb.Append(" ");
            }
            sb.Append(c);
        }
        return sb.ToString();
    }

    private static string SplitCamelCase(string str)
    {
        string[] temp = Regex.Split(str, @"(?<!^)(?=[A-Z])");
        string result = String.Join(" ", temp);
        return result;
    }

    private static readonly Regex CachedRegex = new Regex("(?<!^)(?=[A-Z])");
    private static string SplitCamelCaseCachedRegex(string str)
    {
        string[] temp = CachedRegex.Split(str);
        string result = String.Join(" ", temp);
        return result;
    }

    private static readonly Regex CompiledRegex =
        new Regex("(?<!^)(?=[A-Z])", RegexOptions.Compiled);
    private static string SplitCamelCaseCompiledRegex(string str)
    {
        string[] temp = CompiledRegex.Split(str);
        string result = String.Join(" ", temp);
        return result;
    }

    private class SkipEnumerable<T> : IEnumerable<T>
    {
        private readonly IEnumerable<T> original;
        private readonly int skip;

        public SkipEnumerable(IEnumerable<T> original, int skip)
        {
            this.original = original;
            this.skip = skip;
        }

        public IEnumerator<T> GetEnumerator()
        {
            IEnumerator<T> ret = original.GetEnumerator();
            for (int i=0; i < skip; i++)
            {
                ret.MoveNext();
            }
            return ret;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

Now the results:

BenchmarkOverhead...  22ms
MakeNiceString...  10062ms
ImprovedMakeNiceString...  12367ms
RefactoredMakeNiceString...  3489ms
MakeNiceStringWithStringIndexer...  3115ms
MakeNiceStringWithForeach...  3292ms
MakeNiceStringWithForeachAndLinqSkip...  5702ms
MakeNiceStringWithForeachAndCustomSkip...  4490ms
SplitCamelCase...  68267ms
SplitCamelCaseCachedRegex...  52529ms
SplitCamelCaseCompiledRegex...  26806ms

As you can see, the string indexer version is the winner - it's also pretty simple code.

Hope this helps... and don't forget, there are bound to be other options I haven't thought of!

OwnerDisplayName: Jon Skeet

LastEditorDisplayName: Jon Skeet