问:
Is there a configuration setting to globally set the :default_strategy to :build for all factory_girl Factories?
I know you can override the default strategy for creating a Factory object like so:

```<code>Factory.define :person, :default_strategy => :build do
  # stuff
end

Factory.define :person, :default_strategy => :create do
  # stuff
end

# same behavior as the previous factory
Factory.define :person do
  # stuff
end
</code>```

but I'm wondering if I can add a setting to a factory_girl config file or maybe in the /environments/test.rb file so that

```<code>Factory.define :person do
  # stuff
end
</code>```

builds a Person object by default and not create one by default.

答:
From the source:

```<code>module FactoryGirl
  class Factory
    # ...
    def default_strategy #:nodoc:
      @options[:default_strategy] || :create
    end
    # ...
  end
end
</code>```

The default strategy equals the strategy that is passed as an option to the definition, and otherwise is set to :create. So it seems that's it not possible to set the strategy for all factories unless you monkey-patch FactoryGirl::Factory#default_strategy.

Body:
I know you can override the default strategy for creating a Factory object like so:

Factory.define :person, :default_strategy => :build do
  # stuff
end

Factory.define :person, :default_strategy => :create do
  # stuff
end

# same behavior as the previous factory
Factory.define :person do
  # stuff
end

but I'm wondering if I can add a setting to a factory_girl config file or maybe in the /environments/test.rb file so that

Factory.define :person do
  # stuff
end

builds a Person object by default and not create one by default.

Body:
From the source:

module FactoryGirl
  class Factory
    # ...
    def default_strategy #:nodoc:
      @options[:default_strategy] || :create
    end
    # ...
  end
end

The default strategy equals the strategy that is passed as an option to the definition, and otherwise is set to :create. So it seems that's it not possible to set the strategy for all factories unless you monkey-patch FactoryGirl::Factory#default_strategy.


来源: stackexchange

问:
No outlines on bins of Matplotlib histograms or Seaborn distplots
While doing some practice problems using seaborn and a Jupyter notebook, I realized that the distplot() graphs did not have the darker outlines on the individual bins that all of the sample graphs in the documentation have.  I tried creating the graphs using Pycharm and noticed the same thing.  Thinking it was a seaborn problem, I tried some hist() charts using matplotlib, only to get the same results.

```<code>import matplotlib.pyplot as plt
import seaborn as sns
titanic = sns.load_dataset('titanic')
plt.hist(titanic['fare'], bins=30)
</code>```

yielded the following graph:

Finally I stumbled across the 'edgecolor' parameter on the plt.hist() function, and setting it to black did the trick.  Unfortunately I haven't found a similar parameter to use on the seaborn distplot() function, so I am still unable to get a chart that looks like it should.

I looked into changing the rcParams in matplotlib, but I have no experience with that and the following script I ran seemed to do nothing:

```<code>import matplotlib as mpl

mpl.rcParams['lines.linewidth'] = 1
mpl.rcParams['lines.color'] = 'black'
mpl.rcParams['patch.linewidth'] = 1
mpl.rcParams['patch.edgecolor'] = 'black'
mpl.rcParams['axes.linewidth'] = 1
mpl.rcParams['axes.edgecolor'] = 'black'
</code>```

I was just kind of guessing at the value I was supposed to change, but running my graphs again showed no changes.

I then attempted to go back to the default settings using mpl.rcdefaults()
but once again, no change.

I reinstalled matplotlib using conda but still the graphs look the same.  I am running out of ideas on how to change the default edge color for these charts.  I am running the latest versions of Python, matplotlib, and seaborn using the Conda build.

答:
As part of the update to matplotlib 2.0 the edges on bar plots are turned off by default. However, you may use the rcParam

```<code>plt.rcParams["patch.force_edgecolor"] = True
</code>```

to turn the edges on globally.

Probably the easiest option is to specifically set the edgecolor when creating a seaborn plot, using the hist_kws argument,

```<code>ax = sns.distplot(x, hist_kws=dict(edgecolor="k", linewidth=2))
</code>```

For matplotlib plots, you can directly use the edgecolor or ec argument.

```<code>plt.bar(x,y, edgecolor="k")
plt.hist(x, edgecolor="k")
</code>```

Equally, for pandas plots,

```<code>df.plot(kind='hist',edgecolor="k")
</code>```

A complete seaborn example:

```<code>import  numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

x = np.random.randn(100)
ax = sns.distplot(x, hist_kws=dict(edgecolor="k", linewidth=2))
plt.show()
</code>```

ContentLicense: CC BY-SA 3.0

Body:
While doing some practice problems using seaborn and a Jupyter notebook, I realized that the distplot() graphs did not have the darker outlines on the individual bins that all of the sample graphs in the documentation have.  I tried creating the graphs using Pycharm and noticed the same thing.  Thinking it was a seaborn problem, I tried some hist() charts using matplotlib, only to get the same results.

import matplotlib.pyplot as plt
import seaborn as sns
titanic = sns.load_dataset('titanic')
plt.hist(titanic['fare'], bins=30)

yielded the following graph:

Finally I stumbled across the 'edgecolor' parameter on the plt.hist() function, and setting it to black did the trick.  Unfortunately I haven't found a similar parameter to use on the seaborn distplot() function, so I am still unable to get a chart that looks like it should.

I looked into changing the rcParams in matplotlib, but I have no experience with that and the following script I ran seemed to do nothing:

import matplotlib as mpl

mpl.rcParams['lines.linewidth'] = 1
mpl.rcParams['lines.color'] = 'black'
mpl.rcParams['patch.linewidth'] = 1
mpl.rcParams['patch.edgecolor'] = 'black'
mpl.rcParams['axes.linewidth'] = 1
mpl.rcParams['axes.edgecolor'] = 'black'

I was just kind of guessing at the value I was supposed to change, but running my graphs again showed no changes.

I then attempted to go back to the default settings using mpl.rcdefaults()
but once again, no change.

I reinstalled matplotlib using conda but still the graphs look the same.  I am running out of ideas on how to change the default edge color for these charts.  I am running the latest versions of Python, matplotlib, and seaborn using the Conda build.

Body:
As part of the update to matplotlib 2.0 the edges on bar plots are turned off by default. However, you may use the rcParam

plt.rcParams["patch.force_edgecolor"] = True

to turn the edges on globally.

Probably the easiest option is to specifically set the edgecolor when creating a seaborn plot, using the hist_kws argument,

ax = sns.distplot(x, hist_kws=dict(edgecolor="k", linewidth=2))

For matplotlib plots, you can directly use the edgecolor or ec argument.

plt.bar(x,y, edgecolor="k")
plt.hist(x, edgecolor="k")

Equally, for pandas plots,

df.plot(kind='hist',edgecolor="k")

A complete seaborn example:

import  numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

x = np.random.randn(100)
ax = sns.distplot(x, hist_kws=dict(edgecolor="k", linewidth=2))
plt.show()

ContentLicense: CC BY-SA 4.0


问:
AttributeError: cannot assign module before Module.__init__() call
I am getting the following error.

```<code>Traceback (most recent call last):
  File "main.py", line 63, in <module>
    question_classifier = QuestionClassifier(corpus.dictionary, embeddings_index, corpus.max_sent_length, args)
  File "/net/if5/wua4nw/wasi/academic/research_with_prof_chang/projects/question_answering/duplicate_question_detection/source/question_classifier.py", line 26, in __init__
    self.embedding = EmbeddingLayer(len(dictionary), args.emsize, args.dropout)
  File "/if5/wua4nw/anaconda3/lib/python3.5/site-packages/torch/nn/modules/module.py", line 255, in __setattr__
    "cannot assign module before Module.__init__() call")
AttributeError: cannot assign module before Module.__init__() call
</code>```

I have a class as follows.

```<code>class QuestionClassifier(nn.Module):

     def __init__(self, dictionary, embeddings_index, max_seq_length, args):
         self.embedding = EmbeddingLayer(len(dictionary), args.emsize, args.dropout)
         self.encoder = EncoderRNN(args.emsize, args.nhid, args.model, args.bidirection, args.nlayers, args.dropout)
         self.drop = nn.Dropout(args.dropout)
</code>```

So, when I run the following line:

```<code>question_classifier = QuestionClassifier(corpus.dictionary, embeddings_index, corpus.max_sent_length, args)
</code>```

I get the above mentioned error. Here, EmbeddingLayer and EncoderRNN is a class written by me which inherits nn.module like the QuestionClassifier class.

What I am doing wrong here?

答:
Looking at the pytorch source code for Module, we see in the docstring an example of deriving from Module includes:

```<code> class Model(nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            self.conv1 = nn.Conv2d(1, 20, 5)
            self.conv2 = nn.Conv2d(20, 20, 5)
</code>```

So you probably want to call Module's init the same way in your derived class:

```<code>super(QuestionClassifier, self).__init__()
</code>```

Body:
I am getting the following error.

Traceback (most recent call last):
  File "main.py", line 63, in <module>
    question_classifier = QuestionClassifier(corpus.dictionary, embeddings_index, corpus.max_sent_length, args)
  File "/net/if5/wua4nw/wasi/academic/research_with_prof_chang/projects/question_answering/duplicate_question_detection/source/question_classifier.py", line 26, in __init__
    self.embedding = EmbeddingLayer(len(dictionary), args.emsize, args.dropout)
  File "/if5/wua4nw/anaconda3/lib/python3.5/site-packages/torch/nn/modules/module.py", line 255, in __setattr__
    "cannot assign module before Module.__init__() call")
AttributeError: cannot assign module before Module.__init__() call

I have a class as follows.

class QuestionClassifier(nn.Module):

     def __init__(self, dictionary, embeddings_index, max_seq_length, args):
         self.embedding = EmbeddingLayer(len(dictionary), args.emsize, args.dropout)
         self.encoder = EncoderRNN(args.emsize, args.nhid, args.model, args.bidirection, args.nlayers, args.dropout)
         self.drop = nn.Dropout(args.dropout)

So, when I run the following line:

question_classifier = QuestionClassifier(corpus.dictionary, embeddings_index, corpus.max_sent_length, args)

I get the above mentioned error. Here, EmbeddingLayer and EncoderRNN is a class written by me which inherits nn.module like the QuestionClassifier class.

What I am doing wrong here?

