问:
Character Segmentation and Recognition for Unevenly Spaced Digits
I have a image of number as shown below.

I segmented the number above into it's digits using methods of Adaptive Thresholding and detecting contours and placing a restriction of height and weight for bounding rectangle to be greater than 15 to get following segmented digits.

Instead of above output, I would like to segment the number in the image above so as to get each digit individually. This result further after resizing to (28, 28) can be fed to CNN of MNIST for better prediction of particular digits.
 So, is there any other neat way of segmenting this number in image into individual digits?

One method as mentioned here suggests to slide a green window of fixed size and detect the digits by training a Neural Net. So,how will this NN be trained to classify the digits? This method avoids the OpenCV approach to separate each individual digit but just sliding window over whole image won't that be a little expensive. How to deal with positive and negative examples while training (should i create a separate dataset... positive examples can be of mnist digits but what about negative examples.)?

Segmentation:

```<code>img = cv2.imread('Image')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

blur = cv2.GaussianBlur(gray,(3,3), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY_INV, 7,10)
thresh = clear_border(thresh)

# find contours in the thresholded image, then initialize the
# list of group locations
clone = np.dstack([gray.copy()] * 3)
groupCnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE,
    cv2.CHAIN_APPROX_SIMPLE)
groupCnts = groupCnts[0] if imutils.is_cv2() else groupCnts[1]
groupLocs = []

clone = np.dstack([gray.copy()] * 3)
# loop over the group contours
for (i, c) in enumerate(groupCnts):
    # compute the bounding box of the contour
    (x, y, w, h) = cv2.boundingRect(c)
    # only accept the contour region as a grouping of characters if
    # the ROI is sufficiently large
    if w >= 15 and h >= 15:
        print (i, (x, y, w, h))
        cv2.rectangle(clone, (x,y), (x+w, y+h), (255,0,0), 1)
        groupLocs.append((x, y, w, h))
</code>```

Sliding Window:

```<code>clf = joblib.load("digits_cls.pkl")    #mnist trained classifier
img = cv2.imread('Image', 0)
winW, winH = (22, 40)
cv2.imshow("Window0", img)
cv2.waitKey(1)

blur = cv2.GaussianBlur(img, (5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv2.THRESH_BINARY,11,2)
thresh = clear_border(thresh)

for (x, y, window) in sliding_window(img, stepSize=10, windowSize=(winW, winH)):
    if (window.shape[0] != winH or window.shape[1] != winW):
        continue
    clone = img.copy()
    roi = thresh[y:y+winH, x:x+winW]
    roi = cv2.resize(roi, (28, 28), interpolation=cv2.INTER_AREA)
    roi = cv2.dilate(roi, (3, 3))
    cv2.imshow("Window1", roi)
    cv2.waitKey(1)
    roi_hog_fd = hog(roi, orientations=9, pixels_per_cell=(14, 14), cells_per_block=(1, 1), visualise=False)
    nbr = clf.predict(np.array([roi_hog_fd], 'float64'))
    print (nbr)

    # since we do not have a classifier, we'll just draw the window
    clone = img.copy()
    cv2.rectangle(clone, (x, y), (x + winW, y + winH), (0, 255, 0), 2)
    cv2.imshow("Window2", clone)
    cv2.waitKey(1)
    time.sleep(0.95)
</code>```

Weird Output(even for blank window it predicts): 522637753787357777722

Seperating joined digits:

```<code> h,w = img.shape[:2]
 count = 0
 iw = 15
 dw = w
 sw, sh = int(0), int(0)
 while (dw > 0):
    new_img = img[:, sw:(count+1)*iw]
    dw = dw - iw
    sw = sw + iw
    if (dw-iw < 0):
        iw = w
    new = os.path.join('amount/', 'amount_'+ str(count)+'.png')
    cv2.imwrite(new, new_img)
</code>```

Output:

  -->

  -->

Having found a way to seprate these joined digits and feeding them to mnist trained classifier, output is inaccurate yet.

Steps I used :

(i)Extract first image

(ii)Segment first image into separate image i.e. get 2nd image.

(iii)See if image width is exceeding some threshold if yes segment it further to yield separate digit (in case of joined digits as above)

(iv) Feed all the separate digits obtained after step 3 to mnist classifier to get the prediction of digit based on reshaped image.

Lengthy right?

Is there any other efficient way to convert first image to digits directly (yes I used pytesseract too!!)?

答:
Training a new neural net will be an elegant solution if you have the time and resource to do so.

To separate each of the digits individually, you can try to inverse the intensity of the image so the handwriting is white and background is black. Then project the values horizontally (sum all pixel values horizontally) and look for the peaks. Every peak location should indicate a new character location.

Extra smoothing function on the projected graph should refine the character locations.

Body:
I have a image of number as shown below.

I segmented the number above into it's digits using methods of Adaptive Thresholding and detecting contours and placing a restriction of height and weight for bounding rectangle to be greater than 15 to get following segmented digits.

Instead of above output, I would like to segment the number in the image above so as to get each digit individually. This result further after resizing to (28, 28) can be fed to CNN of MNIST for better prediction of particular digits.
 So, is there any other neat way of segmenting this number in image into individual digits?

One method as mentioned here suggests to slide a green window of fixed size and detect the digits by training a Neural Net. So,how will this NN be trained to classify the digits? This method avoids the OpenCV approach to separate each individual digit but just sliding window over whole image won't that be a little expensive. How to deal with positive and negative examples while training (should i create a separate dataset... positive examples can be of mnist digits but what about negative examples.)?

Segmentation:

img = cv2.imread('Image')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

blur = cv2.GaussianBlur(gray,(3,3), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY_INV, 7,10)
thresh = clear_border(thresh)

# find contours in the thresholded image, then initialize the
# list of group locations
clone = np.dstack([gray.copy()] * 3)
groupCnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE,
    cv2.CHAIN_APPROX_SIMPLE)
groupCnts = groupCnts[0] if imutils.is_cv2() else groupCnts[1]
groupLocs = []

clone = np.dstack([gray.copy()] * 3)
# loop over the group contours
for (i, c) in enumerate(groupCnts):
    # compute the bounding box of the contour
    (x, y, w, h) = cv2.boundingRect(c)
    # only accept the contour region as a grouping of characters if
    # the ROI is sufficiently large
    if w >= 15 and h >= 15:
        print (i, (x, y, w, h))
        cv2.rectangle(clone, (x,y), (x+w, y+h), (255,0,0), 1)
        groupLocs.append((x, y, w, h))

Sliding Window:

clf = joblib.load("digits_cls.pkl")    #mnist trained classifier
img = cv2.imread('Image', 0)
winW, winH = (22, 40)
cv2.imshow("Window0", img)
cv2.waitKey(1)

blur = cv2.GaussianBlur(img, (5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv2.THRESH_BINARY,11,2)
thresh = clear_border(thresh)

for (x, y, window) in sliding_window(img, stepSize=10, windowSize=(winW, winH)):
    if (window.shape[0] != winH or window.shape[1] != winW):
        continue
    clone = img.copy()
    roi = thresh[y:y+winH, x:x+winW]
    roi = cv2.resize(roi, (28, 28), interpolation=cv2.INTER_AREA)
    roi = cv2.dilate(roi, (3, 3))
    cv2.imshow("Window1", roi)
    cv2.waitKey(1)
    roi_hog_fd = hog(roi, orientations=9, pixels_per_cell=(14, 14), cells_per_block=(1, 1), visualise=False)
    nbr = clf.predict(np.array([roi_hog_fd], 'float64'))
    print (nbr)

    # since we do not have a classifier, we'll just draw the window
    clone = img.copy()
    cv2.rectangle(clone, (x, y), (x + winW, y + winH), (0, 255, 0), 2)
    cv2.imshow("Window2", clone)
    cv2.waitKey(1)
    time.sleep(0.95)

Weird Output(even for blank window it predicts): 522637753787357777722

Seperating joined digits:

 h,w = img.shape[:2]
 count = 0
 iw = 15
 dw = w
 sw, sh = int(0), int(0)
 while (dw > 0):
    new_img = img[:, sw:(count+1)*iw]
    dw = dw - iw
    sw = sw + iw
    if (dw-iw < 0):
        iw = w
    new = os.path.join('amount/', 'amount_'+ str(count)+'.png')
    cv2.imwrite(new, new_img)

Output:

  -->

  -->

Having found a way to seprate these joined digits and feeding them to mnist trained classifier, output is inaccurate yet.

Steps I used :

(i)Extract first image

(ii)Segment first image into separate image i.e. get 2nd image.

(iii)See if image width is exceeding some threshold if yes segment it further to yield separate digit (in case of joined digits as above)

(iv) Feed all the separate digits obtained after step 3 to mnist classifier to get the prediction of digit based on reshaped image.

Lengthy right?

Is there any other efficient way to convert first image to digits directly (yes I used pytesseract too!!)?


来源: stackexchange

问:
Java- Diamond types are not supported at this language level
I have just started working on a Java project, and have downloaded the source code from GitHub, using IntelliJ- I have never used IntelliJ before, but am told that it is a much better IDE to use than Eclipse (which is what I was using when I last did any Java development- about four years ago).

When I try to build the source locally on my computer, having pulled the latest working version from GitHub, I get a compile error on several different lines of code- the error says:

Error:(27, 34) java: diamond operator is not supported in -source 1.5 (use -source 7 or higher to enable diamond operator)

and the lines where these compile errors appear, are lines like:

```<code>return new ArrayList<>(0);
</code>```

If I select the line, and do Alt + Enter on the error, it shows a message stating that I can

"Set language level to 7- Diamonds, ARM, Multi-cache, etc"

However, if I select this option, nothing happens...

In the pom.xml file, there is the following xml:

```<code><plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>${maven-source-plugin.version}</version>
    <executions>
        <execution>
            <id>attach-sources</id>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>
</code>```

But when I looked this error up, I came across the answer at: Diamond type are not supported at this language level, which indicated that I should be using maven1.7 or higher- and it appears that the project is already using version 1.8, so I don't understand why I'm getting this compile error...

Anyone have any suggestions?

答:
Add the following code into your pom.xml file.

```<code><!-- maven-compiler-plugin -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I have just started working on a Java project, and have downloaded the source code from GitHub, using IntelliJ- I have never used IntelliJ before, but am told that it is a much better IDE to use than Eclipse (which is what I was using when I last did any Java development- about four years ago).

When I try to build the source locally on my computer, having pulled the latest working version from GitHub, I get a compile error on several different lines of code- the error says:

Error:(27, 34) java: diamond operator is not supported in -source 1.5 (use -source 7 or higher to enable diamond operator)

and the lines where these compile errors appear, are lines like:

return new ArrayList<>(0);

If I select the line, and do Alt + Enter on the error, it shows a message stating that I can

"Set language level to 7- Diamonds, ARM, Multi-cache, etc"

However, if I select this option, nothing happens...

In the pom.xml file, there is the following xml:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>${maven-source-plugin.version}</version>
    <executions>
        <execution>
            <id>attach-sources</id>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

But when I looked this error up, I came across the answer at: Diamond type are not supported at this language level, which indicated that I should be using maven1.7 or higher- and it appears that the project is already using version 1.8, so I don't understand why I'm getting this compile error...

Anyone have any suggestions?

Body:
Add the following code into your pom.xml file.

<!-- maven-compiler-plugin -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>


问:
Regex: Disable Symbols
Is there any way to disable all symbols, punctuations, block elements, geometric shapes and dingbats such like these:

✁ ✂ ✃ ✄ ✆ ✇ ✈ ✉ ✌ ✍ ✎ ✏ ✐ ✑ ✒ ✓ ✔ ✕  ⟻ ⟼ ⟽ ⟾ ⟿  ⟻ ⟼ ⟽ ⟾ ⟿ ▚ ▛ ▜ ▝ ▞ ▟

without writing down all of them in the Regular Expression Pattern, while enable all other normal language characters such like chinese, arabic etc.. such like these:

文化中国 الجزيرة نت

?

I'm building a javascript validation function and my real problem is that I can't use:

```<code>[a-zA-Z0-9]
</code>```

Because this ignores a lots of languages too not just the symbols.

答:
Not really.

JavaScript doesn't support Unicode Character Properties.  The closest you'll get is excluding ranges by Unicode code point as Greg Hewgill suggested.

For example, to match all of the characters under Mathematical Symbols:

```<code>/[\u2190-\u259F]/
</code>```

ContentLicense: CC BY-SA 2.5

Title: Regex: Disable Symbols

Body:
Is there any way to disable all symbols, punctuations, block elements, geometric shapes and dingbats such like these:

✁ ✂ ✃ ✄ ✆ ✇ ✈ ✉ ✌ ✍ ✎ ✏ ✐ ✑ ✒ ✓ ✔ ✕  ⟻ ⟼ ⟽ ⟾ ⟿  ⟻ ⟼ ⟽ ⟾ ⟿ ▚ ▛ ▜ ▝ ▞ ▟

without writing down all of them in the Regular Expression Pattern, while enable all other normal language characters such like chinese, arabic etc.. such like these:

文化中国 الجزيرة نت

?

I'm building a javascript validation function and my real problem is that I can't use:

[a-zA-Z0-9]

Because this ignores a lots of languages too not just the symbols.

Body:
Not really.

JavaScript doesn't support Unicode Character Properties.  The closest you'll get is excluding ranges by Unicode code point as Greg Hewgill suggested.

For example, to match all of the characters under Mathematical Symbols:

/[\u2190-\u259F]/


问:
How to use an index on a variable
I have a list which I currently add items to in the following way:

```<code>public GameObject object1 = new GameObject("Example Data");
public GameObject object2 = new GameObject("Example Data");
public GameObject object3 = new GameObject("Example Data");
public GameObject object4 = new GameObject("Example Data");
public GameObject object5 = new GameObject("Example Data");
public GameObject object6 = new GameObject("Example Data");
public GameObject object7 = new GameObject("Example Data");
public GameObject object8 = new GameObject("Example Data");
public GameObject object9 = new GameObject("Example Data");
public GameObject object10 = new GameObject("Example Data");
List<GameObject> Objects = new List<GameObject>();

Objects.Add(object1);
Objects.Add(object2);
Objects.Add(object3);
Objects.Add(object4);
Objects.Add(object5);
Objects.Add(object6);
Objects.Add(object7);
Objects.Add(object8);
Objects.Add(object9);
Objects.Add(object10);
</code>```

How would I do this in C# using a foreach? I tried something like the following example but I couldn't get it to work:

```<code>foreach (var number in Enumerable.Range(1, 10))
{
    Objects.Add("object" + [number]);
}
</code>```

答:
In order to read a private field using a dynamically-generated name, you'll need to write a special function to read it via Reflection. Here is how I would write such a function:

```<code>public static object GetFieldValue(this object input, string name)
{
    return input
        .GetType()
        .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
        .ToList()
        .Where(f => f.Name == name)
        .Single()
        .GetValue(input);
}
</code>```

You can then use it like this:

```<code>for (int i = 1; i <= 10; i++)
{
    string fieldName = "object" + i.ToString();
    var o = this.GetFieldValue(fieldName);
    objects.Add(o);
}
</code>```

That being said, this is not a great idea. In fact, this is a really weird thing to do. The normal way you'd deal with this is to omit the objectX variables completely; just store each instance in the list.

```<code>List<GameObject> Objects = new List<GameObject>();
for (int i=0; i<10; i++)
{
    Objects.Add(new GameObject("Example data"));
}
</code>```

If you need to get one of the instances back out of the list, just reference it by index (although you may have to subtract 1 since it is 0-based):

```<code>var object1 = Objects[0];
</code>```

Another way to deal with it, especially if each of those instances is unique in some way, it to use a dictionary:

```<code>Dictionary<string, GameObject> objects = new Dictionary<string, GameObject>();
objects["Player"] = new GameObject("I am a player");
objects["Enemy"] = new GameObject("I am an enemy");
objects["NPC"] = new GameObject("I am a hapless bystander");
</code>```

Then you can access each of the individual objects by name, or you can iterate over all of them if you need to, e.g. if you need to dipose one object you can use

```<code>objects["Player"].Dispose();
objects.Remove("Player");
</code>```

and if you need to dispose of everything at once (e.g. the game is over):

```<code>foreach (var o in objects) o.Dispose();
objects.Clear();
</code>```

As a rule, if you find yourself putting numbers in variable names, you have probably made a mistake in your design. It is almost always better to put them into an array, list, or other data structure meant to contain multiple instances.

Title: How to use an index on a variable

Body:
I have a list which I currently add items to in the following way:

public GameObject object1 = new GameObject("Example Data");
public GameObject object2 = new GameObject("Example Data");
public GameObject object3 = new GameObject("Example Data");
public GameObject object4 = new GameObject("Example Data");
public GameObject object5 = new GameObject("Example Data");
public GameObject object6 = new GameObject("Example Data");
public GameObject object7 = new GameObject("Example Data");
public GameObject object8 = new GameObject("Example Data");
public GameObject object9 = new GameObject("Example Data");
public GameObject object10 = new GameObject("Example Data");
List<GameObject> Objects = new List<GameObject>();

Objects.Add(object1);
Objects.Add(object2);
Objects.Add(object3);
Objects.Add(object4);
Objects.Add(object5);
Objects.Add(object6);
Objects.Add(object7);
Objects.Add(object8);
Objects.Add(object9);
Objects.Add(object10);

How would I do this in C# using a foreach? I tried something like the following example but I couldn't get it to work:

foreach (var number in Enumerable.Range(1, 10))
{
    Objects.Add("object" + [number]);
}

Body:
In order to read a private field using a dynamically-generated name, you'll need to write a special function to read it via Reflection. Here is how I would write such a function:

public static object GetFieldValue(this object input, string name)
{
    return input
        .GetType()
        .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
        .ToList()
        .Where(f => f.Name == name)
        .Single()
        .GetValue(input);
}

You can then use it like this:

for (int i = 1; i <= 10; i++)
{
    string fieldName = "object" + i.ToString();
    var o = this.GetFieldValue(fieldName);
    objects.Add(o);
}

That being said, this is not a great idea. In fact, this is a really weird thing to do. The normal way you'd deal with this is to omit the objectX variables completely; just store each instance in the list.

List<GameObject> Objects = new List<GameObject>();
for (int i=0; i<10; i++)
{
    Objects.Add(new GameObject("Example data"));
}

If you need to get one of the instances back out of the list, just reference it by index (although you may have to subtract 1 since it is 0-based):

var object1 = Objects[0];

Another way to deal with it, especially if each of those instances is unique in some way, it to use a dictionary:

Dictionary<string, GameObject> objects = new Dictionary<string, GameObject>();
objects["Player"] = new GameObject("I am a player");
objects["Enemy"] = new GameObject("I am an enemy");
objects["NPC"] = new GameObject("I am a hapless bystander");

Then you can access each of the individual objects by name, or you can iterate over all of them if you need to, e.g. if you need to dipose one object you can use

objects["Player"].Dispose();
objects.Remove("Player");

and if you need to dispose of everything at once (e.g. the game is over):

foreach (var o in objects) o.Dispose();
objects.Clear();

As a rule, if you find yourself putting numbers in variable names, you have probably made a mistake in your design. It is almost always better to put them into an array, list, or other data structure meant to contain multiple instances.


问:
Select elements in such a way that most of the elements are in the beginning of a list
I have a list of values and I want to select n values in such a way that most of the elements come from the beginning of the list and diminish as it goes further in the list (as shown in the link below).

```<code>np.random.seed(0)
a = pd.Series(range(100))
np.random.shuffle(a)
a.values

array([26, 86,  2, 55, 75, 93, 16, 73, 54, 95, 53, 92, 78, 13,  7, 30, 22,
       24, 33,  8, 43, 62,  3, 71, 45, 48,  6, 99, 82, 76, 60, 80, 90, 68,
       51, 27, 18, 56, 63, 74,  1, 61, 42, 41,  4, 15, 17, 40, 38,  5, 91,
       59,  0, 34, 28, 50, 11, 35, 23, 52, 10, 31, 66, 57, 79, 85, 32, 84,
       14, 89, 19, 29, 49, 97, 98, 69, 20, 94, 72, 77, 25, 37, 81, 46, 39,
       65, 58, 12, 88, 70, 87, 36, 21, 83,  9, 96, 67, 64, 47, 44])
</code>```

what is the good way to select those numbers?

http://www.bydatabedriven.com/wp-content/uploads/2012/12/Screen-Shot-2012-12-03-at-8.12.36-PM.png

As an example if n = 10, then the returned values may be (more numbers picked from the begining of the list as compared to those values which are to the end of the list) :

26, 2, 16, 92, 8, 45, 61, 99, 94 39

答:
Solving by Re-inventing the Wheel

Here is how you do it from the first principles.

random.random() returns a random number between 0 and 1. This means that the expression random.random() < x becomes true less frequently as x becomes closer to 0.

For each element in the array, say array[i], let us define the odds of the element getting picked as

odds_pick(i) = (1 - i / len(array)) * DAMP.
  Here, DAMP is a number between 0 and 1, which is used to diminish the odds of a number being picked. Thus,

when i = 0 (the first element), the odds of the element being picked are just = DAMP.

For the last element, it's DAMP / len(array).

For others, the odds are between these extremes, and they diminish as i gets larger.

Finally, to get this appropriate sample, iterate over the array, and check if random.random() < odds_pick(i). If so, pick the element.

Because of how we have defined odds_pick(i), it will become more and more close to 0 as i increases, and thus random.random() < odds_pick(i) will be less and less true towards the end. Ultimately, this means we end up picking elements more frequently from the front than from the end.

Code:

```<code>import random
def sample_with_bias(arr, n, damping_factor=.3):
    res = []
    indexes_picked = []
    n_picked = 0
    while n_picked < n:
        for i, x in enumerate(arr):
            odds_pick = damping_factor * (1 - i * 1. / len(arr))
            if i not in indexes_picked and random.random() < odds_pick:
                print(odds_pick)
                n_picked += 1
                indexes_picked.append(i)
                res.append(x)
    return res
</code>```

Note that there are multiple pass over the array to cover the corner case where n unique elements could not be sampled in a single pass.

Let's run some experiments:

```<code>def run_experiment(arr, damping_factor, num_pick=10, num_runs=100):
    all_samples = []
    for i in range(num_runs):
        all_samples.extend(sample_with_bias(arr, num_pick, damping_factor=damping_factor))
    dist = Counter(all_samples)
    dist = sorted(list(dist.items()), key=lambda k: k[0])
    k, v = zip(*dist)
    plt.bar(k, v)
    plt.title("Damping Factor = {0}".format(damping_factor))
    plt.show()
</code>```

and

```<code>for df in [0.10, 0.50, 0.99]:
    np.random.seed(0)
    a = pd.Series(range(100))
    run_experiment(a, damping_factor=df)
</code>```

Results

For lots of damping, almost uniform with still a bias for the elements in the beginning:

Let's see what happens when we decrease the damping:

With almost no damping, only the elements in the front are picked:

Body:
I have a list of values and I want to select n values in such a way that most of the elements come from the beginning of the list and diminish as it goes further in the list (as shown in the link below).

np.random.seed(0)
a = pd.Series(range(100))
np.random.shuffle(a)
a.values

array([26, 86,  2, 55, 75, 93, 16, 73, 54, 95, 53, 92, 78, 13,  7, 30, 22,
       24, 33,  8, 43, 62,  3, 71, 45, 48,  6, 99, 82, 76, 60, 80, 90, 68,
       51, 27, 18, 56, 63, 74,  1, 61, 42, 41,  4, 15, 17, 40, 38,  5, 91,
       59,  0, 34, 28, 50, 11, 35, 23, 52, 10, 31, 66, 57, 79, 85, 32, 84,
       14, 89, 19, 29, 49, 97, 98, 69, 20, 94, 72, 77, 25, 37, 81, 46, 39,
       65, 58, 12, 88, 70, 87, 36, 21, 83,  9, 96, 67, 64, 47, 44])

what is the good way to select those numbers?

http://www.bydatabedriven.com/wp-content/uploads/2012/12/Screen-Shot-2012-12-03-at-8.12.36-PM.png

As an example if n = 10, then the returned values may be (more numbers picked from the begining of the list as compared to those values which are to the end of the list) :

26, 2, 16, 92, 8, 45, 61, 99, 94 39

Body:
Solving by Re-inventing the Wheel

Here is how you do it from the first principles.

random.random() returns a random number between 0 and 1. This means that the expression random.random() < x becomes true less frequently as x becomes closer to 0.

For each element in the array, say array[i], let us define the odds of the element getting picked as

odds_pick(i) = (1 - i / len(array)) * DAMP.
  Here, DAMP is a number between 0 and 1, which is used to diminish the odds of a number being picked. Thus,

when i = 0 (the first element), the odds of the element being picked are just = DAMP.

For the last element, it's DAMP / len(array).

For others, the odds are between these extremes, and they diminish as i gets larger.

Finally, to get this appropriate sample, iterate over the array, and check if random.random() < odds_pick(i). If so, pick the element.

Because of how we have defined odds_pick(i), it will become more and more close to 0 as i increases, and thus random.random() < odds_pick(i) will be less and less true towards the end. Ultimately, this means we end up picking elements more frequently from the front than from the end.

Code:

import random
def sample_with_bias(arr, n, damping_factor=.3):
    res = []
    indexes_picked = []
    n_picked = 0
    while n_picked < n:
        for i, x in enumerate(arr):
            odds_pick = damping_factor * (1 - i * 1. / len(arr))
            if i not in indexes_picked and random.random() < odds_pick:
                print(odds_pick)
                n_picked += 1
                indexes_picked.append(i)
                res.append(x)
    return res

Note that there are multiple pass over the array to cover the corner case where n unique elements could not be sampled in a single pass.

Let's run some experiments:

def run_experiment(arr, damping_factor, num_pick=10, num_runs=100):
    all_samples = []
    for i in range(num_runs):
        all_samples.extend(sample_with_bias(arr, num_pick, damping_factor=damping_factor))
    dist = Counter(all_samples)
    dist = sorted(list(dist.items()), key=lambda k: k[0])
    k, v = zip(*dist)
    plt.bar(k, v)
    plt.title("Damping Factor = {0}".format(damping_factor))
    plt.show()

and

for df in [0.10, 0.50, 0.99]:
    np.random.seed(0)
    a = pd.Series(range(100))
    run_experiment(a, damping_factor=df)

Results

For lots of damping, almost uniform with still a bias for the elements in the beginning:

Let's see what happens when we decrease the damping:

With almost no damping, only the elements in the front are picked:


问:
indexed by a type vs containing a type in idris
I'm currently going through the Type-Driven Development with Idris book.

I have two questions relating to the design of the example data store in Chapter 6.  The data store is a command line application that allows the user to set what kind of data is stored in it, and then add new data.

Here are the relevant parts of the code (simplified slightly).  You can see the full code on Github:

```<code>module Main

import Data.Vect

infixr 4 .+.

-- This datatype is to define what sorts of data can be contained in the data store.
data Schema
  = SString
  | SInt
  | (.+.) Schema Schema

-- This is a type-level function that translates a Schema to an actual type.
SchemaType : Schema -> Type
SchemaType SString = String
SchemaType SInt = Int
SchemaType (x .+. y) = (SchemaType x, SchemaType y)

-- This is the data store.  It can potentially be storing any sort of schema.
record DataStore where
       constructor MkData
       schema : Schema
       size : Nat
       items : Vect size (SchemaType schema)

-- This adds new data to the datastore, making sure that the new data is
-- the same type that the DataStore holds.
addToStore
  : (dataStore : DataStore) -> SchemaType (schema dataStore) -> DataStore
addToStore (MkData schema' size' store') newitem =
  MkData schema' _ (addToData store')
  where
    addToData
      : Vect size' (SchemaType schema') -> Vect (size' + 1) (SchemaType schema')
    addToData xs = xs ++ [newitem]