Body:
Looking at the pytorch source code for Module, we see in the docstring an example of deriving from Module includes:

 class Model(nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            self.conv1 = nn.Conv2d(1, 20, 5)
            self.conv2 = nn.Conv2d(20, 20, 5)

So you probably want to call Module's init the same way in your derived class:

super(QuestionClassifier, self).__init__()


问:
precision and recall in lucene
hello all
I was wondering, if I want to measure precision and recall in lucene then what's the best way for me to do it? is there any sample cource code that I can use?

a little background, I am using lucene to create a kind of search engine for my thesis. and I also wanted to do an analysis of how well those search engine performs and the only way to do that I think is for me to compute the precision and recall metrics. so any suggestion would be helpful.

thanks though

答:
You can try these email threads. Alternatively, you can use MRR.
See also Search Application Relevance Issues.</p>

ContentLicense: CC BY-SA 2.5

Title: precision and recall in lucene


问:
Android Program Hangs After Click
I'm writing an android app that quizzes me on drink recipes through multiple choice. After a choice is pressed, the app colors the correct answer and produces a new question. After some number of rounds however, it hangs and I can't find why. I posted the code and layout below.

```<code>package com.example.frances.rocksdrinks;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class Menu extends AppCompatActivity {
String[] allDrinks = {"BOURBON ON THE ROCKS", "SCOTCH ON THE ROCKS", "TOP SHELF SCOTCH ON THE ROCKS", "BLACK RUSSIAN", "SICILIAN KISS",
        "GOD MOTHER", "GOD FATHER", "RUSTY NAIL", "NUTTY IRISHMAN", "STINGER", "KAMIKAZE", "PURPLE HOOTER", "WINDEX",
        "RASPBERRY KAMIKAZE", "MUDSLIDE", "AFTER FIVE", "B~51", "B~52", "B~53", "OATMEAL COOKIE"};

Map<String, String> liquor = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "1 1/2 oz Bourbon Whiskey");
    put("scotch on the rocks", "1 1/2 oz Scotch Whiskey");
    put("top shelf scotch on the rocks", "1 1/2 oz Scotch Whiskey");
    put("black russian", "1 1/4 oz Vodka & 3/4 oz Kahlua");
    put("sicilian kiss", "1 1/4 oz Southern Comfort & 3/4 oz Amaretto");
    put("god mother", "1 1/4 oz Vodka & 3/4 oz Amaretto");
    put("god father", "1 1/4 oz Scotch & 3/4 oz Amaretto");
    put("rusty nail", "1 1/4 oz Scotch & 3/4 oz Drambuie");
    put("Nutty Irishman", "1 1/4 oz Baileys & 3/4 oz Frangelico");
    put("stinger", "1 1/4 oz Brandy & 3/4 oz White Creme De Menthe");
    put("kamikaze", "1 1/4 oz Vodka & 3/4 oz Triple Sec");
    put("purple hooter", "1 1/4 oz Vodka & 3/4 oz Chambord");
    put("windex", "1 1/4 oz Vodka & 3/4 oz Blue Curacao");
    put("raspberry kamikaze", "1 1/4 oz Raspberry Vodka & 3/4 oz Triple Sec");
    put("mudslide", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Vodka");
    put("after five", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Peppermint Schnapps");
    put("b~51", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Frangelico");
    put("b~52", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Grand Marnier");
    put("b~53", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Amaretto");
    put("oatmeal cookie", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Goldschlager");
}};

Map<String, String> mixer = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "");
    put("scotch on the rocks", "");
    put("top shelf scotch on the rocks", "");
    put("black russian", "");
    put("sicilian kiss", "");
    put("god mother", "");
    put("god father", "");
    put("rusty nail", "");
    put("Nutty Irishman", "");
    put("stinger", "");
    put("kamikaze", "");
    put("purple hooter", "");
    put("windex", "");
    put("raspberry kamikaze", "");
    put("mudslide", "");
    put("after five", "");
    put("b~51", "");
    put("b~52", "");
    put("b~53", "");
    put("oatmeal cookie", "");
}};

Map<String, String> garnish = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "None");
    put("scotch on the rocks", "None");
    put("top shelf scotch on the rocks", "None");
    put("black russian", "None");
    put("sicilian kiss", "None");
    put("god mother", "None");
    put("god father", "None");
    put("rusty nail", "Lemon Twist");
    put("Nutty Irishman", "None");
    put("stinger", "Mint Leaf");
    put("kamikaze", "Splash Lime Juice");
    put("purple hooter", "Splash Lime Juice");
    put("windex", "Splash Lime Juice");
    put("raspberry kamikaze", "Splash Lime Juice");
    put("mudslide", "None");
    put("after five", "None");
    put("b~51", "None");
    put("b~52", "None");
    put("b~53", "None");
    put("oatmeal cookie", "None");
}};

Random r = new Random();

TextView choice1, choice2, choice3, choice4, answer, question;
String ans;
int qIndex;
String[] choices;
TextView correct;
Handler handler;

TextView pressed;

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

    choice1 = (TextView) findViewById(R.id.choice1);
    choice2 = (TextView) findViewById(R.id.choice2);
    choice3 = (TextView) findViewById(R.id.choice3);
    choice4 = (TextView) findViewById(R.id.choice4);

    answer = (TextView) findViewById(R.id.answer);
    question = (TextView) findViewById(R.id.question);

    handler = new Handler();

    createQuestion();
    createAnswers();

    question.setTextSize(21);
}

public void choice(View v)
{
    pressed = (TextView) findViewById(v.getId());
    answer.setVisibility(View.VISIBLE);

    if (pressed.getText().toString() == choices[0])
    {
        pressed.setTextColor(Color.parseColor("#00BF00"));
        answer.setText("CORRECT!");
        answer.setTextColor(Color.parseColor("#00BF00"));
    }
    else
    {
        pressed.setTextColor(Color.parseColor("#F60000"));
        answer.setText("WRONG!");
        answer.setTextColor(Color.parseColor("#F60000"));
        correct.setTextColor(Color.parseColor("#00BF00"));
    }

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            pressed.setTextColor(Color.parseColor("#777777"));
            correct.setTextColor(Color.parseColor("#777777"));
            answer.setVisibility(View.GONE);

            createQuestion();
            createAnswers();
        }
    }, 3000);

}

//if answer is a recipe, use 20sp as font size
private void createQuestion()
{
    String[] qs = {"Which drink contains ", "What garnish does drink contain", "What mixer does drink use",
            "Which of the following describes a drink"};

    int i = r.nextInt(allDrinks.length);
    ans = allDrinks[i];

    qIndex = r.nextInt(qs.length);
    String q = "";

    if (qIndex != 0)
    {
        q = qs[qIndex].replace("drink", ans);
    }
    else
    {
        q = qs[qIndex] + liquor.get(ans.toLowerCase());

        if (!mixer.get(ans.toLowerCase()).isEmpty())
        {
            q += " + " + mixer.get(ans.toLowerCase());;
        }

        if (!garnish.get(ans.toLowerCase()).equals("None"))
        {
            q += " + " + garnish.get(ans.toLowerCase());
        }
    }

    question.setText(q + "?");
}

private void createAnswers()
{
    choices = new String[4];
    int count = 1;
    String a = "";

    if (qIndex == 3)
    {
        choices[0] = liquor.get(ans.toLowerCase());
        if (!mixer.get(ans.toLowerCase()).isEmpty())
        {
            choices[0] += ", " + mixer.get(ans.toLowerCase());
        }

        if (!garnish.get(ans.toLowerCase()).equals("None"))
        {
            choices[0] += ", " + garnish.get(ans.toLowerCase());
        }

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (allDrinks[i] != ans)
            {
                a = liquor.get(allDrinks[i].toLowerCase());

                if (!mixer.get(ans.toLowerCase()).isEmpty())
                {
                    a += ", " + mixer.get(allDrinks[i].toLowerCase());
                }

                if (!garnish.get(allDrinks[i].toLowerCase()).equals("None"))
                {
                    a += ", " + garnish.get(allDrinks[i].toLowerCase());
                }

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }

            }
        }
    }
    else if (qIndex == 0)
    {
        choices[0] = ans;

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (allDrinks[i] != ans)
            {
                a = allDrinks[i];

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }

        }
    }
    else if (qIndex == 1)
    {
        String[] g = {"Splash Coke", "Splash Grenadine", "Splash Sprite", "None"};
        choices[0] = garnish.get(ans.toLowerCase());

        while (count != 4)
        {
            int i = r.nextInt(g.length);
            if (g[i] != choices[0])
            {
                a = g[i];

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }
        }
    }
    else
    {
        choices[0] = mixer.get(ans.toLowerCase());

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (mixer.get(allDrinks[i].toLowerCase()) != choices[0])
            {
                a = mixer.get(allDrinks[i].toLowerCase());
                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }
        }
    }

    TextView[] cs = {choice1, choice2, choice3, choice4};
    cs = shuffle(cs);
    correct = cs[0];

    for (int i = 0; i<4; i++)
    {
        if (qIndex == 3)
        {
            cs[i].setTextSize(12);
        }
        else
        {
            cs[i].setTextSize(18);
        }
        cs[i].setText(choices[i]);
    }
}

private TextView[] shuffle(TextView[] arr)
{
    int index;
    TextView temp;
    for (int i = arr.length - 1; i > 0; i--)
    {
        index = r.nextInt(i + 1);
        temp = arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
    }
    return arr;
}
</code>```

}

Here is the layout file

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/question"
    android:layout_width="wrap_content"
    android:layout_height="140sp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20sp"
    android:textSize="25sp"
    android:layout_marginLeft="20sp"
    android:layout_marginRight="20sp"
    android:gravity="center"
    android:textColor="@color/black"
    android:text="Which drink contains 1/2 oz Jagermeister1/2 oz Peach Schnapps + Cranberry Juice"/>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="300sp"
    android:layout_marginTop="30sp">

    <TextView
        android:id="@+id/choice1"
        android:layout_marginLeft="0sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice2"
        android:layout_marginLeft="180sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice3"
        android:layout_marginTop="130sp"
        android:layout_marginLeft="0sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice4"
        android:layout_marginTop="130sp"
        android:layout_marginLeft="180sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="1 oz vodka, 50/50 orange and cranberry, lime"
        android:textSize="23sp"
        android:onClick="choice"
        android:textColor="#777777"
        android:clickable="true"
        android:gravity="center"/>