-- These are commands the user can use on the command line.  They are able
-- to change the schema, and add new data.
data Command : Schema -> Type where
  SetSchema : (newSchema : Schema) -> Command schema
  Add : SchemaType schema -> Command schema

-- Given a Schema, this parses input from the user into a Command.
parse : (schema : Schema) -> String -> Maybe (Command schema)

-- This is the main workhorse of the application.  It parses user
-- input, turns it into a command, then evaluates the command and
-- returns an updated DataStore.
processInput
  : (dataStore : DataStore) -> String -> Maybe (String, DataStore)
processInput dataStore@(MkData schema' size' items') input =
  case parse schema' input of
    Nothing => Just ("Invalid command\n", dataStore)
    Just (SetSchema newSchema) =>
      Just ("updated schema and reset datastore\n", MkData newSchema _ [])
    Just (Add item) =>
      let newStore = addToStore (MkData schema' size' items') item
      in Just ("ID " ++ show (size dataStore) ++ "\n", newStore)

-- This kicks off processInput with an empty datastore and a simple Schema
-- of SString.
main : IO ()
main = replWith (MkData SString _ []) "Command: " processInput
</code>```

This makes sense and is easy to use, but one thing bugged me about the design.  Why does the DataStore contain a Schema instead of being indexed by one?

Because the DataStore is not indexed by a Schema, we could have written an incorrect addToStore function like this:

```<code>addToStore
  : (dataStore : DataStore) -> SchemaType (schema dataStore) -> DataStore
addToStore _ newitem =
  MkData SInt _ []
</code>```

Here is what I would imagine more type safe code would look like.  You can see the full code on Github:

```<code>module Main

import Data.Vect

infixr 4 .+.

data Schema
  = SString
 | SInt
 | (.+.) Schema Schema

SchemaType : Schema -> Type
SchemaType SString = String
SchemaType SInt = Int
SchemaType (x .+. y) = (SchemaType x, SchemaType y)

record DataStore (schema : Schema) where
       constructor MkData
       size : Nat
       items : Vect size (SchemaType schema)

addToStore
  : (dataStore : DataStore schema) ->
    SchemaType schema ->
    DataStore schema
addToStore {schema} (MkData size' store') newitem =
  MkData _ (addToData store')
  where
    addToData
      : Vect size' (SchemaType schema) -> Vect (size' + 1) (SchemaType schema)
    addToData xs = xs ++ [newitem]

data Command : Schema -> Type where
  SetSchema : (newSchema : Schema) -> Command schema
  Add : SchemaType schema -> Command schema

parse : (schema : Schema) -> String -> Maybe (Command schema)

processInput
  : (schema : Schema ** DataStore schema) ->
    String ->
    Maybe (String, (newschema ** DataStore newschema))
processInput (schema ** (MkData size' items')) input =
  case parse schema input of
    Nothing => Just ("Invalid command\n", (_ ** MkData size' items'))
    Just (SetSchema newSchema) =>
      Just ("updated schema and reset datastore\n", (newSchema ** MkData _ []))
    Just (Add item) =>
      let newStore = addToStore (MkData size' items') item
          msg = "ID " ++ show (size newStore) ++ "\n"
      in Just (msg, (schema ** newStore))

main : IO ()
main = replWith (SString ** MkData _ []) "Command: " processInput
</code>```

Here are my two questions:

Why didn't the book use the more type-safe version of the DataStore type (the one indexed by the Schema)?  Is there something that is gained by using the less type-safe version (the one that just contains a Schema)?

What is the theoretical difference of a type being indexed by another type vs containing another type?  Does this difference change depending on what language you are working on?

For instance, I imagine there might not be a big difference in Idris, but there is quite a big difference in Haskell. (Right...?)

I just started playing around with Idris (and I am not particularly well-versed with the use of singletons or GADTs in Haskell), so I'm having a hard time wrapping my head around this.  If you could point me to any papers talking about this, I'd be very interested.

答: Per the comments, this was pedantry.  Early on, a dependent record is used so that dealing with type indexes is not required.  Later, a indexed type is used in order to restrict (and make easier to find via proof-search) valid implementations.</p>

Body:
I'm currently going through the Type-Driven Development with Idris book.

I have two questions relating to the design of the example data store in Chapter 6.  The data store is a command line application that allows the user to set what kind of data is stored in it, and then add new data.

Here are the relevant parts of the code (simplified slightly).  You can see the full code on Github:

module Main

import Data.Vect

infixr 4 .+.

-- This datatype is to define what sorts of data can be contained in the data store.
data Schema
  = SString
  | SInt
  | (.+.) Schema Schema

-- This is a type-level function that translates a Schema to an actual type.
SchemaType : Schema -> Type
SchemaType SString = String
SchemaType SInt = Int
SchemaType (x .+. y) = (SchemaType x, SchemaType y)

-- This is the data store.  It can potentially be storing any sort of schema.
record DataStore where
       constructor MkData
       schema : Schema
       size : Nat
       items : Vect size (SchemaType schema)

-- This adds new data to the datastore, making sure that the new data is
-- the same type that the DataStore holds.
addToStore
  : (dataStore : DataStore) -> SchemaType (schema dataStore) -> DataStore
addToStore (MkData schema' size' store') newitem =
  MkData schema' _ (addToData store')
  where
    addToData
      : Vect size' (SchemaType schema') -> Vect (size' + 1) (SchemaType schema')
    addToData xs = xs ++ [newitem]

-- These are commands the user can use on the command line.  They are able
-- to change the schema, and add new data.
data Command : Schema -> Type where
  SetSchema : (newSchema : Schema) -> Command schema
  Add : SchemaType schema -> Command schema

-- Given a Schema, this parses input from the user into a Command.
parse : (schema : Schema) -> String -> Maybe (Command schema)

-- This is the main workhorse of the application.  It parses user
-- input, turns it into a command, then evaluates the command and
-- returns an updated DataStore.
processInput
  : (dataStore : DataStore) -> String -> Maybe (String, DataStore)
processInput dataStore@(MkData schema' size' items') input =
  case parse schema' input of
    Nothing => Just ("Invalid command\n", dataStore)
    Just (SetSchema newSchema) =>
      Just ("updated schema and reset datastore\n", MkData newSchema _ [])
    Just (Add item) =>
      let newStore = addToStore (MkData schema' size' items') item
      in Just ("ID " ++ show (size dataStore) ++ "\n", newStore)

-- This kicks off processInput with an empty datastore and a simple Schema
-- of SString.
main : IO ()
main = replWith (MkData SString _ []) "Command: " processInput

This makes sense and is easy to use, but one thing bugged me about the design.  Why does the DataStore contain a Schema instead of being indexed by one?

Because the DataStore is not indexed by a Schema, we could have written an incorrect addToStore function like this:

addToStore
  : (dataStore : DataStore) -> SchemaType (schema dataStore) -> DataStore
addToStore _ newitem =
  MkData SInt _ []

Here is what I would imagine more type safe code would look like.  You can see the full code on Github:

module Main

import Data.Vect

infixr 4 .+.

data Schema
  = SString
 | SInt
 | (.+.) Schema Schema

SchemaType : Schema -> Type
SchemaType SString = String
SchemaType SInt = Int
SchemaType (x .+. y) = (SchemaType x, SchemaType y)

record DataStore (schema : Schema) where
       constructor MkData
       size : Nat
       items : Vect size (SchemaType schema)

addToStore
  : (dataStore : DataStore schema) ->
    SchemaType schema ->
    DataStore schema
addToStore {schema} (MkData size' store') newitem =
  MkData _ (addToData store')
  where
    addToData
      : Vect size' (SchemaType schema) -> Vect (size' + 1) (SchemaType schema)
    addToData xs = xs ++ [newitem]

data Command : Schema -> Type where
  SetSchema : (newSchema : Schema) -> Command schema
  Add : SchemaType schema -> Command schema

parse : (schema : Schema) -> String -> Maybe (Command schema)

processInput
  : (schema : Schema ** DataStore schema) ->
    String ->
    Maybe (String, (newschema ** DataStore newschema))
processInput (schema ** (MkData size' items')) input =
  case parse schema input of
    Nothing => Just ("Invalid command\n", (_ ** MkData size' items'))
    Just (SetSchema newSchema) =>
      Just ("updated schema and reset datastore\n", (newSchema ** MkData _ []))
    Just (Add item) =>
      let newStore = addToStore (MkData size' items') item
          msg = "ID " ++ show (size newStore) ++ "\n"
      in Just (msg, (schema ** newStore))

main : IO ()
main = replWith (SString ** MkData _ []) "Command: " processInput

Here are my two questions:

Why didn't the book use the more type-safe version of the DataStore type (the one indexed by the Schema)?  Is there something that is gained by using the less type-safe version (the one that just contains a Schema)?

What is the theoretical difference of a type being indexed by another type vs containing another type?  Does this difference change depending on what language you are working on?

For instance, I imagine there might not be a big difference in Idris, but there is quite a big difference in Haskell. (Right...?)

I just started playing around with Idris (and I am not particularly well-versed with the use of singletons or GADTs in Haskell), so I'm having a hard time wrapping my head around this.  If you could point me to any papers talking about this, I'd be very interested.


问:
connect to Wonderware Historian OLE DB using python 3 and OSX or Linux
Could anyone share a functional connection method to Wonderware's Historian using python3 on OSX (or linux)?

Historian is apparently a Microsoft SQL Server OLE DB (see pg102 of http://www.logic-control.com/datasheets/1/Historian/HistorianConcepts.pdf).

Another SO post suggests that the only python library available capable of connecting to an OLE DB is 'adodbapi' (Connecting to Microsoft SQL server using Python)

an attempt in code (using default RO credentials):

```<code>import adodbapi
ServerName = "ServerName"
MSQLDatabase = "Runtime"
username = "aaUser"
password = "pwUser"
conn = adodbapi.connect("PROVIDER=INSQL;Data Source={0};Database={1};trusted_connection=yes;UID={2};PWD{3};".format(ServerName,MSQLDatabase,username,password))
</code>```

That gives an error:

```<code>adodbapi.apibase.OperationalError: (InterfaceError("Windows COM Error: Dispatch('ADODB.Connection') failed.",)...
</code>```

The error is probably due to the absence and unavailability of the pywin32 package, which is apparently Windows only (Pywin32 (com objects) on Mac)

Tips appreciated.  I highly suspect that the Microsoft vs Mac/Linux worlds just can't be bridged in this situation.

答:
I am able to access a Wonderware server using Python3 both through sqlalchemy and pyodbc on Linux and Windows - I don't have a Mac so you're on your own there. I've read that there are other drivers available, but I don't have any experience with them. If you have any suggestions here I'd be glad to hear them.

This is how I modularize the functionality of pyodbc. Essentially, I've defined a function in our code that sets up the sql engine conncetion:

```<code>def get_conn():
    conn_pyodbc = pyodbc.connect(DSN=<myDSN>, UID=<user>, PWD=<pass>)
    return conn_pyodbc
</code>```

And I use the connection as such:

```<code>def executeQuery(sql_query):
    with get_conn() as conn:
        df = pd.read_sql(sql_query, conn)
</code>```

Using the context manager just seems like an easier way of handling opening and closing database connections.

As far as setting up the DSN, I needed to install the Microsoft ODBC driver, which was easy enough to do by following some links I found online. After a successful installation I edited the /etc/odbc.init and /etc/odbcinst.ini files manually such that they look like this now:

```<code>$ cat /etc/odbc.ini
[myDSN]
Driver=ODBC Driver 13 for SQL Server
Description=Awesome server
Trace=No
Server=<serverIP>
</code>```

and

```<code>$ cat odbcinst.ini
[ODBC Driver 13 for SQL Server]
Description=Microsoft ODBC Driver 13 for SQL Server
Driver=/opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.1
UsageCount=1
</code>```

In my experience, you can use 'Trusted Connection', but that means that your computer will try to connect to the server using it's Windows credentials. These work if you are logged into a Windows machine that has access to the data in question. Running on Linux is a different story, so I keep to the user/password combo.

Anymore questions feel free to ask.

Body:
Could anyone share a functional connection method to Wonderware's Historian using python3 on OSX (or linux)?

Historian is apparently a Microsoft SQL Server OLE DB (see pg102 of http://www.logic-control.com/datasheets/1/Historian/HistorianConcepts.pdf).

Another SO post suggests that the only python library available capable of connecting to an OLE DB is 'adodbapi' (Connecting to Microsoft SQL server using Python)

an attempt in code (using default RO credentials):

import adodbapi
ServerName = "ServerName"
MSQLDatabase = "Runtime"
username = "aaUser"
password = "pwUser"
conn = adodbapi.connect("PROVIDER=INSQL;Data Source={0};Database={1};trusted_connection=yes;UID={2};PWD{3};".format(ServerName,MSQLDatabase,username,password))

That gives an error:

adodbapi.apibase.OperationalError: (InterfaceError("Windows COM Error: Dispatch('ADODB.Connection') failed.",)...

The error is probably due to the absence and unavailability of the pywin32 package, which is apparently Windows only (Pywin32 (com objects) on Mac)

Tips appreciated.  I highly suspect that the Microsoft vs Mac/Linux worlds just can't be bridged in this situation.

Body:
I am able to access a Wonderware server using Python3 both through sqlalchemy and pyodbc on Linux and Windows - I don't have a Mac so you're on your own there. I've read that there are other drivers available, but I don't have any experience with them. If you have any suggestions here I'd be glad to hear them.

This is how I modularize the functionality of pyodbc. Essentially, I've defined a function in our code that sets up the sql engine conncetion:

def get_conn():
    conn_pyodbc = pyodbc.connect(DSN=<myDSN>, UID=<user>, PWD=<pass>)
    return conn_pyodbc

And I use the connection as such:

def executeQuery(sql_query):
    with get_conn() as conn:
        df = pd.read_sql(sql_query, conn)

Using the context manager just seems like an easier way of handling opening and closing database connections.

As far as setting up the DSN, I needed to install the Microsoft ODBC driver, which was easy enough to do by following some links I found online. After a successful installation I edited the /etc/odbc.init and /etc/odbcinst.ini files manually such that they look like this now:

$ cat /etc/odbc.ini
[myDSN]
Driver=ODBC Driver 13 for SQL Server
Description=Awesome server
Trace=No
Server=<serverIP>

and

$ cat odbcinst.ini
[ODBC Driver 13 for SQL Server]
Description=Microsoft ODBC Driver 13 for SQL Server
Driver=/opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.1
UsageCount=1

In my experience, you can use 'Trusted Connection', but that means that your computer will try to connect to the server using it's Windows credentials. These work if you are logged into a Windows machine that has access to the data in question. Running on Linux is a different story, so I keep to the user/password combo.

Anymore questions feel free to ask.


问:
Microsoft Test Manager Communication with Developers
I'm currently designing and setting up everything for our development team, regarding to our new workflow with scrum, test management , ....

Scrum wise is everything done, I'm currently setting up the testing workflow and enviroment.

We would like to establisht he Microsoft Test Manager.

Everything is clear to 1 very important thing - How do requirements of a Test Plan for a single Sprint communicate with the tester, to be ready to be tested.

Workflow and Missing Part explained:

Developer get BacklogItem, describe Tasks, RWT, ... and define possible TestCases, but are not responsible for the complete TestCase szenario.

Tester create a TestPlan for the current iteration, and add every BackLogItem to the TestSuite as a requirement.

TestCases already created get displayed

Tester starts to write more TestCases and defines new ones.

Developer commits work for BacklogItem.

???? Developer and Tester do a mystirous handshake and suddenly the tester knows that the specific BacklogItem is ready to test and all included test cases ????

Tester tests the given TestCases, reports and creates Bug's if needed.

So as you see, how is the communication between the development team and tester team what is ready to be tested.

What I have spotted so far is the BLOCKED state of a test case.As long as a Test Case is in blocked state, the tester knows to not touch this test case.

This could work, but wow this is a huge overhead for the developer, as a developer has once he has committed his code to the tfs, go to the test area in TFS web Portal, and set the state of every test case of the given backlog item to be ready to tested or otherwise said, the state READY.

This isn't really working for us.

The other way would be a huge overhead for the testers, so if they need to track down in the tfs web portal, which backlogitem is in the commited state, and then start testing the test cases for the assoicated BacklogItem which is a requirement of the current test plan.

So as you see hopefully, my problem is how do the testers know, when a requirement is ready to be tested and all it's assoicated test cases???

答:
A process that has worked for me and my teams is:

Everyone on the team uses TFS as their guidepost as to what to work on

daily standups help determine work for the day (dev finished work on x)

Requirements are set to Produced state to show that the dev has finished their work. That's a trigger that it's ready to be tested (as well as conversation)

Tester can see in TFS what's Produced and ready for testing (have tasks under Requirements for testing perhaps)

I don't believe that the developers should interact with the Test Case work items. Testers and developers should be having conversations several times daily about their work.

Hope that helps!


问:
Storing metadata about password hashes in the database?
I was talking to a friend of mine and he stated that to store user passwords in the database, he, and I quote:

Takes a users password

Hashes it with a random salt

Then, he prefixes the result of #2 with the hash type and the salt, joining them with a pipe delimited string. (e.g. SHA1|RANDOMSALT|afde4343....)

Stores result of #3 in the db

He claims that's it readable, as he "can instantly know" what type of hash digest is used.

I don't think I've ever seen this before, but, I'm looking for reasons on why it would be bad aside from the fact than an unauthorized user can instantly know what type of hash is used to encrypt the passwords and the extra space required for storing the field.

My gut reaction is that this approach to working with passwords is silly, as any indication to help an attacker break passwords is a weakness. Any other reasons I should use to convince him that this is a bad idea?

Thanks!

答:
It's also good practice to store the hash "cost" (number of times the hash has been stretched), even crypt() does that. Possibly, the worst issue is that you first have to query the database (to know the salt, cost, algorithm) and then check against your generated hash, this requires an extra trip to the DB.

Why is this a good practice? Well, if you have user-specific salts, they have to be stored somewhere... Also, you may (in the future) want to escalate the cost (number of times a hash is "re-hashed") of your hashes to keep up with Moore's Law, if you don't know the original cost you wont be able to do anything.

I strongly recommend that you read this blog post about (secure) password hashing.


问:
RxJava operator Debounce is not working
I want to implement place autocomplete in Android application, and for this I'm using Retrofit and RxJava. I want to make response every 2 seconds after user type something. I'm trying to use debounce operator for this, but it's not working. It's giving me the result immediately without any pause.</p>

```<code> mAutocompleteSearchApi.get(input, "(cities)", API_KEY)
            .debounce(2, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .flatMap(prediction -> Observable.fromIterable(prediction.getPredictions()))
            .subscribe(prediction -> {
                Log.e(TAG, "rxAutocomplete : " + prediction.getStructuredFormatting().getMainText());
            });
</code>```

答:
As @BenP says in the comment, you appear to be applying debounce to the Place Autocomplete service. This call will return an Observable that emits a single result (or error) before completing, at which point the debounce operator will emit that one and only item.

What you probably want to be doing is debouncing the user input with something like:

// Subject holding the most recent user input
BehaviorSubject<String> userInputSubject = BehaviorSubject.create();

// Handler that is notified when the user changes input
public void onTextChanged(String text) {
    userInputSubject.onNext(text);
}

// Subscription to monitor changes to user input, calling API at most every
// two seconds. (Remember to unsubscribe this subscription!)
userInputSubject
    .debounce(2, TimeUnit.SECONDS)
    .flatMap(input -> mAutocompleteSearchApi.get(input, "(cities)", API_KEY))
    .flatMap(prediction -> Observable.fromIterable(prediction.getPredictions()))
    .subscribe(prediction -> {
        Log.e(TAG, "rxAutocomplete : " + prediction.getStructuredFormatting().getMainText());
    });
```

Title: RxJava operator Debounce is not working

Body:
I want to implement place autocomplete in Android application, and for this I'm using Retrofit and RxJava. I want to make response every 2 seconds after user type something. I'm trying to use debounce operator for this, but it's not working. It's giving me the result immediately without any pause.

 mAutocompleteSearchApi.get(input, "(cities)", API_KEY)
            .debounce(2, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .flatMap(prediction -> Observable.fromIterable(prediction.getPredictions()))
            .subscribe(prediction -> {
                Log.e(TAG, "rxAutocomplete : " + prediction.getStructuredFormatting().getMainText());
            });


问:
How to fix the dynamic domains issue in Odoo?
I have created a new model named product.service.type. Then, in product.product model, I have also created a Many2many field (named service_type, pointing to product.service.type model).

Now I have the model test, which has product_id and service_type_id fields, both Many2one pointing to product.product and product.service.type respectively.

What I want is that if you select a product, the service type domain changes to show only the service types of the selected product. I managed this through an onchange:

def onchange_product_id(self, cr, uid, ids, product_id, context=None):
    if product_id:
        product = self.pool.get('product.product').browse(
            cr, uid, [product_id], context=context)
        service_type_ids = product.service_type.mapped('id')
        return {
            'domain': {
                'service_type_id': [('id', 'in', service_type_ids)],
            },
        }
```

This is working great, the problem is when you are editing the record (not creating a new one), because in this case the onchange is not being executed and therefore, the domain shows all service types.

You can see the same problem in partners form, with the field title. Create a new partner which is a company, the domain of title field changes to allow you select only records like Corp., Ltd., etc., but if you set that the partner is a contact, you can select among records like Doctor, Madam, Miss, etc. Now, save the partner with the data you want, and go to other menu of the topbar. Return to partners form and open the created partner to edit it. Check the title field without changing the is_company field. Now you have all titles available, despite your partner belongs to a specific class (company or contact).

How could I fix this problem?

答:
On your model test, beside your 2 fields, you need one additional many2many that related to field service_type of object product.product. Then give domain to your field service_type_id.

Here is the illustration,

On model product.product you have:

service_type (m2m to product.service.type)

On model test you have:

product_id (m2o to product.product)

service_type_id (m2o to product.service.type)

available_service_type_ids (m2m related/computed to service_type of product.product)

On your xml, service_type_id will have domain [(id , in, available_service_type_ids and available_service_type_ids[0] and available_service_type_ids[0][2] or False)]

Body:
I have created a new model named product.service.type. Then, in product.product model, I have also created a Many2many field (named service_type, pointing to product.service.type model).

Now I have the model test, which has product_id and service_type_id fields, both Many2one pointing to product.product and product.service.type respectively.

What I want is that if you select a product, the service type domain changes to show only the service types of the selected product. I managed this through an onchange:

def onchange_product_id(self, cr, uid, ids, product_id, context=None):
    if product_id:
        product = self.pool.get('product.product').browse(
            cr, uid, [product_id], context=context)
        service_type_ids = product.service_type.mapped('id')
        return {
            'domain': {
                'service_type_id': [('id', 'in', service_type_ids)],
            },
        }

This is working great, the problem is when you are editing the record (not creating a new one), because in this case the onchange is not being executed and therefore, the domain shows all service types.

You can see the same problem in partners form, with the field title. Create a new partner which is a company, the domain of title field changes to allow you select only records like Corp., Ltd., etc., but if you set that the partner is a contact, you can select among records like Doctor, Madam, Miss, etc. Now, save the partner with the data you want, and go to other menu of the topbar. Return to partners form and open the created partner to edit it. Check the title field without changing the is_company field. Now you have all titles available, despite your partner belongs to a specific class (company or contact).

How could I fix this problem?


问:
UICollectionView scroll to last item without Animation
I have a UICollectionView to display chat messages. At the beginning I load the existing messages to the collectionView and scroll the collectionView down to the last message with this method:

```<code>- (void)scrollToLastMessageAnimated:(BOOL)animated;
{
    if (_messages.count == 0) { return; }

    NSUInteger indexOfLastSection = _messagesBySections.count - 1;
    NSInteger indexOfMessageInLastSection = [_messagesBySections[indexOfLastSection] count] - 1;
    NSIndexPath *path = [NSIndexPath indexPathForItem:indexOfMessageInLastSection
                                            inSection:indexOfLastSection];

    [_collectionView scrollToItemAtIndexPath:path
                           atScrollPosition:UICollectionViewScrollPositionCenteredVertically
                                   animated:animated];
}
</code>```

This only works animated when I call it in the viewDidAppear: method and not in viewWillAppear: method. How can I scroll down without animation?

答:
A more foolproof solution that handles multiple/0 sections/items</p>

```<code>extension UICollectionView {
    func scrollToLastItem(at scrollPosition: UICollectionViewScrollPosition = .centeredHorizontally, animated: Bool = true) {
        let lastSection = numberOfSections - 1
        guard lastSection >= 0 else { return }
        let lastItem = numberOfItems(inSection: lastSection) - 1
        guard lastItem >= 0 else { return }
        let lastItemIndexPath = IndexPath(item: lastItem, section: lastSection)
        scrollToItem(at: lastItemIndexPath, at: scrollPosition, animated: animated)
    }
}
</code>```

Body:
I have a UICollectionView to display chat messages. At the beginning I load the existing messages to the collectionView and scroll the collectionView down to the last message with this method:

- (void)scrollToLastMessageAnimated:(BOOL)animated;
{
    if (_messages.count == 0) { return; }

    NSUInteger indexOfLastSection = _messagesBySections.count - 1;
    NSInteger indexOfMessageInLastSection = [_messagesBySections[indexOfLastSection] count] - 1;
    NSIndexPath *path = [NSIndexPath indexPathForItem:indexOfMessageInLastSection
                                            inSection:indexOfLastSection];

    [_collectionView scrollToItemAtIndexPath:path
                           atScrollPosition:UICollectionViewScrollPositionCenteredVertically
                                   animated:animated];
}

This only works animated when I call it in the viewDidAppear: method and not in viewWillAppear: method. How can I scroll down without animation?

Body:
A more foolproof solution that handles multiple/0 sections/items

extension UICollectionView {
    func scrollToLastItem(at scrollPosition: UICollectionViewScrollPosition = .centeredHorizontally, animated: Bool = true) {
        let lastSection = numberOfSections - 1
        guard lastSection >= 0 else { return }
        let lastItem = numberOfItems(inSection: lastSection) - 1
        guard lastItem >= 0 else { return }
        let lastItemIndexPath = IndexPath(item: lastItem, section: lastSection)
        scrollToItem(at: lastItemIndexPath, at: scrollPosition, animated: animated)
    }
}


问:
Removing from a list without affecting a dummy variable
```<code> from random import choice

inputs=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
func={}
code=""
z=len(inputs)
x=z-1
temp=inputs
while x>=0:
    y=choice(temp)
    print(str(x)+"   "+inputs[x]+"   "+y)
    func[inputs[x]]=y
    code=code+inputs[x]+y
    del temp[x]
    x=x-1
    print(temp)
    print(inputs)
</code>```

Why does this code not asign every element of inputs to a unique and random element of inputs(as the temp dummy set)? it seems to delete items from both temp and inputs when only told to delete items from the dummy set.

Thanks for any help.

答:
You are creating an alias of your list instead of a true copy of it:
replace temp=inputs  with   temp=inputs[:]

```<code>import random

inputs =  ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
func = {}
code = ""
z = len(inputs)
x = z-1
temp = inputs[:]    #<-- here
while x >= 0:
    y = random.choice(temp)
    print(str(x) + "   " + inputs[x] + "   " + y)
    func[inputs[x]] = y
    code = code+inputs[x] + y
    del temp[x]
    x = x - 1
    print(temp)
    print(inputs)
</code>```

Body:
 from random import choice

inputs=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
func={}
code=""
z=len(inputs)
x=z-1
temp=inputs
while x>=0:
    y=choice(temp)
    print(str(x)+"   "+inputs[x]+"   "+y)
    func[inputs[x]]=y
    code=code+inputs[x]+y
    del temp[x]
    x=x-1
    print(temp)
    print(inputs)

Why does this code not asign every element of inputs to a unique and random element of inputs(as the temp dummy set)? it seems to delete items from both temp and inputs when only told to delete items from the dummy set.

Thanks for any help.

Body:
You are creating an alias of your list instead of a true copy of it:
replace temp=inputs  with   temp=inputs[:]

import random

inputs =  ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
func = {}
code = ""
z = len(inputs)
x = z-1
temp = inputs[:]    #<-- here
while x >= 0:
    y = random.choice(temp)
    print(str(x) + "   " + inputs[x] + "   " + y)
    func[inputs[x]] = y
    code = code+inputs[x] + y
    del temp[x]
    x = x - 1
    print(temp)
    print(inputs)


问:
Application Insight on premises without Internet Access
I've to develop a WPF application in an intranet environment with no internet access for security reason. I was wondering if it's possible to collect data locally (on a server) then to FTP them or even better to have the application insight alternative installed on a Server.
Has anyone faced a similar situation and have been able to solve it?</p>

答:
You could do something like that yourself if you really needed to.  Instead of using the built in InMemoryChannel or ServerChannel classes to send telemetry, you'd create your own implementation to store them somewhere else. (or you could change the endpoint that the default channels point to to a web service inside the intranet.

you could then collect those files up and ftp them outside, and write another service to read those files and send the telemetry to app insights.  Though it seems less like a good idea given the intranet with no internet for security reasons.

Or, better yet, you could simply write internal service to parse and store all that telemetry and show it on that web service inside the intranet and use appinsights only as an sdk and schema, and don't send any of your data outside your intranet at all.

More likely: upvote adding AI to azure stack, (https://feedback.azure.com/forums/357324-application-insights/suggestions/11683746-bring-application-insights-to-azure-stack) and then get an azure stack implementation inside your intranet?  then you get all the other goodies of Azure from Azure stack as well.


问:
extension method parameter in gridview databind
I'm binding an object to a gridview. The object (LeClient) consists of several variables, two of which are related to its phone number. One variable contains a string of digits (LePhone) and the other contains an int that represents the country code (LeCountryCode). I have an extension method for strings that works to format the string LePhone and that I'd like to pass it LeCountryCode as the parameter.

So far, on RowDataBound I have an event handler with the following line:

```<code>e.Row.Cells[5].Text = (string)(e.Row.Cells[5].Text).ToPhoneFormat(1);
</code>```

I'd like to replace the 1 with the corresponding country code that's stored in the object LeClient associated with the row. How does this work? I tried

```<code>.ToPhoneFormat(e.Row.DataItem("LeCountryCode"));
</code>```

but it's not giving me the expected result.

Thanks

答:
Should be able to cast the DataItem:

```<code>.ToPhoneFormat((e.Row.DataItem as LeClient).LeCountryCode);
</code>```

Otherwise, you could add a FormattedPhoneNumber property to your LeClient object and bind to that instead.

Body:
I'm binding an object to a gridview. The object (LeClient) consists of several variables, two of which are related to its phone number. One variable contains a string of digits (LePhone) and the other contains an int that represents the country code (LeCountryCode). I have an extension method for strings that works to format the string LePhone and that I'd like to pass it LeCountryCode as the parameter.

So far, on RowDataBound I have an event handler with the following line:

e.Row.Cells[5].Text = (string)(e.Row.Cells[5].Text).ToPhoneFormat(1);

I'd like to replace the 1 with the corresponding country code that's stored in the object LeClient associated with the row. How does this work? I tried

.ToPhoneFormat(e.Row.DataItem("LeCountryCode"));

but it's not giving me the expected result.

Thanks

Body:
Should be able to cast the DataItem:

.ToPhoneFormat((e.Row.DataItem as LeClient).LeCountryCode);

Otherwise, you could add a FormattedPhoneNumber property to your LeClient object and bind to that instead.


问:
Css Change color of element by click on the other element
I have pagination
How can I change background of pagination__link with text "left" when click on the other links? It is necessary to use  only CSS.

答:
input[name="radio"]{
  display: none;
}
label{
  text-decoration: underline;
  color: blue;
}

input[name="radio"]:checked + label{
  background-color: yellow;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><ul class="pagination">
  <li class="pagination__item">
    <input type="radio" id="radio1" name="radio" />
    <label for="radio1">left</label>
    <!--

      left

    -->
  </li>
  <li class="pagination__item">
    <input type="radio" id="radio2" name="radio" />
    <label for="radio2">Page1</label>
    <!--

      Page 1

    -->
  </li>
  <li class="pagination__item pagination__item--active">
    <input type="radio" id="radio3" name="radio" />
    <label for="radio3">Page1</label>
    <!--

      Page 2

    -->
  </li>
</ul></code>```

Maybe it's not the answer what you want.

But I think it can be good hint for your problem.

You can use the checkbox trick or radio trick.

Body:
input[name="radio"]{
  display: none;
}
label{
  text-decoration: underline;
  color: blue;
}

input[name="radio"]:checked + label{
  background-color: yellow;
}

<ul class="pagination">
  <li class="pagination__item">
    <input type="radio" id="radio1" name="radio" />
    <label for="radio1">left</label>
    <!--
    <a class="pagination__link" href="#">
      left
    </a>
    -->
  </li>
  <li class="pagination__item">
    <input type="radio" id="radio2" name="radio" />
    <label for="radio2">Page1</label>
    <!--
    <a class="pagination__link" href="#">
      Page 1
    </a>
    -->
  </li>
  <li class="pagination__item pagination__item--active">
    <input type="radio" id="radio3" name="radio" />
    <label for="radio3">Page1</label>
    <!--
    <a class="pagination__link" href="#">
      Page 2
    </a>
    -->
  </li>
</ul>

Maybe it's not the answer what you want.

But I think it can be good hint for your problem.

You can use the checkbox trick or radio trick.


问:
Wait for response from api using http.post in Angular 4
So I am trying to create packages in rapid succession with a for loop. I try to do this with a for loop and a api call, this api call makes the package. My loop has to wait for the return of each call but it doesn't.

I also dont like to change my backend.service to a Promise instead of a Observable. Is it possible to do this with a Observable?

component.ts

```<code>for (let i = 0; i < this.dataArray.length; i++) {
  this.backend.createPackage(this.package, this.hasPackagePhoto, this.wantsPackageLabel).subscribe(data => {
    let d = data as any;
    this.backend.packageTrackTrace = d.package.tracktrace;
    this.backend.awsLink = d.label;
  }, error => {
    this.backend.showMessage(false, 'Foutcode 2a: Het toevoegen van een pakket is niet gelukt.');
    console.log(error);
    this.errorMsg = "Verkeerde postcode!";
  }
  );
}
</code>```

backend.service.ts

```<code>createPackage(p: Package, photo: Boolean, label: Boolean): Observable<Response> {
    const h = new Headers({ 'Content-Type': 'application/json', 'x-access-token': this.auth.getToken() });
    const options = new RequestOptions({ headers: h });

    const pt: any = {
        type: p.type,
        sender: p.sender,
        recipient: p.recipient,
        weight: p.weight,
        value: p.value,
        photo: photo,
        label: label,
        instructions: p.instructions
    };
    if (p.owner != null) {
        pt.owner = p.owner;
    }
    if (p.size != null) {
        pt.size = p.size;
    }

    return this.http.post(`${this.config.apiBase}/packages`, pt, options)
        .map((res:Response) => {
            this.newPackageCallbacks.forEach(cb => {
                cb();
            });
            return this.parseJSON(res);
        })
        .catch(this.handleError);
}
</code>```

答:
You can make your loop an observable and concatMap() to createPackage.

The callbacks might be a problem if they are slow. You might want to execute those in the outer subscribe.

Observable.from(this.dataArray)
  .concatMap(() =>
    this.backend.createPackage(this.package, this.hasPackagePhoto, this.wantsPackageLabel);
  )
  .subscribe(
    data => {

      // Execute callbacks here if they need to complete before next package
      this.backend.newPackageCallbacks.forEach(cb => {
        cb();
      });

      let d = data as any;
      this.backend.packageTrackTrace = d.package.tracktrace;
      this.backend.awsLink = d.label;
    },
    error => {
      this.backend.showMessage(false, 'Foutcode 2a: Het toevoegen van een pakket is niet gelukt.');
      console.log(error);
      this.errorMsg = "Verkeerde postcode!";
    }
   )
```

<p>To illustrate <code>concatMap()</code> vs <code>flatMap()</code>, here's some dummy code</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>console.clear()
const Observable = Rx.Observable;

// Dummy setup for testing
let counter = 0;
const backendService = {
  createThePackage: () => {
    return Observable.of('y' + counter++)
      .delay((6 - counter) * 10) // delay to resolve in order of 3, 2, 1
  }
}
const dataArray = [1,2,3]

// flatMap takes order of resolving
counter = 0;
Observable.from(dataArray)
  .flatMap(() => {
    return backendService.createThePackage();
  })
  .subscribe(x => {
    console.log('flatMap: ' + x)
  })

// concatMap takes order of creating
counter = 0;
Observable.from(dataArray)
  .concatMap(() => {
    return backendService.createThePackage();
  })
  .subscribe(x => {
    console.log('concatMap: ' + x)
  })</code>```

```

Body:
So I am trying to create packages in rapid succession with a for loop. I try to do this with a for loop and a api call, this api call makes the package. My loop has to wait for the return of each call but it doesn't.

I also dont like to change my backend.service to a Promise instead of a Observable. Is it possible to do this with a Observable?

component.ts

for (let i = 0; i < this.dataArray.length; i++) {
  this.backend.createPackage(this.package, this.hasPackagePhoto, this.wantsPackageLabel).subscribe(data => {
    let d = data as any;
    this.backend.packageTrackTrace = d.package.tracktrace;
    this.backend.awsLink = d.label;
  }, error => {
    this.backend.showMessage(false, 'Foutcode 2a: Het toevoegen van een pakket is niet gelukt.');
    console.log(error);
    this.errorMsg = "Verkeerde postcode!";
  }
  );
}

backend.service.ts

createPackage(p: Package, photo: Boolean, label: Boolean): Observable<Response> {
    const h = new Headers({ 'Content-Type': 'application/json', 'x-access-token': this.auth.getToken() });
    const options = new RequestOptions({ headers: h });

    const pt: any = {
        type: p.type,
        sender: p.sender,
        recipient: p.recipient,
        weight: p.weight,
        value: p.value,
        photo: photo,
        label: label,
        instructions: p.instructions
    };
    if (p.owner != null) {
        pt.owner = p.owner;
    }
    if (p.size != null) {
        pt.size = p.size;
    }

    return this.http.post(`${this.config.apiBase}/packages`, pt, options)
        .map((res:Response) => {
            this.newPackageCallbacks.forEach(cb => {
                cb();
            });
            return this.parseJSON(res);
        })
        .catch(this.handleError);
}

Body:
You can make your loop an observable and concatMap() to createPackage.

The callbacks might be a problem if they are slow. You might want to execute those in the outer subscribe.

Observable.from(this.dataArray)
  .concatMap(() =>
    this.backend.createPackage(this.package, this.hasPackagePhoto, this.wantsPackageLabel);
  )
  .subscribe(
    data => {

      // Execute callbacks here if they need to complete before next package
      this.backend.newPackageCallbacks.forEach(cb => {
        cb();
      });

      let d = data as any;
      this.backend.packageTrackTrace = d.package.tracktrace;
      this.backend.awsLink = d.label;
    },
    error => {
      this.backend.showMessage(false, 'Foutcode 2a: Het toevoegen van een pakket is niet gelukt.');
      console.log(error);
      this.errorMsg = "Verkeerde postcode!";
    }
   )

To illustrate concatMap() vs flatMap(), here's some dummy code

console.clear()
const Observable = Rx.Observable;

// Dummy setup for testing
let counter = 0;
const backendService = {
  createThePackage: () => {
    return Observable.of('y' + counter++)
      .delay((6 - counter) * 10) // delay to resolve in order of 3, 2, 1
  }
}
const dataArray = [1,2,3]

// flatMap takes order of resolving
counter = 0;
Observable.from(dataArray)
  .flatMap(() => {
    return backendService.createThePackage();
  })
  .subscribe(x => {
    console.log('flatMap: ' + x)
  })

// concatMap takes order of creating
counter = 0;
Observable.from(dataArray)
  .concatMap(() => {
    return backendService.createThePackage();
  })
  .subscribe(x => {
    console.log('concatMap: ' + x)
  })

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>


问:
Using threading.RLock Correctly
I'm creating a utility in Python that reads data in from a file on startup on a separate thread so that the rest of the GUI components can load. The data gets stored into a list and then appended to a combobox. How would I lock the list so that no other method can call the list at the same time it's being used by the def read_employees(self, read_file): method.

This is the best attempt I can come up with.

```<code>#left out imports

class MyDialog(wx.Frame):

    def __init__(self, parent, title):
        self.no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
        wx.Frame.__init__(self, parent, title=title, size=(500, 450),style = self.no_resize)

        self.lock = threading.RLock()
        self.empList = []

    def read_employees(self, read_file):

        with open(read_file) as f_obj:
            employees = json.load(f_obj)

        with self.lock:
            self.empList = [empEmail for empEmail in employees.keys()]
            wx.CallAfter(self.emp_selection.Append, self.empList)

    def start_read_thread(self):
        filename = 'employee.json'
        with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
            executor.submit(self.read_employees, filename)

app = wx.App(False)
frame = MyDialog(None, "Crystal Rose")
app.MainLoop()
</code>```

Is using RLock appropriate here?

答:
I don't know what else you have going on in the app, but I'd recommend taking a look at the wx.CallAfter function. It is thread-safe and can be used to send messages or post events.

```<code>import wx
from wx.lib.pubsub import Publisher
import json
from threading import Thread

def update_employee_list(read_file):
    with open(read_file) as f_obj:
        employee_list = json.load(f_obj) # this line should release the GIL so it continues other threads
    # next line sends a thread-safe message to the main event thread
    wx.CallAfter(Publisher().sendMesage, 'updateEmployeeList', employee_list)

class MyDialog(wx.Frame):
    def __init__(self, parent, title):
        self.no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
        wx.Frame.__init__(self, parent, title=title, size=(500, 450),style = self.no_resize)
        self.empList = []
        # subscribe our function to be called when 'updateEmployeeList' messages are received
        Publisher().subscribe(self.updateDisplay, 'updateEmployeeList')

    def updateDisplay(self, employee_list):
        # this assignment should be atomic and thread-safe
        self.empList = employee_list
        # wxPython GUI runs in a single thread, so this is a blocking call
        # if you have many many list items, you may want to modify this method
        # to add one employee at a time to the list to keep it non-blocking.
        self.emp_selection.Append(employee_list)

    def start_read_thread(self):
        filename = 'employee.json'
        t = Thread(target= update_employee_list, args=(filename, ))
        t.start()  # this starts the thread and immediately continues this thread's execution
</code>```

Update:

Using a with ThreadPoolExecutor blocks because the code is equivalent to:

```<code>executor = ThreadPoolExecutor(max_workers=1)
executor.submit(worker_func, args)
executor.shutdown(wait=True)  # <--- wait=True causes Executor to block until all threads complete
</code>```

You could still use the ThreadPoolExecutor as follows, without the with block. Because you're only :

```<code>executor = ThreadPoolExecutor(max_workers=1)
executor.submit(worker_func, args)
executor.shutdown(wait=False)  # <--- threads will still complete, but execution of this thread continues immediately
</code>```

For more about concurrent futures and Executors, see here for documention.

Title: Using threading.RLock Correctly

Body:
I'm creating a utility in Python that reads data in from a file on startup on a separate thread so that the rest of the GUI components can load. The data gets stored into a list and then appended to a combobox. How would I lock the list so that no other method can call the list at the same time it's being used by the def read_employees(self, read_file): method.

This is the best attempt I can come up with.

#left out imports

class MyDialog(wx.Frame):

    def __init__(self, parent, title):
        self.no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
        wx.Frame.__init__(self, parent, title=title, size=(500, 450),style = self.no_resize)

        self.lock = threading.RLock()
        self.empList = []

    def read_employees(self, read_file):

        with open(read_file) as f_obj:
            employees = json.load(f_obj)

        with self.lock:
            self.empList = [empEmail for empEmail in employees.keys()]
            wx.CallAfter(self.emp_selection.Append, self.empList)

    def start_read_thread(self):
        filename = 'employee.json'
        with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
            executor.submit(self.read_employees, filename)

app = wx.App(False)
frame = MyDialog(None, "Crystal Rose")
app.MainLoop()

Is using RLock appropriate here?

Body:
I don't know what else you have going on in the app, but I'd recommend taking a look at the wx.CallAfter function. It is thread-safe and can be used to send messages or post events.

import wx
from wx.lib.pubsub import Publisher
import json
from threading import Thread

def update_employee_list(read_file):
    with open(read_file) as f_obj:
        employee_list = json.load(f_obj) # this line should release the GIL so it continues other threads
    # next line sends a thread-safe message to the main event thread
    wx.CallAfter(Publisher().sendMesage, 'updateEmployeeList', employee_list)

class MyDialog(wx.Frame):
    def __init__(self, parent, title):
        self.no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
        wx.Frame.__init__(self, parent, title=title, size=(500, 450),style = self.no_resize)
        self.empList = []
        # subscribe our function to be called when 'updateEmployeeList' messages are received
        Publisher().subscribe(self.updateDisplay, 'updateEmployeeList')

    def updateDisplay(self, employee_list):
        # this assignment should be atomic and thread-safe
        self.empList = employee_list
        # wxPython GUI runs in a single thread, so this is a blocking call
        # if you have many many list items, you may want to modify this method
        # to add one employee at a time to the list to keep it non-blocking.
        self.emp_selection.Append(employee_list)

    def start_read_thread(self):
        filename = 'employee.json'
        t = Thread(target= update_employee_list, args=(filename, ))
        t.start()  # this starts the thread and immediately continues this thread's execution

Update:

Using a with ThreadPoolExecutor blocks because the code is equivalent to:

executor = ThreadPoolExecutor(max_workers=1)
executor.submit(worker_func, args)
executor.shutdown(wait=True)  # <--- wait=True causes Executor to block until all threads complete

You could still use the ThreadPoolExecutor as follows, without the with block. Because you're only :

executor = ThreadPoolExecutor(max_workers=1)
executor.submit(worker_func, args)
executor.shutdown(wait=False)  # <--- threads will still complete, but execution of this thread continues immediately

For more about concurrent futures and Executors, see here for documention.


问:
Dynamically assign event in javascript object
I have following javascript class:

```<code>var ImageGallery = function(arr) {
    var ImgArr = arr;
    var MainImgId = "";

    this.build = function() {
        var div = document.createElement("div");
        for (var i = 0; i < ImgArr.length; i++) {
            var img = document.createElement("img");
            img.scr = ImgArr[i];
            // what to do next, how to assign loadMainImage function ?????
            img.onclick =
            div.appendChild(img);

        }
    }

    this.loadMainImage = function(imgPath) {
        document.getElementById(MainImgId).src = imgPath;
    }
}
</code>```

next, in code I create an object of that class:

```<code>var gallery = new ImageGallery(someArrWithPaths);
gallery.MainImgId = 'idOfMainImg';
gallery.build();
</code>```

How can I assign img.onclick event to launch loadMainImage(imgPath) function every time I click on the image?

Thanks a lot!

答:
I would try to avoid using methods like onevent (in your case onclick), because it is easy to loose this handler (just writing img.onclick somewhere else will override previous handler)

try to use some javascript library (like jQuery), it will simplify your development at least a bit. And back to your question, using YUI 2 I would write so:

```<code>var imgCount = ImgArr.length; // do not use ImgArr.length in for definition, it is better
// to save it once and then use... otherwise each time in loop will look up ImgArr object to find length property
for (var i = 0; i < imgCount; i++) {
     var img = document.createElement("img");
     var src = ImgArr[i];
     img.scr = src ;
     YAHOO.util.Event.addListener(img, "click", this.loadMainImage, src, this);
}
</code>```

You can find similar function in jQuery or other frameworks. What it does:

YAHOO.util.Event.addListener(obj, event, handler, argument, context) - attach event listener to obj, for event and handler specified. argument - what to pass to that handler, and context to execute that handler (in your case it will be just this)

Doing this just don't forget to unattach this handler when you unload your page (or whatever you do), e.g.  YAHOO.util.Event.removeListener(img, "click", this.loadMainImage), or calling function which removes all listener attached (like YUI's purgeElement). Yes, things are a bit easier when you use img.onclick = ...;, seems like in this case browser will take care about it.

Body:
I have following javascript class:

var ImageGallery = function(arr) {
    var ImgArr = arr;
    var MainImgId = "";

    this.build = function() {
        var div = document.createElement("div");
        for (var i = 0; i < ImgArr.length; i++) {
            var img = document.createElement("img");
            img.scr = ImgArr[i];
            // what to do next, how to assign loadMainImage function ?????
            img.onclick =
            div.appendChild(img);

        }
    }

    this.loadMainImage = function(imgPath) {
        document.getElementById(MainImgId).src = imgPath;
    }
}

next, in code I create an object of that class:

var gallery = new ImageGallery(someArrWithPaths);
gallery.MainImgId = 'idOfMainImg';
gallery.build();

How can I assign img.onclick event to launch loadMainImage(imgPath) function every time I click on the image?

Thanks a lot!

Body:
I would try to avoid using methods like onevent (in your case onclick), because it is easy to loose this handler (just writing img.onclick somewhere else will override previous handler)

try to use some javascript library (like jQuery), it will simplify your development at least a bit. And back to your question, using YUI 2 I would write so:

var imgCount = ImgArr.length; // do not use ImgArr.length in for definition, it is better
// to save it once and then use... otherwise each time in loop will look up ImgArr object to find length property
for (var i = 0; i < imgCount; i++) {
     var img = document.createElement("img");
     var src = ImgArr[i];
     img.scr = src ;
     YAHOO.util.Event.addListener(img, "click", this.loadMainImage, src, this);
}

You can find similar function in jQuery or other frameworks. What it does:

YAHOO.util.Event.addListener(obj, event, handler, argument, context) - attach event listener to obj, for event and handler specified. argument - what to pass to that handler, and context to execute that handler (in your case it will be just this)

Doing this just don't forget to unattach this handler when you unload your page (or whatever you do), e.g.  YAHOO.util.Event.removeListener(img, "click", this.loadMainImage), or calling function which removes all listener attached (like YUI's purgeElement). Yes, things are a bit easier when you use img.onclick = ...;, seems like in this case browser will take care about it.


问:
Form built with FormBuilder is not updated after Service subscribe
My form is displayed correctly, although the data from the Service is not being applied to the form controls when this.getUser(+id); is executed and there are no errors on Development Tools console. I can see the successful HTTP request/response via Development Tool, but can't see the update in my form.

What is wrong with my code?

Component.ts

```<code>import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NotificationsService } from 'angular2-notifications';

import { UsersService } from '../../core/services/users.service';

import { User } from '../../shared/interfaces/user';

@Component({
  templateUrl: './users-form.component.html',
  styleUrls: ['./users-form.component.scss'],
    providers: [UsersService]
})
export class UsersFormComponent implements OnInit {

  userForm: FormGroup;
  user: User = {
    name: '',
    username: '',
    roleId: 3
  };

  formMode = 'Cadastro';

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private usersService: UsersService,
    private formBuilder: FormBuilder,
    private notification: NotificationsService) { }

  ngOnInit() {
    const id = this.route.snapshot.params['id'];
    this.buildForm();
    if (id) {
      this.formMode = 'Edição';
      this.getUser(+id);
    }
  }

  getUser(id: number) {
    this.usersService.getUserById(id)
      .subscribe((user: User) => {
        this.user = user;
      },
      (err) => console.log(err));
  }

  buildForm() {
    this.userForm = this.formBuilder.group({
      name: [this.user.name, Validators.required],
      username: [this.user.username, Validators.required],
      roleId: [this.user.roleId, Validators.required]
    });
  }

  submit({ value, valid }: { value: User, valid: boolean }) {

    value.id = this.user.id;

    if (value.id) {
      this.usersService.update(value)
        .subscribe((res: User) => {
          if (res) {
            this.router.navigate(['/users']);
            this.notification.success('Sucesso!', 'Registro atualizado.');
          } else {
            this.notification.error('Erro!', 'Registro não atualizado.');
          }
        },
        (err) => console.log(err));
    } else {
      this.usersService.insert(value)
        .subscribe((res: User) => {
          if (res) {
            this.router.navigate(['/users']);
            this.notification.success('Sucesso!', 'Cadastro realizado.');
          } else {
            this.notification.error('Erro!', 'Cadastro não realizado.');
          }
        },
        (err) => console.log(err));
    }
  }
}
</code>```

Component.html

```<code><div class="animated fadeIn">
  <div class="row">
    <div class="col-sm-12">
      <div class="card">
        <div class="card-header">
          <strong>Usuário</strong>
          <small>{{formMode}}</small>
        </div>
        <div class="card-block">
          <form [formGroup]="userForm" (ngSubmit)="submit(userForm)" novalidate>
            <div class="form-group">
              <label for="name">Nome</label>
              <input type="text" class="form-control" id="name" placeholder="Informe o nome" formControlName="name">
              <div class="alert alert-danger" [hidden]="userForm.controls.name">Campo Nome requerido</div>
            </div>
            <div class="form-group">
              <label for="login">Login</label>
              <input type="text" class="form-control" id="username" placeholder="Informe o login" formControlName="username">
              <div class="alert alert-danger" [hidden]="userForm.controls.username">Campo Login requerido</div>
            </div>
            <div class="form-group">
              <label for="role">Perfil</label>
              <select class="form-control" id="role" formControlName="roleId">
                <option value="1">Supervisor</option>
                <option value="2">Analista</option>
                <option value="3">Inspetor</option>
              </select>
              <div class="alert alert-danger" [hidden]="userForm.controls.roleId">Campo Perfil requerido</div>
            </div>
            <div class="form-group">
              <button class="btn btn-primary" type="submit" [disabled]="!userForm.valid">Salvar</button>
              <button [routerLink]="['/users']" class="btn btn-secondary" type="button">Cancelar</button>
            </div>
          </form>
        </div>
      </div>
    </div>
    <!--/.col-->
  </div>
  <!--/.row-->
</div>
</code>```

答:
Adding on to @joshrathke answer, the following should save you a few more lines of code.

You can choose to use .patchValue() directly:

```<code>getUser(id: number) {
  this.usersService.getUserById(id).subscribe(user => {
      this.user = user;
      this.userForm.patchValue(this.user);
    },
    (err) => console.log(err)
  );
}
</code>```

If your emission's interface from your .subscribe() method is similar to :user interface,  you can also choose to use .setValue().

```<code>getUser(id: number) {
  this.usersService.getUserById(id).subscribe(user => {
      this.user = user;
      this.userForm.setValue(this.user);
    },
    (err) => console.log(err)
  );
}
</code>```

Body:
My form is displayed correctly, although the data from the Service is not being applied to the form controls when this.getUser(+id); is executed and there are no errors on Development Tools console. I can see the successful HTTP request/response via Development Tool, but can't see the update in my form.

What is wrong with my code?

Component.ts

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NotificationsService } from 'angular2-notifications';

import { UsersService } from '../../core/services/users.service';

import { User } from '../../shared/interfaces/user';

@Component({
  templateUrl: './users-form.component.html',
  styleUrls: ['./users-form.component.scss'],
    providers: [UsersService]
})
export class UsersFormComponent implements OnInit {

  userForm: FormGroup;
  user: User = {
    name: '',
    username: '',
    roleId: 3
  };

  formMode = 'Cadastro';

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private usersService: UsersService,
    private formBuilder: FormBuilder,
    private notification: NotificationsService) { }

  ngOnInit() {
    const id = this.route.snapshot.params['id'];
    this.buildForm();
    if (id) {
      this.formMode = 'Edição';
      this.getUser(+id);
    }
  }

  getUser(id: number) {
    this.usersService.getUserById(id)
      .subscribe((user: User) => {
        this.user = user;
      },
      (err) => console.log(err));
  }

  buildForm() {
    this.userForm = this.formBuilder.group({
      name: [this.user.name, Validators.required],
      username: [this.user.username, Validators.required],
      roleId: [this.user.roleId, Validators.required]
    });
  }

  submit({ value, valid }: { value: User, valid: boolean }) {

    value.id = this.user.id;

    if (value.id) {
      this.usersService.update(value)
        .subscribe((res: User) => {
          if (res) {
            this.router.navigate(['/users']);
            this.notification.success('Sucesso!', 'Registro atualizado.');
          } else {
            this.notification.error('Erro!', 'Registro não atualizado.');
          }
        },
        (err) => console.log(err));
    } else {
      this.usersService.insert(value)
        .subscribe((res: User) => {
          if (res) {
            this.router.navigate(['/users']);
            this.notification.success('Sucesso!', 'Cadastro realizado.');
          } else {
            this.notification.error('Erro!', 'Cadastro não realizado.');
          }
        },
        (err) => console.log(err));
    }
  }
}

Component.html

          Usuário
          {{formMode}}

          <form [formGroup]="userForm" (ngSubmit)="submit(userForm)" novalidate>

              Nome
              <input type="text" class="form-control" id="name" placeholder="Informe o nome" formControlName="name">

Campo Nome requerido

              Login
              <input type="text" class="form-control" id="username" placeholder="Informe o login" formControlName="username">

Campo Login requerido

              Perfil
              <select class="form-control" id="role" formControlName="roleId">
                <option value="1">Supervisor</option>
                <option value="2">Analista</option>
                <option value="3">Inspetor</option>
              </select>

Campo Perfil requerido

              <button class="btn btn-primary" type="submit" [disabled]="!userForm.valid">Salvar</button>
              <button [routerLink]="['/users']" class="btn btn-secondary" type="button">Cancelar</button>

          </form>

Body:
Adding on to @joshrathke answer, the following should save you a few more lines of code.

You can choose to use .patchValue() directly:

getUser(id: number) {
  this.usersService.getUserById(id).subscribe(user => {
      this.user = user;
      this.userForm.patchValue(this.user);
    },
    (err) => console.log(err)
  );
}

If your emission's interface from your .subscribe() method is similar to :user interface,  you can also choose to use .setValue().

getUser(id: number) {
  this.usersService.getUserById(id).subscribe(user => {
      this.user = user;
      this.userForm.setValue(this.user);
    },
    (err) => console.log(err)
  );
}