</RelativeLayout>

<TextView
    android:layout_marginTop="-40sp"
    android:id="@+id/answer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:textSize="30sp"
    android:textColor="@color/green"
    android:textStyle="bold"/>

</LinearLayout>
</code>```

The logcat gives this output when it starts hanging

```<code>03-28 12:51:05.460 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 9.490ms
03-28 12:51:15.605 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 14222(509KB) AllocSpace objects, 0(0B) LOS objects, 24% free, 1825KB/2MB, paused 5.062ms total 11.585ms
03-28 12:51:23.159 29897-29913/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 10.660ms for cause Background
03-28 12:52:48.768 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.314ms
03-28 12:52:58.857 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 30454(1094KB) AllocSpace objects, 0(0B) LOS objects, 38% free, 1708KB/2MB, paused 5.259ms total 13.447ms
03-28 12:54:07.970 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.891ms
03-28 12:54:24.523 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.254ms
03-28 12:54:45.569 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.900ms
03-28 12:54:49.078 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 8.536ms
03-28 12:54:57.595 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.742ms
03-28 12:55:30.525 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.450ms for cause HeapTrim
03-28 12:55:34.194 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.670ms
03-28 12:55:56.904 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.412ms
03-28 12:56:09.293 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.397ms
03-28 12:56:37.481 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 29570(1064KB) AllocSpace objects, 0(0B) LOS objects, 38% free, 1688KB/2MB, paused 10.745ms total 18.296ms
03-28 12:56:42.810 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.896ms
03-28 12:57:03.446 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 8.611ms
03-28 12:57:10.750 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 9.071ms for cause HeapTrim
03-28 12:57:38.029 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.944ms
03-28 12:57:45.548 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.624ms
03-28 12:58:00.093 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.481ms
03-28 12:58:10.900 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.327ms for cause HeapTrim
03-28 12:59:42.489 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 7.841ms
03-28 13:00:01.148 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 6.726ms for cause HeapTrim
03-28 13:00:18.072 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 26985(971KB) AllocSpace objects, 0(0B) LOS objects, 35% free, 1757KB/2MB, paused 6.471ms total 14.159ms
03-28 13:00:21.155 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.892ms for cause HeapTrim
03-28 13:00:41.162 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 5.154ms for cause HeapTrim
03-28 13:02:48.702 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.836ms
03-28 13:02:53.694 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.996ms
</code>```

I haven't been able to find out what's wrong from my code. This is currently the only activity in the app. Thank you.

UPDATE:
I found that if I remove the createAnswers function, it stops hanging but I haven't figured out why it causes the hang.

SOLVED:
Turns out since rocks drinks don't have a mixer (all entries in the mixer hashmap is an empty string), it affects the else statement in createAnswers where I create answers for the mixer question. I don't know why it created memory leaks though but I removed it and now it works fine.

答: You should check the while loop inside the createAnswers function , does it ends every time at acceptable time or takes a long time because count++ is inside a condition that may not be fulfilled </p>

Title: Android Program Hangs After Click

Body:
I'm writing an android app that quizzes me on drink recipes through multiple choice. After a choice is pressed, the app colors the correct answer and produces a new question. After some number of rounds however, it hangs and I can't find why. I posted the code and layout below.

package com.example.frances.rocksdrinks;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class Menu extends AppCompatActivity {
String[] allDrinks = {"BOURBON ON THE ROCKS", "SCOTCH ON THE ROCKS", "TOP SHELF SCOTCH ON THE ROCKS", "BLACK RUSSIAN", "SICILIAN KISS",
        "GOD MOTHER", "GOD FATHER", "RUSTY NAIL", "NUTTY IRISHMAN", "STINGER", "KAMIKAZE", "PURPLE HOOTER", "WINDEX",
        "RASPBERRY KAMIKAZE", "MUDSLIDE", "AFTER FIVE", "B~51", "B~52", "B~53", "OATMEAL COOKIE"};

Map<String, String> liquor = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "1 1/2 oz Bourbon Whiskey");
    put("scotch on the rocks", "1 1/2 oz Scotch Whiskey");
    put("top shelf scotch on the rocks", "1 1/2 oz Scotch Whiskey");
    put("black russian", "1 1/4 oz Vodka & 3/4 oz Kahlua");
    put("sicilian kiss", "1 1/4 oz Southern Comfort & 3/4 oz Amaretto");
    put("god mother", "1 1/4 oz Vodka & 3/4 oz Amaretto");
    put("god father", "1 1/4 oz Scotch & 3/4 oz Amaretto");
    put("rusty nail", "1 1/4 oz Scotch & 3/4 oz Drambuie");
    put("Nutty Irishman", "1 1/4 oz Baileys & 3/4 oz Frangelico");
    put("stinger", "1 1/4 oz Brandy & 3/4 oz White Creme De Menthe");
    put("kamikaze", "1 1/4 oz Vodka & 3/4 oz Triple Sec");
    put("purple hooter", "1 1/4 oz Vodka & 3/4 oz Chambord");
    put("windex", "1 1/4 oz Vodka & 3/4 oz Blue Curacao");
    put("raspberry kamikaze", "1 1/4 oz Raspberry Vodka & 3/4 oz Triple Sec");
    put("mudslide", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Vodka");
    put("after five", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Peppermint Schnapps");
    put("b~51", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Frangelico");
    put("b~52", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Grand Marnier");
    put("b~53", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Amaretto");
    put("oatmeal cookie", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Goldschlager");
}};

Map<String, String> mixer = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "");
    put("scotch on the rocks", "");
    put("top shelf scotch on the rocks", "");
    put("black russian", "");
    put("sicilian kiss", "");
    put("god mother", "");
    put("god father", "");
    put("rusty nail", "");
    put("Nutty Irishman", "");
    put("stinger", "");
    put("kamikaze", "");
    put("purple hooter", "");
    put("windex", "");
    put("raspberry kamikaze", "");
    put("mudslide", "");
    put("after five", "");
    put("b~51", "");
    put("b~52", "");
    put("b~53", "");
    put("oatmeal cookie", "");
}};

Map<String, String> garnish = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "None");
    put("scotch on the rocks", "None");
    put("top shelf scotch on the rocks", "None");
    put("black russian", "None");
    put("sicilian kiss", "None");
    put("god mother", "None");
    put("god father", "None");
    put("rusty nail", "Lemon Twist");
    put("Nutty Irishman", "None");
    put("stinger", "Mint Leaf");
    put("kamikaze", "Splash Lime Juice");
    put("purple hooter", "Splash Lime Juice");
    put("windex", "Splash Lime Juice");
    put("raspberry kamikaze", "Splash Lime Juice");
    put("mudslide", "None");
    put("after five", "None");
    put("b~51", "None");
    put("b~52", "None");
    put("b~53", "None");
    put("oatmeal cookie", "None");
}};

Random r = new Random();

TextView choice1, choice2, choice3, choice4, answer, question;
String ans;
int qIndex;
String[] choices;
TextView correct;
Handler handler;

TextView pressed;

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

    choice1 = (TextView) findViewById(R.id.choice1);
    choice2 = (TextView) findViewById(R.id.choice2);
    choice3 = (TextView) findViewById(R.id.choice3);
    choice4 = (TextView) findViewById(R.id.choice4);

    answer = (TextView) findViewById(R.id.answer);
    question = (TextView) findViewById(R.id.question);

    handler = new Handler();

    createQuestion();
    createAnswers();

    question.setTextSize(21);
}

public void choice(View v)
{
    pressed = (TextView) findViewById(v.getId());
    answer.setVisibility(View.VISIBLE);

    if (pressed.getText().toString() == choices[0])
    {
        pressed.setTextColor(Color.parseColor("#00BF00"));
        answer.setText("CORRECT!");
        answer.setTextColor(Color.parseColor("#00BF00"));
    }
    else
    {
        pressed.setTextColor(Color.parseColor("#F60000"));
        answer.setText("WRONG!");
        answer.setTextColor(Color.parseColor("#F60000"));
        correct.setTextColor(Color.parseColor("#00BF00"));
    }

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            pressed.setTextColor(Color.parseColor("#777777"));
            correct.setTextColor(Color.parseColor("#777777"));
            answer.setVisibility(View.GONE);

            createQuestion();
            createAnswers();
        }
    }, 3000);

}

//if answer is a recipe, use 20sp as font size
private void createQuestion()
{
    String[] qs = {"Which drink contains ", "What garnish does drink contain", "What mixer does drink use",
            "Which of the following describes a drink"};

    int i = r.nextInt(allDrinks.length);
    ans = allDrinks[i];

    qIndex = r.nextInt(qs.length);
    String q = "";

    if (qIndex != 0)
    {
        q = qs[qIndex].replace("drink", ans);
    }
    else
    {
        q = qs[qIndex] + liquor.get(ans.toLowerCase());

        if (!mixer.get(ans.toLowerCase()).isEmpty())
        {
            q += " + " + mixer.get(ans.toLowerCase());;
        }

        if (!garnish.get(ans.toLowerCase()).equals("None"))
        {
            q += " + " + garnish.get(ans.toLowerCase());
        }
    }

    question.setText(q + "?");
}

private void createAnswers()
{
    choices = new String[4];
    int count = 1;
    String a = "";

    if (qIndex == 3)
    {
        choices[0] = liquor.get(ans.toLowerCase());
        if (!mixer.get(ans.toLowerCase()).isEmpty())
        {
            choices[0] += ", " + mixer.get(ans.toLowerCase());
        }

        if (!garnish.get(ans.toLowerCase()).equals("None"))
        {
            choices[0] += ", " + garnish.get(ans.toLowerCase());
        }

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (allDrinks[i] != ans)
            {
                a = liquor.get(allDrinks[i].toLowerCase());

                if (!mixer.get(ans.toLowerCase()).isEmpty())
                {
                    a += ", " + mixer.get(allDrinks[i].toLowerCase());
                }

                if (!garnish.get(allDrinks[i].toLowerCase()).equals("None"))
                {
                    a += ", " + garnish.get(allDrinks[i].toLowerCase());
                }

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }

            }
        }
    }
    else if (qIndex == 0)
    {
        choices[0] = ans;

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (allDrinks[i] != ans)
            {
                a = allDrinks[i];

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }

        }
    }
    else if (qIndex == 1)
    {
        String[] g = {"Splash Coke", "Splash Grenadine", "Splash Sprite", "None"};
        choices[0] = garnish.get(ans.toLowerCase());

        while (count != 4)
        {
            int i = r.nextInt(g.length);
            if (g[i] != choices[0])
            {
                a = g[i];

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }
        }
    }
    else
    {
        choices[0] = mixer.get(ans.toLowerCase());

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (mixer.get(allDrinks[i].toLowerCase()) != choices[0])
            {
                a = mixer.get(allDrinks[i].toLowerCase());
                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }
        }
    }

    TextView[] cs = {choice1, choice2, choice3, choice4};
    cs = shuffle(cs);
    correct = cs[0];

    for (int i = 0; i<4; i++)
    {
        if (qIndex == 3)
        {
            cs[i].setTextSize(12);
        }
        else
        {
            cs[i].setTextSize(18);
        }
        cs[i].setText(choices[i]);
    }
}

private TextView[] shuffle(TextView[] arr)
{
    int index;
    TextView temp;
    for (int i = arr.length - 1; i > 0; i--)
    {
        index = r.nextInt(i + 1);
        temp = arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
    }
    return arr;
}

}

Here is the layout file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/question"
    android:layout_width="wrap_content"
    android:layout_height="140sp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20sp"
    android:textSize="25sp"
    android:layout_marginLeft="20sp"
    android:layout_marginRight="20sp"
    android:gravity="center"
    android:textColor="@color/black"
    android:text="Which drink contains 1/2 oz Jagermeister1/2 oz Peach Schnapps + Cranberry Juice"/>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="300sp"
    android:layout_marginTop="30sp">

    <TextView
        android:id="@+id/choice1"
        android:layout_marginLeft="0sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice2"
        android:layout_marginLeft="180sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice3"
        android:layout_marginTop="130sp"
        android:layout_marginLeft="0sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice4"
        android:layout_marginTop="130sp"
        android:layout_marginLeft="180sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="1 oz vodka, 50/50 orange and cranberry, lime"
        android:textSize="23sp"
        android:onClick="choice"
        android:textColor="#777777"
        android:clickable="true"
        android:gravity="center"/>

</RelativeLayout>

<TextView
    android:layout_marginTop="-40sp"
    android:id="@+id/answer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:textSize="30sp"
    android:textColor="@color/green"
    android:textStyle="bold"/>

</LinearLayout>

The logcat gives this output when it starts hanging

03-28 12:51:05.460 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 9.490ms
03-28 12:51:15.605 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 14222(509KB) AllocSpace objects, 0(0B) LOS objects, 24% free, 1825KB/2MB, paused 5.062ms total 11.585ms
03-28 12:51:23.159 29897-29913/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 10.660ms for cause Background
03-28 12:52:48.768 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.314ms
03-28 12:52:58.857 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 30454(1094KB) AllocSpace objects, 0(0B) LOS objects, 38% free, 1708KB/2MB, paused 5.259ms total 13.447ms
03-28 12:54:07.970 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.891ms
03-28 12:54:24.523 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.254ms
03-28 12:54:45.569 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.900ms
03-28 12:54:49.078 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 8.536ms
03-28 12:54:57.595 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.742ms
03-28 12:55:30.525 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.450ms for cause HeapTrim
03-28 12:55:34.194 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.670ms
03-28 12:55:56.904 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.412ms
03-28 12:56:09.293 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.397ms
03-28 12:56:37.481 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 29570(1064KB) AllocSpace objects, 0(0B) LOS objects, 38% free, 1688KB/2MB, paused 10.745ms total 18.296ms
03-28 12:56:42.810 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.896ms
03-28 12:57:03.446 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 8.611ms
03-28 12:57:10.750 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 9.071ms for cause HeapTrim
03-28 12:57:38.029 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.944ms
03-28 12:57:45.548 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.624ms
03-28 12:58:00.093 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.481ms
03-28 12:58:10.900 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.327ms for cause HeapTrim
03-28 12:59:42.489 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 7.841ms
03-28 13:00:01.148 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 6.726ms for cause HeapTrim
03-28 13:00:18.072 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 26985(971KB) AllocSpace objects, 0(0B) LOS objects, 35% free, 1757KB/2MB, paused 6.471ms total 14.159ms
03-28 13:00:21.155 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.892ms for cause HeapTrim
03-28 13:00:41.162 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 5.154ms for cause HeapTrim
03-28 13:02:48.702 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.836ms
03-28 13:02:53.694 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.996ms

I haven't been able to find out what's wrong from my code. This is currently the only activity in the app. Thank you.

UPDATE:
I found that if I remove the createAnswers function, it stops hanging but I haven't figured out why it causes the hang.

SOLVED:
Turns out since rocks drinks don't have a mixer (all entries in the mixer hashmap is an empty string), it affects the else statement in createAnswers where I create answers for the mixer question. I don't know why it created memory leaks though but I removed it and now it works fine.


问:
Excel Return Date before another date by another column name
I have two sheets of data with the following.

I want return the date from sheet 2 on sheet 1 with the start date BEFORE the remove date.  For example.  For Customer A, the remove date is 12/29/2016.  I would want to return the date of 12/20/2014 from sheet 2 as it is the next previous date from the remove date of 12/29/2016 from sheet 1 and is removed prior to the third date of 1/20/2017.  Similarly for Customer B, the date returned would be 11/9/2013.

Vlookup will not work as there are more than one unique value for customer and I had no luck with index and match.  Is there any other possible solution?

Here is an edit.  The Sumproduct and aggregate method for the start date works great.  The issue is I need the last date to be the first record after the replacement date.  So in this case, it would be 2/1/16.  Using the Min or Max sumproduct and aggregate method, I get either 0 or the max date of 3/22/17, which is not what I want.

答:
For those that don't have the latest version of excel and can't use maxifs, we can do an array formula: take the max date that is less than the date corresponding to A

```<code>=SUMPRODUCT(MAX((A9:A14=A3)*(IF((B9:B14)<B3,B9:B14))))
</code>```

entered as array formulae (Ctrl+Shift+Enter)

Body:
For those that don't have the latest version of excel and can't use maxifs, we can do an array formula: take the max date that is less than the date corresponding to A

=SUMPRODUCT(MAX((A9:A14=A3)*(IF((B9:B14)<B3,B9:B14))))

entered as array formulae (Ctrl+Shift+Enter)


问:
Rails app - extra record displaying
I have an app that allows users to add albums they like to a database. Anyone can then come along and write a review for that album. Pretty simple.

I am running into a problem where an extra record appears to be created for the reviews on each album's show page. Every album, even if it has not ever been reviewed, has an additional, seemingly empty review being displayed when I use .each to display each review in the album show page. I want to get rid of that.

Here is an image of the problem. I have used CSS to highlight reviews in red. As you can see, there is an empty review at the bottom. When I inspect the review in question, it's raty title is "Not reviewed yet!"

Here is my albums_controller:

```<code>class AlbumsController < ApplicationController
  before_action :set_album, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, only: [:edit, :new, :update, :destroy]

  def index
    @albums = Album.all
    if params[:search].nil?
      @albums = Album.all.order(year: :desc).order(title: :asc).paginate(:page => params[:page], :per_page => 24)
    else
      @albums = @albums.where("albums.title || albums.year || albums.artist LIKE ?", "%#{params[:search]}%").order(year: :desc).order(title: :asc).paginate(:page => params[:page], :per_page => 24)
    end
  end

  def show
     if @album.reviews.blank?
      @average_review = 0
     else
      @average_review = @album.reviews.average(:rating).round(2)
     end
     @review = @album.reviews.build
   end

   def new
     @album = Album.new
   end

   def edit

   end

   def create
     @album = current_user.albums.build(album_params)

     respond_to do |format|
      if @album.save
         format.html { redirect_to @album, notice: 'Album was successfully created.' }
        format.json { render :show, status: :created, location: @album }
      else
        format.html { render :new }
        format.json { render json: @album.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
     respond_to do |format|
      if @album.update(album_params)
        format.html { redirect_to @album, notice: 'Album was successfully updated.' }
        format.json { render :show, status: :ok, location: @album }
      else
        format.html { render :edit }
        format.json { render json: @album.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @album.destroy
    respond_to do |format|
      format.html { redirect_to albums_url, notice: 'Album was successfully    destroyed.' }
      format.json { head :no_content }
    end
  end

private
# Use callbacks to share common setup or constraints between actions.

def set_album
  @album = Album.find(params[:id])
end

def album_params
  params.require(:album).permit(:title, :artist, :year, :cover)
end
end
</code>```

Here is the album show page, which is where the extra review is being displayed:

```<code><div class="row">
<div class="col-xs-10 col-md-6 col-md-push-3 col-xs-push-1 top bottom">
    <%= image_tag @album.cover, class: 'show_image' %>
    <h2><%= @album.title %></h2>
    <h4><%= @album.artist %></h4>
    <h5><%= @album.year %></h5>
    <p class="white">Average Review<div class="average-review-rating" data-score=<%= @average_review %>></div></p>
    <% if user_signed_in? %>
        <% if @album.user_id == current_user.id %>
            <%= link_to 'Edit', edit_album_path(@album), class: 'grey' %>
            | <%= link_to 'Delete', album_path, method: :delete, data: {confirm: "Are you sure?"}, class: 'grey' %>
        <% end %>
    <% end %>
    <br /><br />
    <h4>Reviews</h4>
    <% if user_signed_in? %>
        <p class="grey">Write a review</p>

        <%= form_for [@album, @review] do |r| %>
            <div class="form-group">
                <div id="rating-form">
                    <label>Rating</label>
                </div>
            </div>
            <div class="form-group">
                <%= r.text_area :comment, class: 'form-control', placeholder: "Write a comment" %>
            </div>
            <div class="form-group">
                <%= r.submit "Create", class: 'btn btn-success' %>
            </div>
        <% end %>
    <% end %>

    <br />
    <% @album.reviews.each do |r| %>
        <div class="red">
            <div class="review-rating" data-number="<%= r.rating %>">
            </div>
            <p class="white"><%= r.comment %></p>
            <% if user_signed_in? %>
                <% if current_user.id == r.user_id %>
                    <%= link_to 'Edit', edit_album_review_path(@album, r.id), class: 'grey' %> |
                    <%= link_to 'Delete', album_review_path(@album, r.id), method: :delete, data: {confirm: "Are you sure?"}, class: 'grey' %>
                <% end %>
            <% end %>
            <br /><br />
        </div>
    <% end %>
</div>
</div>

<script>
$('.review-rating').raty({
readOnly: true,
score: function() {
    return $(this).attr('data-number');
},
path: '/assets/'
});

$('#rating-form').raty({
path: '/assets/',
scoreName: 'review[rating]'
});

$('.average-review-rating').raty({
readOnly: true,
path: '/assets/',
score: function() {
    return $(this).attr('data-score')
}
});
</script>
</code>```

Any help would be very appreciated!

答:
The problem here is on the last line of your show method: @review = @album.reviews.build. This line not only creates a new Review instance and assigns it to @review, but it also adds that instance to the array in @album.reviews. So, in your view, when you iterate over @album.reviews, you will see all of the persisted reviews as well as the one new, not persisted review that was built with build.

The easiest way to fix this would be to add this line in your view:

```<code><% @album.reviews.each do |r| %>
  <% next unless r.persisted? %>
</code>```

Another solution would be to associate the new review with the album, but not on the @album instance. In the controller:

```<code>@review = Review.new(album: @album)
</code>```

Title: Rails app - extra record displaying

Body:
I have an app that allows users to add albums they like to a database. Anyone can then come along and write a review for that album. Pretty simple.

I am running into a problem where an extra record appears to be created for the reviews on each album's show page. Every album, even if it has not ever been reviewed, has an additional, seemingly empty review being displayed when I use .each to display each review in the album show page. I want to get rid of that.

Here is an image of the problem. I have used CSS to highlight reviews in red. As you can see, there is an empty review at the bottom. When I inspect the review in question, it's raty title is "Not reviewed yet!"

Here is my albums_controller:

class AlbumsController < ApplicationController
  before_action :set_album, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, only: [:edit, :new, :update, :destroy]

  def index
    @albums = Album.all
    if params[:search].nil?
      @albums = Album.all.order(year: :desc).order(title: :asc).paginate(:page => params[:page], :per_page => 24)
    else
      @albums = @albums.where("albums.title || albums.year || albums.artist LIKE ?", "%#{params[:search]}%").order(year: :desc).order(title: :asc).paginate(:page => params[:page], :per_page => 24)
    end
  end

  def show
     if @album.reviews.blank?
      @average_review = 0
     else
      @average_review = @album.reviews.average(:rating).round(2)
     end
     @review = @album.reviews.build
   end

   def new
     @album = Album.new
   end

   def edit

   end

   def create
     @album = current_user.albums.build(album_params)

     respond_to do |format|
      if @album.save
         format.html { redirect_to @album, notice: 'Album was successfully created.' }
        format.json { render :show, status: :created, location: @album }
      else
        format.html { render :new }
        format.json { render json: @album.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
     respond_to do |format|
      if @album.update(album_params)
        format.html { redirect_to @album, notice: 'Album was successfully updated.' }
        format.json { render :show, status: :ok, location: @album }
      else
        format.html { render :edit }
        format.json { render json: @album.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @album.destroy
    respond_to do |format|
      format.html { redirect_to albums_url, notice: 'Album was successfully    destroyed.' }
      format.json { head :no_content }
    end
  end

private
# Use callbacks to share common setup or constraints between actions.

def set_album
  @album = Album.find(params[:id])
end

def album_params
  params.require(:album).permit(:title, :artist, :year, :cover)
end
end

Here is the album show page, which is where the extra review is being displayed:

    <%= image_tag @album.cover, class: 'show_image' %>

<%= @album.title %>

<%= @album.artist %>

<%= @album.year %>

Average Review<div class="average-review-rating" data-score=<%= @average_review %>>

    <% if user_signed_in? %>
        <% if @album.user_id == current_user.id %>
            <%= link_to 'Edit', edit_album_path(@album), class: 'grey' %>
            | <%= link_to 'Delete', album_path, method: :delete, data: {confirm: "Are you sure?"}, class: 'grey' %>
        <% end %>
    <% end %>

Reviews

    <% if user_signed_in? %>

Write a review

        <%= form_for [@album, @review] do |r| %>

                    Rating

                <%= r.text_area :comment, class: 'form-control', placeholder: "Write a comment" %>

                <%= r.submit "Create", class: 'btn btn-success' %>

        <% end %>
    <% end %>

    <% @album.reviews.each do |r| %>

            <div class="review-rating" data-number="<%= r.rating %>">

<%= r.comment %>

            <% if user_signed_in? %>
                <% if current_user.id == r.user_id %>
                    <%= link_to 'Edit', edit_album_review_path(@album, r.id), class: 'grey' %> |
                    <%= link_to 'Delete', album_review_path(@album, r.id), method: :delete, data: {confirm: "Are you sure?"}, class: 'grey' %>
                <% end %>
            <% end %>

    <% end %>

Any help would be very appreciated!

Body:
The problem here is on the last line of your show method: @review = @album.reviews.build. This line not only creates a new Review instance and assigns it to @review, but it also adds that instance to the array in @album.reviews. So, in your view, when you iterate over @album.reviews, you will see all of the persisted reviews as well as the one new, not persisted review that was built with build.

The easiest way to fix this would be to add this line in your view:

<% @album.reviews.each do |r| %>
  <% next unless r.persisted? %>

Another solution would be to associate the new review with the album, but not on the @album instance. In the controller:

@review = Review.new(album: @album)


问:
Change bracket highlight weight in VS Code to be more visible
I'm just getting VS Code set up to use, one of the things I like to have is highlighting that's visible so I don't have to really look for it. I have the editor.matchBrackets setting set to true, so my brackets are highlighted when one is selected. However, the highlighting is so faint (very thin lines) that it's hard to see (I'm using the Dark+ theme, one of the default themes). Is there a way to affect the bracket highlighting, such as the color, line size, etc, so that it's easy to see?

Thanks.

答:
Unfortunately, you can't do that.

You should look for another Theme that fit your needs, or maybe upvote this issue in VS Code repo which seems similar to your needs. This issue also suggest install an extension that colorize brackets. It's not a solution, but might help.


问:
Why is this flowdocument table always printing 2 columns
I have a ListView in my WPF app that is bound to a collection of tasks to perform (A to-do list). I want the user to be able to print their list and have created the following code based on the MSDN guidelines. (This my first foray into printing)

```<code>public FlowDocument GetPrintDocument()
{
    FlowDocument flowDoc = new FlowDocument();
    Table table = new Table();

    int numColumns = 3;

    flowDoc.Blocks.Add(table);

    for(int x=0;x<numColumns;x++)
    {
        table.Columns.Add(new TableColumn());
    }
    GridLengthConverter glc = new GridLengthConverter();
    table.Columns[0].Width = (GridLength)glc.ConvertFromString("300");
    table.Columns[1].Width = (GridLength)glc.ConvertFromString("50");
    table.Columns[2].Width = (GridLength)glc.ConvertFromString("50");

    table.RowGroups.Add(new TableRowGroup());

    table.RowGroups[0].Rows.Add(new TableRow());
    // store current working row for reference
    TableRow currentRow = table.RowGroups[0].Rows[0];

    currentRow.FontSize = 16;
    currentRow.FontWeight = FontWeights.Bold;

    currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Subject"))));
    currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Due Date"))));
    currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Urgency"))));

    for (int i = 1; i < issues.Count+1; i++)
    {
        table.RowGroups[0].Rows.Add(new TableRow());
        currentRow = table.RowGroups[0].Rows[i];
        currentRow.FontSize = 12;
        currentRow.FontWeight = FontWeights.Normal;

        currentRow.Cells.Add(new TableCell
                            (new Paragraph
                            (new Run
                            (issues[i - 1].IssSubject))));
        currentRow.Cells.Add(new TableCell
                            (new Paragraph
                            (new Run
                            (issues[i - 1].IssDueDate.Date.ToString()))));
        currentRow.Cells.Add(new TableCell
                            (new Paragraph
                            (new Run
                            (issues[i - 1].IssUrgency.ToString()))));
    }
    return flowDoc;
}
</code>```

When I try to print with the following code I always have my page split down the middle with 2 columns (Each containing the 3 columns of the table). I have tried different GridLength values but had no success.

```<code>printDialog.PrintDocument(((IDocumentPaginatorSource)StatusBoardViewModel
               .GetPrintDocument())
               .DocumentPaginator
            ,"Flow Document Print Job");
</code>```

答:
Thanks for the info. I fixed it by just setting the columnwidth like:

```<code>flowDoc.ColumnWidth = pageSize.Width
</code>```

FYI don't ever try to get help from netframeworkdev or .Net Framework Develop b/c they never have good answers. I wish my search engine would have pointed me at StackOverflow instead of that worthless site. StackOverflow always has the answers. :) Thanks again.

(Wish you could just block sites from ever showing in your search results, you know how to do that please tell me.)

Body:
I have a ListView in my WPF app that is bound to a collection of tasks to perform (A to-do list). I want the user to be able to print their list and have created the following code based on the MSDN guidelines. (This my first foray into printing)

public FlowDocument GetPrintDocument()
{
    FlowDocument flowDoc = new FlowDocument();
    Table table = new Table();

    int numColumns = 3;

    flowDoc.Blocks.Add(table);

    for(int x=0;x<numColumns;x++)
    {
        table.Columns.Add(new TableColumn());
    }
    GridLengthConverter glc = new GridLengthConverter();
    table.Columns[0].Width = (GridLength)glc.ConvertFromString("300");
    table.Columns[1].Width = (GridLength)glc.ConvertFromString("50");
    table.Columns[2].Width = (GridLength)glc.ConvertFromString("50");

    table.RowGroups.Add(new TableRowGroup());

    table.RowGroups[0].Rows.Add(new TableRow());
    // store current working row for reference
    TableRow currentRow = table.RowGroups[0].Rows[0];

    currentRow.FontSize = 16;
    currentRow.FontWeight = FontWeights.Bold;

    currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Subject"))));
    currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Due Date"))));
    currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Urgency"))));

    for (int i = 1; i < issues.Count+1; i++)
    {
        table.RowGroups[0].Rows.Add(new TableRow());
        currentRow = table.RowGroups[0].Rows[i];
        currentRow.FontSize = 12;
        currentRow.FontWeight = FontWeights.Normal;

        currentRow.Cells.Add(new TableCell
                            (new Paragraph
                            (new Run
                            (issues[i - 1].IssSubject))));
        currentRow.Cells.Add(new TableCell
                            (new Paragraph
                            (new Run
                            (issues[i - 1].IssDueDate.Date.ToString()))));
        currentRow.Cells.Add(new TableCell
                            (new Paragraph
                            (new Run
                            (issues[i - 1].IssUrgency.ToString()))));
    }
    return flowDoc;
}

When I try to print with the following code I always have my page split down the middle with 2 columns (Each containing the 3 columns of the table). I have tried different GridLength values but had no success.

printDialog.PrintDocument(((IDocumentPaginatorSource)StatusBoardViewModel
               .GetPrintDocument())
               .DocumentPaginator
            ,"Flow Document Print Job");

Body:
Thanks for the info. I fixed it by just setting the columnwidth like:

flowDoc.ColumnWidth = pageSize.Width

FYI don't ever try to get help from netframeworkdev or .Net Framework Develop b/c they never have good answers. I wish my search engine would have pointed me at StackOverflow instead of that worthless site. StackOverflow always has the answers. :) Thanks again.

(Wish you could just block sites from ever showing in your search results, you know how to do that please tell me.)


问:
VueTwo Way Data Binding with Nested Components
Suppose I want to display a List of Questions.  For each question, there is a list of answers, none of which are right or wrong.  For each question, the user can choose an answer.  I'm wondering how to create two-way binding on the selected answer.

The Vue:

```<code>new Vue(
{
    el: "#app",

    data:
    {
        questions: [{}]
    }
}
</code>```

Example Question Model:

```<code>{
    id: 1,
    name: "Which color is your favorite?",
    selectedAnswerId: null,
    selectedAnswerName: null,
    answers:
    [
        {id: 1, name: red, photoUrl: ".../red", selected: false},
        {id: 2, name: green, photoUrl: ".../green", selected: false},
        {id: 3, name: blue, photoUrl: ".../blue", selected: false},
    ]
}
</code>```

Components:

```<code>var myAnswer =
{
    props: ["id", "name", "url", "selected"],
    template:
    `
        <div class="answer" v-bind:class="{selected: selected}">
            <img class="answer-photo" v-bind:src="url">
            <div class="answer-name">{{name}}</div>
        </div>
    `
};

Vue.component("my-question",
{
    props: ["id", "name", "answers"],
    components:
    {
        "my-answer": myAnswer
    },
    template:
    `
        <div class ="question">
            <div class="question-name">{{name}}</div>
            <div class="question-answers">
                <my-answer v-for="answer in answers" v-bind:id="answer.id" v-bind:name="answer.name" v-bind:url="answer.photoUrl" v-bind:selected="answer.selected"></my-answer>
            </div>
        </div>
    `
});
</code>```

When the user selects an answer to a question by clicking on the div, I want the Question model's selectedAnswerId/selectedAnswerName along with the answers selected property to be set accordingly.  Therefore, what do I need to add to my components in order to accomplish this two-way binding?  I believe it requires input elements and v-model, but I couldn't quite figure it out.  Also, I am only one day into Vue.js and have no experience with related frameworks.  So if I am doing anything blatantly wrong or against best practice, that would be good to know as well.  Thanks in advance!

答:
The answer will handle a click event and emit a (custom) selected-answer event. The question will have its own data item to store the selected answer ID; the answer component's selected prop will be based on that. The question will handle the selected-answer event by setting its selectedId.

var myAnswer = {
  props: ["id", "name", "url", "selected"],
  template: `

{{name}}

    `,
  methods: {
    setSelection() {
      this.$emit('selected-answer', this.id);
    }
  }
};

Vue.component("my-question", {
  props: ["id", "name", "answers"],
  data() {
    return {
      selectedId: null
    };
  },
  components: {
    "my-answer": myAnswer
  },
  template: `

{{name}}

                <my-answer v-for="answer in answers"
                :id="answer.id" :name="answer.name" :url="answer.photoUrl"
                :selected="answer.id === selectedId" @selected-answer="selectAnswer"></my-answer>

    `,
  methods: {
    selectAnswer(answerId) {
      this.selectedId = answerId;
    }
  }
});

new Vue({
  el: '#app',
  data: {
    questions: [{
      id: 1,
      name: "Which color is your favorite?",
      answers: [{
          id: 1,
          name: 'red',
          photoUrl: ".../red"
        },
        {
          id: 2,
          name: 'green',
          photoUrl: ".../green"
        },
        {
          id: 3,
          name: 'blue',
          photoUrl: ".../blue"
        },
      ]
    }]
  }
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.answer {
  cursor: pointer;
}

.selected {
  background-color: #f0f0f0;
}</code>```

  <my-question v-for="q in questions" :name="q.name" :answers="q.answers"></my-question>

```

Body:
Suppose I want to display a List of Questions.  For each question, there is a list of answers, none of which are right or wrong.  For each question, the user can choose an answer.  I'm wondering how to create two-way binding on the selected answer.

The Vue:

new Vue(
{
    el: "#app",

    data:
    {
        questions: [{}]
    }
}

Example Question Model:

{
    id: 1,
    name: "Which color is your favorite?",
    selectedAnswerId: null,
    selectedAnswerName: null,
    answers:
    [
        {id: 1, name: red, photoUrl: ".../red", selected: false},
        {id: 2, name: green, photoUrl: ".../green", selected: false},
        {id: 3, name: blue, photoUrl: ".../blue", selected: false},
    ]
}

Components:

var myAnswer =
{
    props: ["id", "name", "url", "selected"],
    template:
    `

{{name}}

    `
};

Vue.component("my-question",
{
    props: ["id", "name", "answers"],
    components:
    {
        "my-answer": myAnswer
    },
    template:
    `

{{name}}

                <my-answer v-for="answer in answers" v-bind:id="answer.id" v-bind:name="answer.name" v-bind:url="answer.photoUrl" v-bind:selected="answer.selected"></my-answer>

    `
});

When the user selects an answer to a question by clicking on the div, I want the Question model's selectedAnswerId/selectedAnswerName along with the answers selected property to be set accordingly.  Therefore, what do I need to add to my components in order to accomplish this two-way binding?  I believe it requires input elements and v-model, but I couldn't quite figure it out.  Also, I am only one day into Vue.js and have no experience with related frameworks.  So if I am doing anything blatantly wrong or against best practice, that would be good to know as well.  Thanks in advance!

Body:
The answer will handle a click event and emit a (custom) selected-answer event. The question will have its own data item to store the selected answer ID; the answer component's selected prop will be based on that. The question will handle the selected-answer event by setting its selectedId.

var myAnswer = {
  props: ["id", "name", "url", "selected"],
  template: `
        <div class="answer" v-bind:class="{selected: selected}"
         @click="setSelection()"
        >
            <img class="answer-photo" :src="url">
            <div class="answer-name">{{name}}</div>
        </div>
    `,
  methods: {
    setSelection() {
      this.$emit('selected-answer', this.id);
    }
  }
};

Vue.component("my-question", {
  props: ["id", "name", "answers"],
  data() {
    return {
      selectedId: null
    };
  },
  components: {
    "my-answer": myAnswer
  },
  template: `
        <div class ="question">
            <div class="question-name">{{name}}</div>
            <div class="question-answers">
                <my-answer v-for="answer in answers"
                :id="answer.id" :name="answer.name" :url="answer.photoUrl"
                :selected="answer.id === selectedId" @selected-answer="selectAnswer"></my-answer>
            </div>
        </div>
    `,
  methods: {
    selectAnswer(answerId) {
      this.selectedId = answerId;
    }
  }
});

new Vue({
  el: '#app',
  data: {
    questions: [{
      id: 1,
      name: "Which color is your favorite?",
      answers: [{
          id: 1,
          name: 'red',
          photoUrl: ".../red"
        },
        {
          id: 2,
          name: 'green',
          photoUrl: ".../green"
        },
        {
          id: 3,
          name: 'blue',
          photoUrl: ".../blue"
        },
      ]
    }]
  }
});

.answer {
  cursor: pointer;
}

.selected {
  background-color: #f0f0f0;
}

<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<div id="app">
  <my-question v-for="q in questions" :name="q.name" :answers="q.answers"></my-question>
</div>


问:
Assistance with SqlConnection
I am working on trying to connect my project to a database, which I am fairly new when it comes to working with databases. When I run the program I get a server error stating that login failed for user. I am working on a sign up form that when filled out will populate the fields in the database after clicking create account.

This is my back end code:

```<code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;

public partial class SignUp : System.Web.UI.Page
{

    SqlConnection conn = new SqlConnection();

    protected void Page_Load(object sender, EventArgs e)
    {
        conn.ConnectionString = @"Data Source=184.168.47.13;Initial Catalog=portfoliobrown;User ID=crossfire19;Password=***********";
    //error occurs here    conn.Open();
    }

    public void ExecuteConnection()
    {

        SqlCommand Command = new SqlCommand("Insert into SignUp" + "(FirstName, LastName, Password, Email)values(@FirsName, @LastName, #Password, @Email)",conn);

        Command.Parameters.AddWithValue("@FirstName", FirstName.Text);
        Command.Parameters.AddWithValue("@LastName", LastName.Text);
        Command.Parameters.AddWithValue("@Password", Email.Text);
        Command.Parameters.AddWithValue("@Email", Password.Text);
        Command.ExecuteNonQuery();

        conn.Close();
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        ExecuteConnection();
    }
}
</code>```

I have a table in the database. FirstName, LastName, Password, Email, Etc
Also my password and user name for the database should be correct, as when I test the connection it works just fine

Thanks for any help I would appreciate it.

答:
Without any more detail, the only thing I have to go on is the phrase "login failed for user". So you need to consider what process the code is running as when it's trying to make this connection. Given that this appears to be a web-page, I would hazard a guess that it is being run by the IIS process (check which user that is). I can't tell whether the process will be able to "see" the IP address that you've given in the connection string; my guess would be that it can't. I'm guessing that you're using Microsoft SQL server, since you've used the tag.

There are a whole bunch of reasons why this error can occur: the process's ability to see the network (e.g. local services can't see the network), firewalls (blocking the port that SQL server uses), configuration of the SQL server to allow remote connections (I think it's 'off' by default), allow mixed-mode authentication (again, depending on the version, I think this is off by default), maybe the database name is wrong, maybe the user doesn't exist on the server, or doesn't have permission to that database, or maybe (for once) the error message is actually right and the password that has been given in the connection string isn't right. (This is not a complete list.)

If I'm right that this is running under IIS, I would suggest putting exactly the same code in a console application, to assist with the diagnosis. When you run the console app, it will be running as you, with your permissions to access the network, rather than the IIS user. If that doesn't work, then (if you can) run the console app on the same machine as the SQL server: if this works, then you know it is just a networking/connection/configuration issue.

As well as the concerns expressed above about SQL injection (thanks for addressing those), I would suggest that you also read up on things that are IDisposable, and how to use the "using" statement (not the one that appears with the namespaces at the top). Both the connection and the command are disposable, so are best used in a using block.

Hope this helps. If it doesn't, then you'll need to give more information.

Title: Assistance with SqlConnection

Body:
I am working on trying to connect my project to a database, which I am fairly new when it comes to working with databases. When I run the program I get a server error stating that login failed for user. I am working on a sign up form that when filled out will populate the fields in the database after clicking create account.

This is my back end code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;

public partial class SignUp : System.Web.UI.Page
{

    SqlConnection conn = new SqlConnection();

    protected void Page_Load(object sender, EventArgs e)
    {
        conn.ConnectionString = @"Data Source=184.168.47.13;Initial Catalog=portfoliobrown;User ID=crossfire19;Password=***********";
    //error occurs here    conn.Open();
    }

    public void ExecuteConnection()
    {

        SqlCommand Command = new SqlCommand("Insert into SignUp" + "(FirstName, LastName, Password, Email)values(@FirsName, @LastName, #Password, @Email)",conn);

        Command.Parameters.AddWithValue("@FirstName", FirstName.Text);
        Command.Parameters.AddWithValue("@LastName", LastName.Text);
        Command.Parameters.AddWithValue("@Password", Email.Text);
        Command.Parameters.AddWithValue("@Email", Password.Text);
        Command.ExecuteNonQuery();

        conn.Close();
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        ExecuteConnection();
    }
}

I have a table in the database. FirstName, LastName, Password, Email, Etc
Also my password and user name for the database should be correct, as when I test the connection it works just fine

Thanks for any help I would appreciate it.


问:
Dynamic created map triggering warning in angular
In angular I want to dynamically create a map based on the address entered. I have successfully done this in VueJS. But in angular this triggers security warnings.

HTML:

```<code><iframe
    ng-src="https://maps.google.com/maps?&q={{encodeURIComponent(item.address)}}&output=embed"
    allowfullscreen>
</iframe>
</code>```

I have tried creating the following:

```<code>app.filter('trustAsResourceUrl', ['$sce', function ($sce) {
    return function (val) {
        return $sce.trustAsResourceUrl(val);
};
</code>```

then piping it as so:

```<code>| trustAsResourceUrl}}
</code>```

Which works if using an already established URL but not since I'm trying to form URL from address. I get the following:

Error: [$interpolate:noconcat] Error while interpolating:  Strict
  Contextual Escaping disallows interpolations that concatenate multiple
  expressions when a trusted value is required.  See
  http://docs.angularjs.org/api/ng.$sce

VueJS was so simple but I can't use it in this project. I'll include it in case it gives any ideas:

```<code>methods: {
    getmap: function(){
        setTimeout(function () {
            const searchInput = document.getElementById('searchTextField');
            let addr = searchInput.value;
            let embed = "<div class='form-group'><label for='exampleInputPassword1'>Map Preview</label><iframe frameborder = '0' scrolling= 'no' marginheight= '0' marginwidth= '0' src= 'https://maps.google.com/maps?&q=" + encodeURIComponent(addr) + "&output=embed' > </iframe></div>";

      $('.place').html(embed); }, 200)
    },
</code>```

答:
Essentially you can't use this filter. You have to create the string you want to use directly on the scope:

```<code>this.src = $sce.trustAsResourceUrl("https://maps.google.com/maps?q="
   + encodeURIComponent(item.address) + "&output=embed");
</code>```

Then

You will have to update the entire src rather than just item.address.

Body:
In angular I want to dynamically create a map based on the address entered. I have successfully done this in VueJS. But in angular this triggers security warnings.

HTML:

I have tried creating the following:

app.filter('trustAsResourceUrl', ['$sce', function ($sce) {
    return function (val) {
        return $sce.trustAsResourceUrl(val);
};

then piping it as so:

| trustAsResourceUrl}}

Which works if using an already established URL but not since I'm trying to form URL from address. I get the following:

Error: [$interpolate:noconcat] Error while interpolating:  Strict
  Contextual Escaping disallows interpolations that concatenate multiple
  expressions when a trusted value is required.  See
  http://docs.angularjs.org/api/ng.$sce

VueJS was so simple but I can't use it in this project. I'll include it in case it gives any ideas:

methods: {
    getmap: function(){
        setTimeout(function () {
            const searchInput = document.getElementById('searchTextField');
            let addr = searchInput.value;
            let embed = "
Map Preview
";

      $('.place').html(embed); }, 200)
    },

Body:
Essentially you can't use this filter. You have to create the string you want to use directly on the scope:

this.src = $sce.trustAsResourceUrl("https://maps.google.com/maps?q="
   + encodeURIComponent(item.address) + "&output=embed");

Then <iframe ng-src="{{$ctrl.src}}">

You will have to update the entire src rather than just item.address.


问:
2D iterator access in C++
I'm working on a 2D table with std::map() to count how many times one number transitions to another number.  I've run into two problems.  First, my first transition doesn't show (1->2).  Second, all my transitions are showing only one time (2->3 and 3->1 both happen twice).

I can see why the transitions are only happening once.  The iterator doesn't see currentVal and goes to else, where it adds the values then exits.  I'm not sure how to fix this though.  Any help is appreciated!

```<code>#include <iostream>
#include <map>
#include <algorithm>
#include <vector>

using namespace std;

//import midi notes
vector <int> midiFile = {1, 2, 3, 1, 20, 5, 2, 3, 1};

//create a 2d hashmap for matrix
map <string, map <string, int> > mCounts;

//strings for the previous value and current value
string prevVal = "";
string currentVal = "";

void addNumbers(vector <int> midiFile) {

    for (int i = 0; i < midiFile.size(); i++) {
        currentVal = to_string(midiFile[i]);

        if(prevVal == "") {
            prevVal = currentVal;   //first value
        } else {
            //playCounts is temporary map to store counts of current val in relation to previous val
            map <string, int> playCounts;

            map <string, int> ::iterator iterator;
            iterator = playCounts.find(currentVal);

            //if mCounts doesn't contain the value yet, create a new hashmap
            if(iterator != playCounts.end()){

                int counter = iterator -> second;
                mCounts[prevVal] [currentVal] = counter + 1;

            } else {
                playCounts.insert(pair <string, int>(currentVal, 1));
                mCounts [prevVal] = playCounts;

            }

            prevVal = currentVal;

        }

        //find values already in map
        map <string, map <string, int> > ::iterator it;
        it = mCounts.find(prevVal);

        if (it != mCounts.end()) {
            //if value is found, do nothing
        } else {
            mCounts.insert(pair <string, map <string, int>>(prevVal, map <string, int>()));
        }
    }
}
</code>```

答:
Try the following approach, in which the two integers making up a transition are combined to a single string of the form "1->2", which then serves as key in a count map. The code becomes more concise that way. Further, I eliminated global variables and made them local ones or parameters:

```<code>#include <iostream>
#include <map>
#include <vector>
#include <sstream>

using std::vector;
using std::map;
using std::string;

void addNumbers(const vector <int> &midiFile, map <string, int> &mCounts) {

    for (int i = 0; i < midiFile.size()-1; i++) {

        int prev = midiFile[i];
        int curr = midiFile[i+1];
        std::stringstream ss;
        ss << prev << "->" << curr;

        mCounts[ss.str()]++;
    }
}

int main(int argc, char* argv[])
{
    vector <int> midiFile = {1, 2, 3, 1, 20, 5, 2, 3, 1};
    map <string, int> mCounts;

    addNumbers(midiFile, mCounts);
    for (auto const& x : mCounts)
    {
        std::cout << x.first  // transition
        << ':'
        << x.second // count
        << std::endl ;
    }

    return 0;
}
</code>```

Output:

```<code>1->2:1
1->20:1
2->3:2
20->5:1
3->1:2
5->2:1
</code>```

Title: 2D iterator access in C++

Body:
I'm working on a 2D table with std::map() to count how many times one number transitions to another number.  I've run into two problems.  First, my first transition doesn't show (1->2).  Second, all my transitions are showing only one time (2->3 and 3->1 both happen twice).

I can see why the transitions are only happening once.  The iterator doesn't see currentVal and goes to else, where it adds the values then exits.  I'm not sure how to fix this though.  Any help is appreciated!

#include <iostream>
#include <map>
#include <algorithm>
#include <vector>

using namespace std;

//import midi notes
vector <int> midiFile = {1, 2, 3, 1, 20, 5, 2, 3, 1};

//create a 2d hashmap for matrix
map <string, map <string, int> > mCounts;

//strings for the previous value and current value
string prevVal = "";
string currentVal = "";

void addNumbers(vector <int> midiFile) {

    for (int i = 0; i < midiFile.size(); i++) {
        currentVal = to_string(midiFile[i]);

        if(prevVal == "") {
            prevVal = currentVal;   //first value
        } else {
            //playCounts is temporary map to store counts of current val in relation to previous val
            map <string, int> playCounts;

            map <string, int> ::iterator iterator;
            iterator = playCounts.find(currentVal);

            //if mCounts doesn't contain the value yet, create a new hashmap
            if(iterator != playCounts.end()){

                int counter = iterator -> second;
                mCounts[prevVal] [currentVal] = counter + 1;

            } else {
                playCounts.insert(pair <string, int>(currentVal, 1));
                mCounts [prevVal] = playCounts;

            }

            prevVal = currentVal;

        }

        //find values already in map
        map <string, map <string, int> > ::iterator it;
        it = mCounts.find(prevVal);

        if (it != mCounts.end()) {
            //if value is found, do nothing
        } else {
            mCounts.insert(pair <string, map <string, int>>(prevVal, map <string, int>()));
        }
    }
}

Body:
Try the following approach, in which the two integers making up a transition are combined to a single string of the form "1->2", which then serves as key in a count map. The code becomes more concise that way. Further, I eliminated global variables and made them local ones or parameters:

#include <iostream>
#include <map>
#include <vector>
#include <sstream>

using std::vector;
using std::map;
using std::string;

void addNumbers(const vector <int> &midiFile, map <string, int> &mCounts) {

    for (int i = 0; i < midiFile.size()-1; i++) {

        int prev = midiFile[i];
        int curr = midiFile[i+1];
        std::stringstream ss;
        ss << prev << "->" << curr;

        mCounts[ss.str()]++;
    }
}

int main(int argc, char* argv[])
{
    vector <int> midiFile = {1, 2, 3, 1, 20, 5, 2, 3, 1};
    map <string, int> mCounts;

    addNumbers(midiFile, mCounts);
    for (auto const& x : mCounts)
    {
        std::cout << x.first  // transition
        << ':'
        << x.second // count
        << std::endl ;
    }

    return 0;
}

Output:

1->2:1
1->20:1
2->3:2
20->5:1
3->1:2
5->2:1


问:
jQuery take array from php file and display in html
This is my php script to display json data:

```<code>$get_chat = "SELECT * FROM chat WHERE u_id1='$u_id' && u_id2=2 ORDER BY data DESC";
$run_chat = $conn->query($get_chat);
if ($run_chat->num_rows > 0) {
while($chat_row = $run_chat->fetch_assoc()) {
echo json_encode( $chat_row );
}
}
</code>```

This is my result from php file:

```<code>{"u_id1":"1","content":"ae","u_id2":"2","data":"17\/03\/27 02:02"}
{"u_id1":"1","content":"ax","u_id2":"2","data":"17\/03\/27 02:01"}
{"u_id1":"1","content":"fd","u_id2":"2","data":"17\/03\/26 11:49"}
{"u_id1":"1","content":"hh","u_id2":"2","data":"17\/03\/26 11:47"}
</code>```

And now I whant to display all of this in html.

答:
Try something like:

```<code><?php while($chat_row = $run_chat->fetch_assoc()): ?>

     <p><?= $chat_row['content']; ?></p>

<?php endwhile; ?>
</code>```

No need to use json_encode unless you want a Javascript object from my understanding, and it doesn't seem like that's what you're trying to do.

Body:
This is my php script to display json data:

$get_chat = "SELECT * FROM chat WHERE u_id1='$u_id' && u_id2=2 ORDER BY data DESC";
$run_chat = $conn->query($get_chat);
if ($run_chat->num_rows > 0) {
while($chat_row = $run_chat->fetch_assoc()) {
echo json_encode( $chat_row );
}
}

This is my result from php file:

{"u_id1":"1","content":"ae","u_id2":"2","data":"17\/03\/27 02:02"}
{"u_id1":"1","content":"ax","u_id2":"2","data":"17\/03\/27 02:01"}
{"u_id1":"1","content":"fd","u_id2":"2","data":"17\/03\/26 11:49"}
{"u_id1":"1","content":"hh","u_id2":"2","data":"17\/03\/26 11:47"}

And now I whant to display all of this in html.

Body:
Try something like:

<?php while($chat_row = $run_chat->fetch_assoc()): ?>

     <p><?= $chat_row['content']; ?></p>

<?php endwhile; ?>

No need to use json_encode unless you want a Javascript object from my understanding, and it doesn't seem like that's what you're trying to do.


问:
Retrieving new data from JSON object not working?
alert(data.name); will not return the name of the data object, though alert(data.price); returns the price and keeps on returning prices, no matter what argument I pass to alert. I'm trying to figure out why. If you have any thoughts, please share. I'm completely new to this interesting, though seemingly opaque and tough to debug, language (i.e, JS/JQ).

I'm running the following code on the front-end to accept a ticker symbol from a user.  Originally, the alert(); contained alert(data.price);, and it displayed the stock's price. I changed it to alert(data.name); and still got the price. I then changed it to alert('hello');, and it returned yet another (correct) stock price.

Front-End:

```<code><!DOCTYPE html>

<html>
    <head>
        <script src="https://code.jquery.com/jquery-latest.min.js"></script>
        <script>
        /*global $*/

            /**
             * Gets a quote via JSON.
             */
            function quote()
            {
                var url = '/quote?symbol=' + $('#symbol').val();
                $.getJSON(url, function(data) {
                    alert(data.name);
                });
            }

        </script>
        <title>ajax0</title>
    </head>
    <body>
        <form onsubmit="quote(); return false;">
            <input autocomplete="off" autofocus id="symbol" placeholder="Symbol" type="text"/>
            <input type="submit" value="Get Quote"/>
        </form>
    </body>
</html>
</code>```

On the back end, I am running the following code. It should provide me with a JSON object that gives me access to a stock's name, price, etc. via dot notation.

Back End:

```<code>import csv
import os
import urllib.request

from flask import Flask, jsonify, render_template, request
from flask.exthook import ExtDeprecationWarning
from warnings import simplefilter
simplefilter("ignore", ExtDeprecationWarning)
from flask_autoindex import AutoIndex

app = Flask(__name__)
AutoIndex(app, browse_root=os.path.curdir)

@app.route("/quote")
def quote():
    url = "http://download.finance.yahoo.com/d/quotes.csv?f=snl1&s={}".format(request.args.get("symbol"))
    webpage = urllib.request.urlopen(url)
    datareader = csv.reader(webpage.read().decode("utf-8").splitlines())
    row = next(datareader)
    return jsonify({"name": row[1], "price": float(row[2]), "symbol": row[0].upper()})
</code>```

答:
While the exact nature of the bug remains somewhat elusive, WiseGuy (above) had the right idea. On every page (e.g., code window of web-based IDE, HTML form, etc) I ensured that "disable cache" was selected under the network tab in Chrome's developer tools. Additionally, I moved the following code from a prior project done in Flask to the back-end, so as to ensure no responses were cached. I also wiped my browser history and cache clean, as this bug has been haunting me for a couple of days, and I had to be certain I had covered all of my bases. This combination of steps achieved the desired result. </p>

```<code># ensure responses aren't cached
if app.config["DEBUG"]:
    @app.after_request
    def after_request(response):
        response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
        response.headers["Expires"] = 0
        response.headers["Pragma"] = "no-cache"
        return response
</code>```

Body:
alert(data.name); will not return the name of the data object, though alert(data.price); returns the price and keeps on returning prices, no matter what argument I pass to alert. I'm trying to figure out why. If you have any thoughts, please share. I'm completely new to this interesting, though seemingly opaque and tough to debug, language (i.e, JS/JQ).

I'm running the following code on the front-end to accept a ticker symbol from a user.  Originally, the alert(); contained alert(data.price);, and it displayed the stock's price. I changed it to alert(data.name); and still got the price. I then changed it to alert('hello');, and it returned yet another (correct) stock price.

Front-End:

<!DOCTYPE html>

        <title>ajax0</title>

        <form onsubmit="quote(); return false;">
            <input autocomplete="off" autofocus id="symbol" placeholder="Symbol" type="text"/>
            <input type="submit" value="Get Quote"/>
        </form>

On the back end, I am running the following code. It should provide me with a JSON object that gives me access to a stock's name, price, etc. via dot notation.

Back End:

import csv
import os
import urllib.request

from flask import Flask, jsonify, render_template, request
from flask.exthook import ExtDeprecationWarning
from warnings import simplefilter
simplefilter("ignore", ExtDeprecationWarning)
from flask_autoindex import AutoIndex

app = Flask(__name__)
AutoIndex(app, browse_root=os.path.curdir)

@app.route("/quote")
def quote():
    url = "http://download.finance.yahoo.com/d/quotes.csv?f=snl1&s={}".format(request.args.get("symbol"))
    webpage = urllib.request.urlopen(url)
    datareader = csv.reader(webpage.read().decode("utf-8").splitlines())
    row = next(datareader)
    return jsonify({"name": row[1], "price": float(row[2]), "symbol": row[0].upper()})

Body:
While the exact nature of the bug remains somewhat elusive, WiseGuy (above) had the right idea. On every page (e.g., code window of web-based IDE, HTML form, etc) I ensured that "disable cache" was selected under the network tab in Chrome's developer tools. Additionally, I moved the following code from a prior project done in Flask to the back-end, so as to ensure no responses were cached. I also wiped my browser history and cache clean, as this bug has been haunting me for a couple of days, and I had to be certain I had covered all of my bases. This combination of steps achieved the desired result.

# ensure responses aren't cached
if app.config["DEBUG"]:
    @app.after_request
    def after_request(response):
        response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
        response.headers["Expires"] = 0
        response.headers["Pragma"] = "no-cache"
        return response


问:
PHP/Apache blocking on each request?
Ok, this may be a dumb question but here goes.  I noticed something the other day when I was playing around with different HTML to PDF converters in PHP.  One I tried (dompdf) took forever to run on my HTML.  Eventually it ran out of memory and ended but while it was still running, none of my other PHP scripts were responsive at all.  It was almost as if that one request was blocking the entire Webserver.

Now I'm assuming either that can't be right or I should be setting something somewhere to control that behaviour.  Can someone please clue me in?

答:
did you had open sessions for each of the scripts?:) they might reuse the same sesion and that blocks until the session is freed by the last request...so they basically wait for each other to complete(in your case the long-running pdf generator). This only applies if you use the same browser.

Tip, not sure why you want html to pdf, but you may take a look at FOP http://xmlgraphics.apache.org/fop/ to generate PDF's. I'm using it and works great..and fast:) It does have its quirks though.

OwnerDisplayName: cletus

Title: PHP/Apache blocking on each request?

LastEditorDisplayName: Rich B

OwnerDisplayName: Misquamaqus