问:
Why is numpy slower than for loop
Update: this feature is now in sciPy.stats.qmc.discrepancy and was ported to Cython and also parallelised.

I have a function using some for loops and I wanted to improve the speed using numpy. But this seems not to do the trick as the bumpy version appears to be 2 times slower. Here is the code:

```<code>import numpy as np
import itertools
import timeit

def func():
    sample = np.random.random_sample((100, 2))

    disc1 = 0
    disc2 = 0
    n_sample = len(sample)
    dim = sample.shape[1]

    for i in range(n_sample):
        prod = 1
        for k in range(dim):
            sub = np.abs(sample[i, k] - 0.5)
            prod *= 1 + 0.5 * sub - 0.5 * sub ** 2

        disc1 += prod

    for i, j in itertools.product(range(n_sample), range(n_sample)):
        prod = 1
        for k in range(dim):
            a = 0.5 * np.abs(sample[i, k] - 0.5)
            b = 0.5 * np.abs(sample[j, k] - 0.5)
            c = 0.5 * np.abs(sample[i, k] - sample[j, k])
            prod *= 1 + a + b - c
        disc2 += prod

    c2 = (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

def func_numpy():
    sample = np.random.random_sample((100, 2))

    disc1 = 0
    disc2 = 0
    n_sample = len(sample)
    dim = sample.shape[1]

    disc1 = np.sum(np.prod(1 + 0.5 * np.abs(sample - 0.5) - 0.5 * np.abs(sample - 0.5) ** 2, axis=1))

    for i, j in itertools.product(range(n_sample), range(n_sample)):
        disc2 += np.prod(1 + 0.5 * np.abs(sample[i] - 0.5) + 0.5 * np.abs(sample[j] - 0.5) - 0.5 * np.abs(sample[i] - sample[j]))

    c2 = (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

print('Normal function time: ' , timeit.repeat('func()', number=20, repeat=5, setup="from __main__ import func"))
print('numpy function time: ', timeit.repeat('func_numpy()', number=20, repeat=5, setup="from __main__ import func_numpy"))
</code>```

The timing output is:

```<code>Normal function time:  [2.831496894999873, 2.832342429959681, 2.8009242500411347, 2.8075121529982425, 2.824807019031141]
numpy function time:  [5.154757721000351, 5.2011515340418555, 5.148996959964279, 5.095560318033677, 5.125199959962629]
</code>```

What am I missing here? I know that the bottleneck is the itertools part because I have a 100x100x2 loop instead of a 100x2 loop before.
Do you see another way to do that?

答:
As I mentioned in the comments your solutions are not really optimal and it doesn't really make sense to compare not-ideal approaches.

For one thing iterating or indexing single elements of a NumPy array is really slow. I recently answered a question including a lot of details (if you're interested you might have a look at it: "convert np array to a set takes too long"). So the Python approach could be faster simply by converting the array to a list:

```<code>def func():
    sample = np.random.random_sample((100, 2))
    disc1 = 0
    n_sample = len(sample)
    dim = sample.shape[1]
    sample = sample.tolist()  # converted to list

    for i in range(n_sample):
        prod = 1
        for item in sample[i]:
            sub = abs(item - 0.5)
            prod *= 1 + 0.5 * sub - 0.5 * sub ** 2
        disc1 += prod

    disc2 = 0
    for i, j in itertools.product(range(n_sample), range(n_sample)):
        prod = 1
        for k in range(dim):
            a = 0.5 * abs(sample[i][k] - 0.5)
            b = 0.5 * abs(sample[j][k] - 0.5)
            c = 0.5 * abs(sample[i][k] - sample[j][k])
            prod *= 1 + a + b - c
        disc2 += prod

    c2 = (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2
</code>```

I also replaced the np.abs calls with normal abs. The normal abs has a lower overhead! And also changed some other parts. In the end this is more than 10-20 times faster than your original "normal" approach.

I didn't have time to check the NumPy approach yet and @Divarkar already included a really good and optimized approach. Comparing the two approaches:

```<code>def func_numpy():
    sample = np.random.random_sample((100, 2))

    disc1 = 0
    disc2 = 0
    n_sample = len(sample)
    dim = sample.shape[1]

    disc1 = np.sum(np.prod(1 +
                           0.5 * np.abs(sample - 0.5) -
                           0.5 * np.abs(sample - 0.5) ** 2,
                           axis=1))

    prod_arr = 1
    for i in range(sample.shape[1]):
        s0 = sample[:,i]
        prod_arr *= (1 +
                     0.5 * np.abs(s0[:,None] - 0.5) +
                     0.5 * np.abs(s0 - 0.5) -
                     0.5 * np.abs(s0[:,None] - s0))
    disc2 = prod_arr.sum()

    c2 = (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

print('Normal function time: ' ,
      timeit.repeat('func()', number=20, repeat=3, setup="from __main__ import func"))
# Normal function time:  [1.4846746248249474, 1.5018398493266432, 1.5476674017127152]
print('numpy function time: ',
      timeit.repeat('func_numpy()', number=20, repeat=3, setup="from __main__ import func_numpy"))
# numpy function time:  [0.020140038561976326, 0.016502230831292763, 0.016452520269695015]
</code>```

So an optimized NumPy approach can definetly beat an "optimized" Python approach. It's almost 100 times faster. In case you want it even faster you could use numba on a slightly modified version of the pure python code:

```<code>import numba as nb

@nb.njit
def func_numba():
    sample = np.random.random_sample((100, 2))
    disc1 = 0
    n_sample = len(sample)
    dim = sample.shape[1]

    for i in range(n_sample):
        prod = 1
        for item in sample[i]:
            sub = abs(item - 0.5)
            prod *= 1 + 0.5 * sub - 0.5 * sub ** 2
        disc1 += prod

    disc2 = 0
    for i in range(n_sample):
        for j in range(n_sample):
            prod = 1
            for k in range(dim):
                a = 0.5 * abs(sample[i,k] - 0.5)
                b = 0.5 * abs(sample[j,k] - 0.5)
                c = 0.5 * abs(sample[i,k] - sample[j,k])
                prod *= 1 + a + b - c
            disc2 += prod

    return (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

func_numba()

print('numba function time: ' ,
      timeit.repeat('func_numba()', number=20, repeat=3, setup="from __main__ import func_numba"))
# numba function time:  [0.003022848984983284, 0.0030429566279508435, 0.004060626777572907]
</code>```

That's almost a factor 8-10 faster than the NumPy approach.

Title: Why is numpy slower than for loop

Body:
Update: this feature is now in sciPy.stats.qmc.discrepancy and was ported to Cython and also parallelised.

I have a function using some for loops and I wanted to improve the speed using numpy. But this seems not to do the trick as the bumpy version appears to be 2 times slower. Here is the code:

import numpy as np
import itertools
import timeit

def func():
    sample = np.random.random_sample((100, 2))

    disc1 = 0
    disc2 = 0
    n_sample = len(sample)
    dim = sample.shape[1]

    for i in range(n_sample):
        prod = 1
        for k in range(dim):
            sub = np.abs(sample[i, k] - 0.5)
            prod *= 1 + 0.5 * sub - 0.5 * sub ** 2

        disc1 += prod

    for i, j in itertools.product(range(n_sample), range(n_sample)):
        prod = 1
        for k in range(dim):
            a = 0.5 * np.abs(sample[i, k] - 0.5)
            b = 0.5 * np.abs(sample[j, k] - 0.5)
            c = 0.5 * np.abs(sample[i, k] - sample[j, k])
            prod *= 1 + a + b - c
        disc2 += prod

    c2 = (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

def func_numpy():
    sample = np.random.random_sample((100, 2))

    disc1 = 0
    disc2 = 0
    n_sample = len(sample)
    dim = sample.shape[1]

    disc1 = np.sum(np.prod(1 + 0.5 * np.abs(sample - 0.5) - 0.5 * np.abs(sample - 0.5) ** 2, axis=1))

    for i, j in itertools.product(range(n_sample), range(n_sample)):
        disc2 += np.prod(1 + 0.5 * np.abs(sample[i] - 0.5) + 0.5 * np.abs(sample[j] - 0.5) - 0.5 * np.abs(sample[i] - sample[j]))

    c2 = (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

print('Normal function time: ' , timeit.repeat('func()', number=20, repeat=5, setup="from __main__ import func"))
print('numpy function time: ', timeit.repeat('func_numpy()', number=20, repeat=5, setup="from __main__ import func_numpy"))

The timing output is:

Normal function time:  [2.831496894999873, 2.832342429959681, 2.8009242500411347, 2.8075121529982425, 2.824807019031141]
numpy function time:  [5.154757721000351, 5.2011515340418555, 5.148996959964279, 5.095560318033677, 5.125199959962629]

What am I missing here? I know that the bottleneck is the itertools part because I have a 100x100x2 loop instead of a 100x2 loop before.
Do you see another way to do that?

Body:
As I mentioned in the comments your solutions are not really optimal and it doesn't really make sense to compare not-ideal approaches.

For one thing iterating or indexing single elements of a NumPy array is really slow. I recently answered a question including a lot of details (if you're interested you might have a look at it: "convert np array to a set takes too long"). So the Python approach could be faster simply by converting the array to a list:

def func():
    sample = np.random.random_sample((100, 2))
    disc1 = 0
    n_sample = len(sample)
    dim = sample.shape[1]
    sample = sample.tolist()  # converted to list

    for i in range(n_sample):
        prod = 1
        for item in sample[i]:
            sub = abs(item - 0.5)
            prod *= 1 + 0.5 * sub - 0.5 * sub ** 2
        disc1 += prod

    disc2 = 0
    for i, j in itertools.product(range(n_sample), range(n_sample)):
        prod = 1
        for k in range(dim):
            a = 0.5 * abs(sample[i][k] - 0.5)
            b = 0.5 * abs(sample[j][k] - 0.5)
            c = 0.5 * abs(sample[i][k] - sample[j][k])
            prod *= 1 + a + b - c
        disc2 += prod

    c2 = (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

I also replaced the np.abs calls with normal abs. The normal abs has a lower overhead! And also changed some other parts. In the end this is more than 10-20 times faster than your original "normal" approach.

I didn't have time to check the NumPy approach yet and @Divarkar already included a really good and optimized approach. Comparing the two approaches:

def func_numpy():
    sample = np.random.random_sample((100, 2))

    disc1 = 0
    disc2 = 0
    n_sample = len(sample)
    dim = sample.shape[1]

    disc1 = np.sum(np.prod(1 +
                           0.5 * np.abs(sample - 0.5) -
                           0.5 * np.abs(sample - 0.5) ** 2,
                           axis=1))

    prod_arr = 1
    for i in range(sample.shape[1]):
        s0 = sample[:,i]
        prod_arr *= (1 +
                     0.5 * np.abs(s0[:,None] - 0.5) +
                     0.5 * np.abs(s0 - 0.5) -
                     0.5 * np.abs(s0[:,None] - s0))
    disc2 = prod_arr.sum()

    c2 = (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

print('Normal function time: ' ,
      timeit.repeat('func()', number=20, repeat=3, setup="from __main__ import func"))
# Normal function time:  [1.4846746248249474, 1.5018398493266432, 1.5476674017127152]
print('numpy function time: ',
      timeit.repeat('func_numpy()', number=20, repeat=3, setup="from __main__ import func_numpy"))
# numpy function time:  [0.020140038561976326, 0.016502230831292763, 0.016452520269695015]

So an optimized NumPy approach can definetly beat an "optimized" Python approach. It's almost 100 times faster. In case you want it even faster you could use numba on a slightly modified version of the pure python code:

import numba as nb

@nb.njit
def func_numba():
    sample = np.random.random_sample((100, 2))
    disc1 = 0
    n_sample = len(sample)
    dim = sample.shape[1]

    for i in range(n_sample):
        prod = 1
        for item in sample[i]:
            sub = abs(item - 0.5)
            prod *= 1 + 0.5 * sub - 0.5 * sub ** 2
        disc1 += prod

    disc2 = 0
    for i in range(n_sample):
        for j in range(n_sample):
            prod = 1
            for k in range(dim):
                a = 0.5 * abs(sample[i,k] - 0.5)
                b = 0.5 * abs(sample[j,k] - 0.5)
                c = 0.5 * abs(sample[i,k] - sample[j,k])
                prod *= 1 + a + b - c
            disc2 += prod

    return (13 / 12) ** dim - 2 / n_sample * disc1 + 1 / (n_sample ** 2) * disc2

func_numba()

print('numba function time: ' ,
      timeit.repeat('func_numba()', number=20, repeat=3, setup="from __main__ import func_numba"))
# numba function time:  [0.003022848984983284, 0.0030429566279508435, 0.004060626777572907]

That's almost a factor 8-10 faster than the NumPy approach.


来源: stackexchange

问:
Elastic Beanstalk Database Pool Issue
I recently decided to switch from Heroku to deploying directly to AWS through their Elastic Beanstalk service - hope my terminology is right still figuring out AWS. I have the app running here on EB and here on Heroku (this is a free Heroku app so may take 10ish seconds to start). The app runs perfectly on Heroku, but on EB it only sometimes loads. Maybe like 1 out of 4 times, I get a Internal Server Error. My database pool it set to 5, and if I scale it up to 25 it works, but I am the only one using the website, and from what I hear 5 should be plenty.

Here is my database.yml:

```<code>development:
  adapter: sqlite3
  database: db/website.db
  pool: 5
  timeout: 5000
test:
  adapter: sqlite3
  database: db/cucumber-tests.db
  pool: 5
  timeout: 5000
production:
  adapter: postgresql
  encoding: utf8
  database: <%= ENV['RDS_DB_NAME'] %>
  username: <%= ENV['RDS_USERNAME'] %>
  password: <%= ENV['RDS_PASSWORD'] %>
  pool: 5
  host: <%= ENV['RDS_HOSTNAME'] %>
  port: <%= ENV['RDS_PORT'] %>
</code>```

Side note, after I figure out why pool 5 is not enough, how to I make the pool size scalable? From what I can tell there is not a RDS_POOL variable. Is there a way I can scale it based on the number of users?

Here is my error log for puma:

```<code>-------------------------------------
/var/log/puma/puma.log
-------------------------------------
/opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb:225:in `context'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb:220:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/nulllogger.rb:9:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/head.rb:13:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:182:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:2013:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `block in call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1787:in `synchronize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/deflater.rb:35:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/configuration.rb:232:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:578:in `handle_request'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:415:in `process_client'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:275:in `block in run'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/thread_pool.rb:120:in `block in spawn_thread'
2017-03-10 03:43:14 - ActiveRecord::ConnectionTimeoutError - could not obtain a connection from the pool within 5.000 seconds (waited 5.000 seconds); all pooled connections were i
n use:
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:202:in `block in wait_poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:193:in `loop'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:193:in `wait_poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:154:in `internal_poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:278:in `internal_poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:148:in `block in poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:158:in `synchronize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:148:in `poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:717:in `acquire_connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:490:in `checkout'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:364:in `connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:883:in `retrieve_connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_handling.rb:128:in `retrieve_connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_handling.rb:91:in `connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/associations/join_dependency.rb:96:in `initialize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/relation/finder_methods.rb:399:in `new'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/relation/finder_methods.rb:399:in `construct_join_dependency'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/relation/finder_methods.rb:321:in `exists?'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/querying.rb:3:in `exists?'
        app/views/index.erb:66:in `block in singleton class'
app/views/index.erb:-6:in `instance_eval'
        app/views/index.erb:-6:in `singleton class'
        app/views/index.erb:-8:in `__tilt_47116404404940'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/tilt-2.0.6/lib/tilt/template.rb:161:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/tilt-2.0.6/lib/tilt/template.rb:161:in `evaluate'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/tilt-2.0.6/lib/tilt/template.rb:100:in `render'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:823:in `render'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:667:in `erb'
        /var/app/current/app/controllers/application_controller.rb:60:in `block in <class:ApplicationController>'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1611:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1611:in `block in compile!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `block (3 levels) in route!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:994:in `route_eval'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `block (2 levels) in route!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1015:in `block in process_route'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1013:in `catch'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1013:in `process_route'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:973:in `block in route!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:972:in `each'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:972:in `route!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1085:in `block in dispatch!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `block in invoke'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `catch'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `invoke'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1082:in `dispatch!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:907:in `block in call!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `block in invoke'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `catch'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `invoke'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:907:in `call!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:895:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb:225:in `context'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb:220:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/nulllogger.rb:9:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/head.rb:13:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:182:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:2013:in `call'
/opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `block in call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1787:in `synchronize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/deflater.rb:35:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/configuration.rb:232:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:578:in `handle_request'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:415:in `process_client'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:275:in `block in run'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/thread_pool.rb:120:in `block in spawn_thread'
</code>```

- All the code is opensource and can be found here -

Thank you. Any help is much appreciated.

UPDATE: I can not let this app be down any longer. I am setting the pool to 25 for now. I have also changed the DSN so the old app can be found here, and the new app here

UPDATE 2: I am adding the ruby-on-rails tag to gain more traction since this issue is related, but the project is using Sinatra not Rails.

答:
It looks like you're using Puma—a threaded web server. Puma starts multiple ruby threads in one process to handle requests concurrently. The number of threads puma is creating might be higher than the number of database connections you have in your pool (defined in database.yml).

ActiveRecord naturally keeps a pool of database connections open and creates new connections lazily. Your database.yml looks like you have the max pool size set to 5. This means ActiveRecord will not create more than 5 connections in the pool and will only create a new connection when the pool is empty and a connection is asked for.

I couldn't find a puma config in your repository, so I'll assume puma is using the defaults. The default max threads for Puma is 16. This might indicate your webserver has 16 threads running (worst-case scenario) and every thread after the 5th is waiting for a connection to be returned to the pool to use. That's 5 connections shared amongst your 16 threads. As a best practice, I always make sure the database pool size is n+1 where n is the maximum number of threads that will run in my application.

I cannot guess why the issue does not also exist in heroku.

ContentLicense: CC BY-SA 3.0

Title: Elastic Beanstalk Database Pool Issue

Body:
I recently decided to switch from Heroku to deploying directly to AWS through their Elastic Beanstalk service - hope my terminology is right still figuring out AWS. I have the app running here on EB and here on Heroku (this is a free Heroku app so may take 10ish seconds to start). The app runs perfectly on Heroku, but on EB it only sometimes loads. Maybe like 1 out of 4 times, I get a Internal Server Error. My database pool it set to 5, and if I scale it up to 25 it works, but I am the only one using the website, and from what I hear 5 should be plenty.

Here is my database.yml:

development:
  adapter: sqlite3
  database: db/website.db
  pool: 5
  timeout: 5000
test:
  adapter: sqlite3
  database: db/cucumber-tests.db
  pool: 5
  timeout: 5000
production:
  adapter: postgresql
  encoding: utf8
  database: <%= ENV['RDS_DB_NAME'] %>
  username: <%= ENV['RDS_USERNAME'] %>
  password: <%= ENV['RDS_PASSWORD'] %>
  pool: 5
  host: <%= ENV['RDS_HOSTNAME'] %>
  port: <%= ENV['RDS_PORT'] %>

Side note, after I figure out why pool 5 is not enough, how to I make the pool size scalable? From what I can tell there is not a RDS_POOL variable. Is there a way I can scale it based on the number of users?

Here is my error log for puma:

-------------------------------------
/var/log/puma/puma.log
-------------------------------------
/opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb:225:in `context'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb:220:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/nulllogger.rb:9:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/head.rb:13:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:182:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:2013:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `block in call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1787:in `synchronize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/deflater.rb:35:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/configuration.rb:232:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:578:in `handle_request'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:415:in `process_client'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:275:in `block in run'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/thread_pool.rb:120:in `block in spawn_thread'
2017-03-10 03:43:14 - ActiveRecord::ConnectionTimeoutError - could not obtain a connection from the pool within 5.000 seconds (waited 5.000 seconds); all pooled connections were i
n use:
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:202:in `block in wait_poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:193:in `loop'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:193:in `wait_poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:154:in `internal_poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:278:in `internal_poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:148:in `block in poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:158:in `synchronize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:148:in `poll'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:717:in `acquire_connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:490:in `checkout'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:364:in `connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:883:in `retrieve_connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_handling.rb:128:in `retrieve_connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_handling.rb:91:in `connection'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/associations/join_dependency.rb:96:in `initialize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/relation/finder_methods.rb:399:in `new'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/relation/finder_methods.rb:399:in `construct_join_dependency'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/relation/finder_methods.rb:321:in `exists?'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.2/lib/active_record/querying.rb:3:in `exists?'
        app/views/index.erb:66:in `block in singleton class'
app/views/index.erb:-6:in `instance_eval'
        app/views/index.erb:-6:in `singleton class'
        app/views/index.erb:-8:in `__tilt_47116404404940'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/tilt-2.0.6/lib/tilt/template.rb:161:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/tilt-2.0.6/lib/tilt/template.rb:161:in `evaluate'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/tilt-2.0.6/lib/tilt/template.rb:100:in `render'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:823:in `render'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:667:in `erb'
        /var/app/current/app/controllers/application_controller.rb:60:in `block in <class:ApplicationController>'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1611:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1611:in `block in compile!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `block (3 levels) in route!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:994:in `route_eval'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `block (2 levels) in route!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1015:in `block in process_route'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1013:in `catch'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1013:in `process_route'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:973:in `block in route!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:972:in `each'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:972:in `route!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1085:in `block in dispatch!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `block in invoke'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `catch'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `invoke'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1082:in `dispatch!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:907:in `block in call!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `block in invoke'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `catch'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `invoke'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:907:in `call!'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:895:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb:225:in `context'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb:220:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/nulllogger.rb:9:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/head.rb:13:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:182:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:2013:in `call'
/opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `block in call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1787:in `synchronize'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/rack-1.6.5/lib/rack/deflater.rb:35:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/configuration.rb:232:in `call'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:578:in `handle_request'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:415:in `process_client'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/server.rb:275:in `block in run'
        /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/puma-3.7.1/lib/puma/thread_pool.rb:120:in `block in spawn_thread'

- All the code is opensource and can be found here -

Thank you. Any help is much appreciated.

UPDATE: I can not let this app be down any longer. I am setting the pool to 25 for now. I have also changed the DSN so the old app can be found here, and the new app here

UPDATE 2: I am adding the ruby-on-rails tag to gain more traction since this issue is related, but the project is using Sinatra not Rails.


问:
Check if date is free with SQL query
I need to check if the time that I'm choosing is free.
So as example the time that is between 17:00 - 17:06 is taken and I try to take time that is between 17:01 - 17:07
What would be the right SQL query to check if time is free or taken? Because in this situation 17:01,17:02,17:03 times are taken.

In database I have two fields laikas that means the start of the time that is taken(17:00), and laikas_end that means the end of taken time(17:07)

As far I got these queries:
To check if the time that I'm taking isn'bt between that time that is taken

```<code>$uzimtumas_laiko = "SELECT * FROM reklamos WHERE `laikas` >= '$laikas' AND `laikas_end` <= '$laikas_end'";
</code>```

To check if the start time and end time matches (that means it is taken):

```<code>$uzimtumas_laiko = "SELECT * FROM reklamos WHERE `laikas` = '$laikas' OR `laikas_end` = '$laikas_end'";
</code>```

The situation can be that I try to take time between 16:49 - 17:02, but 17:00 - 17:06 is taken. So 17:50-17:02 can't be chosen. I belive that I need something with BETWEEN but can't think out anything.

答:
Maybe this might help you out</p>

```<code>"SELECT count(*) as COUNT FROM leave where ((start_date >= to_date(:start_date) and start_date <= to_date(:end_date)) OR (to_date(:start_date) >= start_date and to_date(:start_date) <= end_date)) "
</code>```

Title: Check if date is free with SQL query

Body:
I need to check if the time that I'm choosing is free.
So as example the time that is between 17:00 - 17:06 is taken and I try to take time that is between 17:01 - 17:07
What would be the right SQL query to check if time is free or taken? Because in this situation 17:01,17:02,17:03 times are taken.

In database I have two fields laikas that means the start of the time that is taken(17:00), and laikas_end that means the end of taken time(17:07)

As far I got these queries:
To check if the time that I'm taking isn'bt between that time that is taken

$uzimtumas_laiko = "SELECT * FROM reklamos WHERE `laikas` >= '$laikas' AND `laikas_end` <= '$laikas_end'";

To check if the start time and end time matches (that means it is taken):

$uzimtumas_laiko = "SELECT * FROM reklamos WHERE `laikas` = '$laikas' OR `laikas_end` = '$laikas_end'";

The situation can be that I try to take time between 16:49 - 17:02, but 17:00 - 17:06 is taken. So 17:50-17:02 can't be chosen. I belive that I need something with BETWEEN but can't think out anything.

Body:
Maybe this might help you out

"SELECT count(*) as COUNT FROM leave where ((start_date >= to_date(:start_date) and start_date <= to_date(:end_date)) OR (to_date(:start_date) >= start_date and to_date(:start_date) <= end_date)) "


问:
Substring a sum
I want to substring my string but don't know how.

What I want is this:

```<code>10
10
*
</code>```

(this depends on the user input)

What I currently have as output is this:

```<code>10
10
</code>```

So I am missing the *, i am testing this with a teststring and it looks like this:

```<code>String test= "10;*;10";
System.out.println(test.substring(test.lastIndexOf(";") + 1));
System.out.println(test.substring(0, test.indexOf(";")));
</code>```

How do I fix that the String test is getting several substrings and get the output 10 - * - 10?

答:
You can use the split function from the string class.</p>

```<code>String test = "10;*;10";
String splits[] = test.split(";");

for (String split : splits) {
    System.out.println(split);
}
</code>```

Title: Substring a sum

Body:
I want to substring my string but don't know how.

What I want is this:

10
10
*

(this depends on the user input)

What I currently have as output is this:

10
10

So I am missing the *, i am testing this with a teststring and it looks like this:

String test= "10;*;10";
System.out.println(test.substring(test.lastIndexOf(";") + 1));
System.out.println(test.substring(0, test.indexOf(";")));

How do I fix that the String test is getting several substrings and get the output 10 - * - 10?

Body:
You can use the split function from the string class.

String test = "10;*;10";
String splits[] = test.split(";");

for (String split : splits) {
    System.out.println(split);
}


问:
PHP set value of id
I have some text containing variable data.

```<code>My age is: <span class="var" id="age">54</span> and my name is <span class="var" id="name">Matt</span>
</code>```

If no url paramater is set then the page uses 54 which is correct, however if I set age in the url such as ?age=20 then I would like the age to be set to 20.

The text is from the database and is set to a variable called $content.

Not a duplicate. The text comes from the database and only needs to be replaced is a url param is set

答:
Since you have a "condition" for the age to be displayed, therefore you will have to use PHP if else to check the date. Below is the code that you can use along with the explanation.

Assuming that the below is the string what you get from your db field.

```<code>$fetched_string = '<p> My Smith from <span class="var" id="town">Manchester, aged, <span >class="var" id="age">54</span>';
</code>```

Now you have to extract the age, which is always in between id="age"> and

The best way to do this is by creating a PHP function for this.

```<code>function str_between($string, $searchStart, $searchEnd, $offset = 0) {
        $startPosition = strpos($string, $searchStart, $offset);
        if ($startPosition !== false) {
            $searchStartLength = strlen($searchStart);
            $endPosition = strpos($string, $searchEnd, $startPosition + 1);
            if ($endPosition !== false) {
                return substr($string, $startPosition + $searchStartLength, $endPosition - $searchStartLength);
            }
            return substr($string, $startPosition + $searchStartLength);
        }
        return $string;
    }
</code>```

Now you simply have to pass the string values on the left (which will be the searchStart) and the right (searchEnd) of the fetched age. Below is the code to do this.

```<code>$fetched_age = str_between($fetched_string, 'id="age">', '</span>');
</code>```

Based on this, I have revised the final code that you can use as is.

```<code>//To get the data from a URL, $_GET method is used. First you will check if the "age" has been set in the URL or not. This is done by:

function str_between($string, $searchStart, $searchEnd, $offset = 0) {
    $startPosition = strpos($string, $searchStart, $offset);

    if ($startPosition !== false) {
        $searchStartLength = strlen($searchStart);
        $endPosition = strpos($string, $searchEnd, $startPosition + 1);

        if ($endPosition !== false) {
            return substr($string, $startPosition + $searchStartLength, $endPosition - $searchStartLength);
        }

        return substr($string, $startPosition + $searchStartLength);
    }

    return $string;
}

//Fetched String for db
$fetched_string = $row['full_string'];

//This will give you the age
$fetched_age = str_between($fetched_string, 'id="age">', '</span>');

if (isset($_GET['age'])) {
    //If age is set in the URL, assign it to the PHP Variable
    $age_display = $_GET['age'];
}
else {
    //If age is not set, then assign the age fetched from the db.
    $age_display = $fetched_age;
}
</code>```

Is this what you are looking for?

Title: PHP set value of id

Body:
I have some text containing variable data.

My age is: 54 and my name is Matt

If no url paramater is set then the page uses 54 which is correct, however if I set age in the url such as ?age=20 then I would like the age to be set to 20.

The text is from the database and is set to a variable called $content.

Not a duplicate. The text comes from the database and only needs to be replaced is a url param is set

Body:
Since you have a "condition" for the age to be displayed, therefore you will have to use PHP if else to check the date. Below is the code that you can use along with the explanation.

Assuming that the below is the string what you get from your db field.

$fetched_string = '<p> My Smith from <span class="var" id="town">Manchester, aged, <span >class="var" id="age">54</span>';

Now you have to extract the age, which is always in between id="age"> and </span>

The best way to do this is by creating a PHP function for this.

function str_between($string, $searchStart, $searchEnd, $offset = 0) {
        $startPosition = strpos($string, $searchStart, $offset);
        if ($startPosition !== false) {
            $searchStartLength = strlen($searchStart);
            $endPosition = strpos($string, $searchEnd, $startPosition + 1);
            if ($endPosition !== false) {
                return substr($string, $startPosition + $searchStartLength, $endPosition - $searchStartLength);
            }
            return substr($string, $startPosition + $searchStartLength);
        }
        return $string;
    }

Now you simply have to pass the string values on the left (which will be the searchStart) and the right (searchEnd) of the fetched age. Below is the code to do this.

$fetched_age = str_between($fetched_string, 'id="age">', '</span>');

Based on this, I have revised the final code that you can use as is.

//To get the data from a URL, $_GET method is used. First you will check if the "age" has been set in the URL or not. This is done by:

function str_between($string, $searchStart, $searchEnd, $offset = 0) {
    $startPosition = strpos($string, $searchStart, $offset);

    if ($startPosition !== false) {
        $searchStartLength = strlen($searchStart);
        $endPosition = strpos($string, $searchEnd, $startPosition + 1);

        if ($endPosition !== false) {
            return substr($string, $startPosition + $searchStartLength, $endPosition - $searchStartLength);
        }

        return substr($string, $startPosition + $searchStartLength);
    }

    return $string;
}

//Fetched String for db
$fetched_string = $row['full_string'];

//This will give you the age
$fetched_age = str_between($fetched_string, 'id="age">', '</span>');

if (isset($_GET['age'])) {
    //If age is set in the URL, assign it to the PHP Variable
    $age_display = $_GET['age'];
}
else {
    //If age is not set, then assign the age fetched from the db.
    $age_display = $fetched_age;
}

Is this what you are looking for?


问:
Is it possible to fix the number of threads and dispatch the task when there is idle one?
I want to use OpenMP to attain this effect: fix the number of threads, if there is an idle thread, dispatch the task into it, else wait for an idle one. The following is my test code:

```<code>#include <omp.h>
#include <stdio.h>
#include <unistd.h>

void func(void) {
    #pragma omp parallel for
    for (int i = 0; i < 3; i++)
    {
        sleep(30);
        printf("%d\n", omp_get_thread_num());
    }
}

int main(void) {
    omp_set_nested(1);
    omp_set_num_threads(omp_get_num_procs());
    #pragma omp parallel for
    for (int i = 0; i < 8; i++)
    {
        printf("%d\n", omp_get_thread_num());
        func();
    }

    return 0;
}
</code>```

Actually, my machine contains 24 cores, so

```<code>omp_set_num_threads(omp_get_num_procs())
</code>```

will launch 24 threads at the beginning. Then main's for-loop will occupy 8 threads, during every thread, a func will be called, therefore additonal 2 threads ought to be used. From my calculation, I think 24 threads will be enough. But in actual running, there are totally 208 threads generated.

So my questions are as follows:

(1) Why so many threads are created though 24 seems enough?

(2) Is it possible to fix the number of threads (E.g., same as the number of cores) and dispatch the task when there is idle one?

答:
you should try

```<code>#pragma omp task
</code>```

besides, in my opinion, avoid using nested omp threads.

Body:
I want to use OpenMP to attain this effect: fix the number of threads, if there is an idle thread, dispatch the task into it, else wait for an idle one. The following is my test code:

#include <omp.h>
#include <stdio.h>
#include <unistd.h>

void func(void) {
    #pragma omp parallel for
    for (int i = 0; i < 3; i++)
    {
        sleep(30);
        printf("%d\n", omp_get_thread_num());
    }
}

int main(void) {
    omp_set_nested(1);
    omp_set_num_threads(omp_get_num_procs());
    #pragma omp parallel for
    for (int i = 0; i < 8; i++)
    {
        printf("%d\n", omp_get_thread_num());
        func();
    }

    return 0;
}

Actually, my machine contains 24 cores, so

omp_set_num_threads(omp_get_num_procs())

will launch 24 threads at the beginning. Then main's for-loop will occupy 8 threads, during every thread, a func will be called, therefore additonal 2 threads ought to be used. From my calculation, I think 24 threads will be enough. But in actual running, there are totally 208 threads generated.

So my questions are as follows:

(1) Why so many threads are created though 24 seems enough?

(2) Is it possible to fix the number of threads (E.g., same as the number of cores) and dispatch the task when there is idle one?

Body:
you should try

#pragma omp task

besides, in my opinion, avoid using nested omp threads.


问:
PyQt Threading: GUI interaction Crashes Program
I am designing a program to edit DICOMs. Specifically, I am having issues appropriately interacting with my PyQt UI.

I want to be able to click on a "pause" and on a "stop" button to either pause or stop my editing function. My editing function takes a significant amount of time to process / loop through. Depending on the number of files that it is editing, it can take anywhere from 30 seconds to over an hour. Because of this, I decided to throw my editing function into its own thread using the native threading capabilities of Qt. I was able to get the thread working ie: from my MainWindow class I can click a button that initializes my editing class (class edit(QThread), however interacting with the GUI still crashes the program and I'm not sure why! Below I have added a sample of the general code structure / set up that I am using.

```<code>class anonymizeThread(QThread):
    def __init__(self):
        QThread.__init__(self)

    def __del__(self):
        self.wait()

    #def sendAnon(self, progress_val):
     #   self.completed = 0
      #  return self.completed

    def run(self):
            # while self.completed < 100:
            #     self.completed += 0.00001
            #     self.emit(QtCore.SIGNAL('PROGRESS'), self.completed)
            # ANONYMIZE FUNCTION!
            i = 0
            #flag = self.stop_flag
            while i < 10000000: # and self.stop_flag is not 1:
                print(i)
                i+=1
            print('i didnt enter the loop')

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

        # connect the buttons
        self.worker = anonymizeThread()
        self.anonbtn.clicked.connect(self.anonymize)
        self.open_directory.clicked.connect(self.open_dir)
        self.pause.clicked.connect(self.paused)
        self.stopbtn.clicked.connect(self.stopped)

        # block button signals to start
        self.pause.blockSignals(True)
        self.stopbtn.blockSignals(True)

        self.dir_name = None
        self.pause_flag = None
        self.stop_flag = None
        self.anon_flag = None

        # This is how we quit from the main menu "File" option
        extractAction = self.actionQuit_Ctrl_Q
        extractAction.setShortcut("Ctrl+Q")
        extractAction.setStatusTip('Leave The App')
        extractAction.triggered.connect(self.close_application)

    def updateProgressBar(self,val):
        self.progressBar.setValue(val)
    def close_application(self):
        choice = QMessageBox.question(self, 'Just had to check...', "Are you sure you want to exit?", QMessageBox.Yes | QMessageBox.No)
        if choice == QMessageBox.Yes:
            sys.exit()
        else:
            pass

    def anonymize(self):
        self.pause.blockSignals(False)
        self.stopbtn.blockSignals(False)
        self.worker.start()
        # check if directory chosen
        # self.progressBar.setMaximum(len(dcm)
        # start our anon thread!

    def paused(self):
        #only if running
        if self.pause_flag is 0:
            self.pause_flag = 1
            self.pause.setText('Start')
        elif self.pause_flag is 1:
            self.pause_flag = 0
            self.pause.setText('Pause')
        else:
            pass

    def stopped(self): # need a self.stop() for anonThread

        choice = QMessageBox.question(self,'Stop', "Are you sure you want to stop? You will not be able to pick up exactly where you left off.",
                              QMessageBox.Yes | QMessageBox.No)
        if choice == QMessageBox.Yes:
            self.stop_flag = 1
            #self.stopbtn.blockSignals(True)
            #self.paused.blockSignals(True)
        else:
            pass

    def open_dir(self):
        self.dir_name = str(QFileDialog.getExistingDirectory(self, "Select Directory"))
        if len(self.dir_name) is not 0:
            self.anon_flag = 0

def main():
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
</code>```

答:
Thanks to @eyllansec and @ekhumoro..

In the above code, all instances of self.stop_flag = ... should have been self.worker.stop_flag = ... as it is changing the variable that is to be used in the worker class/thread. My mistake was assuming both classes inherited the same "self".

If there are other errors and or better explanations of what I did incorrectly, please do post an answer and I'll accept it!

Body:
I am designing a program to edit DICOMs. Specifically, I am having issues appropriately interacting with my PyQt UI.

I want to be able to click on a "pause" and on a "stop" button to either pause or stop my editing function. My editing function takes a significant amount of time to process / loop through. Depending on the number of files that it is editing, it can take anywhere from 30 seconds to over an hour. Because of this, I decided to throw my editing function into its own thread using the native threading capabilities of Qt. I was able to get the thread working ie: from my MainWindow class I can click a button that initializes my editing class (class edit(QThread), however interacting with the GUI still crashes the program and I'm not sure why! Below I have added a sample of the general code structure / set up that I am using.

class anonymizeThread(QThread):
    def __init__(self):
        QThread.__init__(self)

    def __del__(self):
        self.wait()

    #def sendAnon(self, progress_val):
     #   self.completed = 0
      #  return self.completed

    def run(self):
            # while self.completed < 100:
            #     self.completed += 0.00001
            #     self.emit(QtCore.SIGNAL('PROGRESS'), self.completed)
            # ANONYMIZE FUNCTION!
            i = 0
            #flag = self.stop_flag
            while i < 10000000: # and self.stop_flag is not 1:
                print(i)
                i+=1
            print('i didnt enter the loop')

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

        # connect the buttons
        self.worker = anonymizeThread()
        self.anonbtn.clicked.connect(self.anonymize)
        self.open_directory.clicked.connect(self.open_dir)
        self.pause.clicked.connect(self.paused)
        self.stopbtn.clicked.connect(self.stopped)

        # block button signals to start
        self.pause.blockSignals(True)
        self.stopbtn.blockSignals(True)

        self.dir_name = None
        self.pause_flag = None
        self.stop_flag = None
        self.anon_flag = None

        # This is how we quit from the main menu "File" option
        extractAction = self.actionQuit_Ctrl_Q
        extractAction.setShortcut("Ctrl+Q")
        extractAction.setStatusTip('Leave The App')
        extractAction.triggered.connect(self.close_application)

    def updateProgressBar(self,val):
        self.progressBar.setValue(val)
    def close_application(self):
        choice = QMessageBox.question(self, 'Just had to check...', "Are you sure you want to exit?", QMessageBox.Yes | QMessageBox.No)
        if choice == QMessageBox.Yes:
            sys.exit()
        else:
            pass

    def anonymize(self):
        self.pause.blockSignals(False)
        self.stopbtn.blockSignals(False)
        self.worker.start()
        # check if directory chosen
        # self.progressBar.setMaximum(len(dcm)
        # start our anon thread!

    def paused(self):
        #only if running
        if self.pause_flag is 0:
            self.pause_flag = 1
            self.pause.setText('Start')
        elif self.pause_flag is 1:
            self.pause_flag = 0
            self.pause.setText('Pause')
        else:
            pass

    def stopped(self): # need a self.stop() for anonThread

        choice = QMessageBox.question(self,'Stop', "Are you sure you want to stop? You will not be able to pick up exactly where you left off.",
                              QMessageBox.Yes | QMessageBox.No)
        if choice == QMessageBox.Yes:
            self.stop_flag = 1
            #self.stopbtn.blockSignals(True)
            #self.paused.blockSignals(True)
        else:
            pass

    def open_dir(self):
        self.dir_name = str(QFileDialog.getExistingDirectory(self, "Select Directory"))
        if len(self.dir_name) is not 0:
            self.anon_flag = 0

def main():
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()


问:
what does for_write_seq_lis do?
I am debugging a Fortran 90 program with valgrind. I get errors having this in the trace

```<code>==93929== Use of uninitialised value of size 4
==93929==    at 0x7C3D4B: for__add_to_lf_table
==93929==    by 0x8014A8: for__open_proc.
==93929==    by 0x7C7B0F: for__open_default
==93929==    by 0x7F3648: for_write_seq_lis
<rest of my application backtrace>
</code>```

And I don't understand if it's my mistake or simply a quirk of the internal library. I'd like to know what these functions do, and any other relevant information.

I am compiling with ifort (IFORT) 11.1 20100806, valgrind 3.6.0 on macosx.

Edit: I was able to spot occurrences of valgrind errors when the associated(ptr) intrinsic is used, or when print * is used. In any case, I am just curious to know what those routines are responsible for. What's an lf table ?

答:
My guess would be that the symbols with names beginning for_  are defined in the run-time libraries that the program uses, probably ones provided with the Intel compiler.  I expect you figured that out for yourself Stefano.  What they do is obscure, other than the obvious: implement various operations of Fortran.

What have you done to track down the origins of the error which makes valgrind complain that you have used an uninitialised value ?  Did you try compiling with the option -check uninit ?  Have you tried the Intel source checker on the code ?

EDIT: Aha.  One of the peculiarities of Fortran is that between the time it is declared and the time it is first associated with a target, a pointer does not have an association status.  It is neither associated nor not associated, and calls to ASSOCIATED may produce odd results; according to the standard they should not, for example, return either .true. or .false..  This may be the source of your problem, though the other symptoms you report do not point this way.

ContentLicense: CC BY-SA 2.5

Title: what does for_write_seq_lis do?

Body:
I am debugging a Fortran 90 program with valgrind. I get errors having this in the trace

==93929== Use of uninitialised value of size 4
==93929==    at 0x7C3D4B: for__add_to_lf_table
==93929==    by 0x8014A8: for__open_proc.
==93929==    by 0x7C7B0F: for__open_default
==93929==    by 0x7F3648: for_write_seq_lis
<rest of my application backtrace>

And I don't understand if it's my mistake or simply a quirk of the internal library. I'd like to know what these functions do, and any other relevant information.

I am compiling with ifort (IFORT) 11.1 20100806, valgrind 3.6.0 on macosx.

Edit: I was able to spot occurrences of valgrind errors when the associated(ptr) intrinsic is used, or when print * is used. In any case, I am just curious to know what those routines are responsible for. What's an lf table ?


问:
Fetch API to force download file
I'm calling an API to download excel file from the server using the fetch API but it didn't force the browser to download, below is my header response:

HTTP/1.1 200 OK Content-Length: 168667
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Server: Microsoft-IIS/8.5
Content-Disposition: attachment; filename=test.xlsx
Access-Control-Allow-Origin: http://localhost:9000
Access-Control-Allow-Credentials: true
Access-Control-Request-Method: POST,GET,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: X-Requested-With,Accept,Content-Type,Origin
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Wed, 24 May 2017 20:18:04 GMT
```
<p>Below my code that I'm using to call the API :</p>
```this.httpClient.fetch(url, {
    method: 'POST',
    body: JSON.stringify(object),
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    }
})
```

答:
The browser won't show the usual interaction for the download (display Save As... dialog, etc.), only if you navigate to that resource. It is easier to show the difference with an example:

window.location='http://mycompany.com/'

Load http://mycompany.com/ via XHR/Fetch in the background.

In 1., the browser will load the page and display its content. In 2., the browser will load the raw data and return it to you, but you have to display it yourself.

You have to do something similar with files. You have the raw data, but you have to "display" it yourself. To do this, you need to create an object-URL for your downloaded file and navigate to it:

```<code>this.httpClient
    .fetch(url, {method, body, headers})
    .then(response => response.blob())
    .then(blob => URL.createObjectURL(blob))
    .then(url => {
        window.open(url, '_blank');
        URL.revokeObjectURL(url);
    });
</code>```

This fetches the response, reads it as a blob, creates an objectURL, opens it (in a new tab), then revokes the URL.

More about object-URLs:
https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL

ContentLicense: CC BY-SA 4.0

Title: Fetch API to force download file

Body:
I'm calling an API to download excel file from the server using the fetch API but it didn't force the browser to download, below is my header response:

HTTP/1.1 200 OK Content-Length: 168667
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Server: Microsoft-IIS/8.5
Content-Disposition: attachment; filename=test.xlsx
Access-Control-Allow-Origin: http://localhost:9000
Access-Control-Allow-Credentials: true
Access-Control-Request-Method: POST,GET,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: X-Requested-With,Accept,Content-Type,Origin
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Wed, 24 May 2017 20:18:04 GMT

Below my code that I'm using to call the API :

this.httpClient.fetch(url, {
    method: 'POST',
    body: JSON.stringify(object),
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    }
})

Body:
The browser won't show the usual interaction for the download (display Save As... dialog, etc.), only if you navigate to that resource. It is easier to show the difference with an example:

window.location='http://mycompany.com/'

Load http://mycompany.com/ via XHR/Fetch in the background.

In 1., the browser will load the page and display its content. In 2., the browser will load the raw data and return it to you, but you have to display it yourself.

You have to do something similar with files. You have the raw data, but you have to "display" it yourself. To do this, you need to create an object-URL for your downloaded file and navigate to it:

this.httpClient
    .fetch(url, {method, body, headers})
    .then(response => response.blob())
    .then(blob => URL.createObjectURL(blob))
    .then(url => {
        window.open(url, '_blank');
        URL.revokeObjectURL(url);
    });

This fetches the response, reads it as a blob, creates an objectURL, opens it (in a new tab), then revokes the URL.

More about object-URLs:
https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL


问:
Process multiple variables in bash loop
I have 4 lists of variables like this:

```<code>YEAR1="2008 2008 2009"
YEAR2="2008 2009 2009"
MONTH1="11 12 01"
MONTH2="12 01 02"
</code>```

I want to pipe them through to a Python script in a way that the first items from all 4 lists are input first, then the second items from each list and so on. I believe I need to use a WHILE loop for this, but mine doesn't work. I don't get an error message either.

```<code>while read $YEAR1 $YEAR2 $MONTH1 $MONTH2;do
    python python-code.py "$YEAR1" "$MONTH1" "$YEAR2" "$MONTH2"
done
</code>```

My Python script is tested and works, I'm just not getting my head around bash scripting.

答:
Here's another solution that works with any number of columns/fields…</p>

```<code># Any number of values works
YEAR1="2008 2008 2009 2010 2011"
YEAR2="2008 2009 2009 2011 20012"
MONTH1="11 12 01 09 03"
MONTH2="12 01 02 06 07"

NUM_COLS=5

for i in $(seq 1 $NUM_COLS)  # iterate each column/field
do
  # Dynamically set field specifiers y1, y2, m1, m2
  y1=$i y2=$((i+NUM_COLS)) m1=$((i+NUM_COLS*2)) m2=$((i+NUM_COLS*3))

  # Select the 4 fields, passing in concatenated data  on one line
  cut -d ' ' -f $y1,$y2,$m1,$m2 <<< "${YEAR1} ${YEAR2} ${MONTH1} ${MONTH2}"
done
</code>```

Title: Process multiple variables in bash loop

Body:
I have 4 lists of variables like this:

YEAR1="2008 2008 2009"
YEAR2="2008 2009 2009"
MONTH1="11 12 01"
MONTH2="12 01 02"

I want to pipe them through to a Python script in a way that the first items from all 4 lists are input first, then the second items from each list and so on. I believe I need to use a WHILE loop for this, but mine doesn't work. I don't get an error message either.

while read $YEAR1 $YEAR2 $MONTH1 $MONTH2;do
    python python-code.py "$YEAR1" "$MONTH1" "$YEAR2" "$MONTH2"
done

My Python script is tested and works, I'm just not getting my head around bash scripting.

Body:
Here's another solution that works with any number of columns/fields…

# Any number of values works
YEAR1="2008 2008 2009 2010 2011"
YEAR2="2008 2009 2009 2011 20012"
MONTH1="11 12 01 09 03"
MONTH2="12 01 02 06 07"

NUM_COLS=5

for i in $(seq 1 $NUM_COLS)  # iterate each column/field
do
  # Dynamically set field specifiers y1, y2, m1, m2
  y1=$i y2=$((i+NUM_COLS)) m1=$((i+NUM_COLS*2)) m2=$((i+NUM_COLS*3))

  # Select the 4 fields, passing in concatenated data  on one line
  cut -d ' ' -f $y1,$y2,$m1,$m2 <<< "${YEAR1} ${YEAR2} ${MONTH1} ${MONTH2}"
done


问:
How do I right justify numbers with decimal points using Python 3.6
I am looking for a way to right justify the numbers in the output so all the decimal points line up, Using Python 3.6.1.

The general format I am using is:

```<code>print('Bonus: $',format(bonus, ',.2f'),sep='')
</code>```

but I cannot figure out how to get the numbers to right justify and keep the currency format.  Here's a pic of output:

答:
Chaining string formatters works:

```<code>>>> "Cash Money: %10s" % "$%.2f" % 6.124
'Cash Money:      $6.12'
</code>```

The first one adds the symbol & formats the number, the second pads it to the proper length.

Used in a more realistic way:

```<code>str_bal = "$%.2f" % bal
print "Balance: %20s" % str_bal
</code>```

A real world example:

I've build a report which intelligently resizes via mixing format strings:

```<code>format_string = "%-9s %-{}s %6.3f%% (%{}i/%{}i) total events: %{}i".format(
                 max_len_key, max_len_pos, max_len_total, max_len_events)
for entry in table:
    ...
    print format_string % (title, key, percent, pos, total, event)
</code>```

which outputs:

```<code>Version:  1.0.0.0  2.688% (10/372) total events: 150
Version:  1.4.1.15 0.000% ( 0/181) total events:  73
</code>```

Note: you can do this without mixing formatters, but I think this ends up clearer than the abomination "%%-9s %%-%is %%6.3f%%%% (%%%ii/%%%ii) total events: %%%ii" (which is the valid replacement for the first format string).

Body:
I am looking for a way to right justify the numbers in the output so all the decimal points line up, Using Python 3.6.1.

The general format I am using is:

print('Bonus: $',format(bonus, ',.2f'),sep='')

but I cannot figure out how to get the numbers to right justify and keep the currency format.  Here's a pic of output:

Body:
Chaining string formatters works:

>>> "Cash Money: %10s" % "$%.2f" % 6.124
'Cash Money:      $6.12'

The first one adds the symbol & formats the number, the second pads it to the proper length.

Used in a more realistic way:

str_bal = "$%.2f" % bal
print "Balance: %20s" % str_bal

A real world example:

I've build a report which intelligently resizes via mixing format strings:

format_string = "%-9s %-{}s %6.3f%% (%{}i/%{}i) total events: %{}i".format(
                 max_len_key, max_len_pos, max_len_total, max_len_events)
for entry in table:
    ...
    print format_string % (title, key, percent, pos, total, event)

which outputs:

Version:  1.0.0.0  2.688% (10/372) total events: 150
Version:  1.4.1.15 0.000% ( 0/181) total events:  73

Note: you can do this without mixing formatters, but I think this ends up clearer than the abomination "%%-9s %%-%is %%6.3f%%%% (%%%ii/%%%ii) total events: %%%ii" (which is the valid replacement for the first format string).


答:
If your start time or end time is in chosen range, so can't chosen:</p>

```<code>$uzimtumas_laiko = "SELECT * FROM reklamos WHERE (`laikas` BETWEEN '$laikas' AND '$laikas_end') OR (`laikas_end` BETWEEN '$laikas' AND '$laikas_end') OR (`laikas` >= '$laikas' AND `laikas` <= '$laikas_end' ) OR  (`laikas_end` >= '$laikas' AND `laikas_end` <= '$laikas_end' )";
</code>```

Title: Check if date is free with SQL query

Body:
If your start time or end time is in chosen range, so can't chosen:

$uzimtumas_laiko = "SELECT * FROM reklamos WHERE (`laikas` BETWEEN '$laikas' AND '$laikas_end') OR (`laikas_end` BETWEEN '$laikas' AND '$laikas_end') OR (`laikas` >= '$laikas' AND `laikas` <= '$laikas_end' ) OR  (`laikas_end` >= '$laikas' AND `laikas_end` <= '$laikas_end' )";


问:
Zend framework 1.12 validator error
I'm getting an error with the StringLength validator in Zend Framework 1.12. The error is:

plugin by name StringLength was not found in the registry;used
  paths:Zend_Validate_:Zend/Validate/

My form is:

```<code><?php

class Application_Form_Public_Registrazione_Registra extends App_Form_Abstract
{

    //definisco la variabile per la connessione al database
    protected $_publicModel;

    public function init()
    {
        $this->_publicModel = new Application_Model_Public();
        $this->setMethod('post');
        $this->setName('registra');
        $this->setAction(''); //vuota in quanto si genera nel Controller

        //per la gestione degli elementi di tipo file
        $this->setAttrib('enctype', 'multipart/form-data');

        //elemento grafico relativo al nome
        $this->addElement('text', 'nome', array(
            'label'       => 'Nome',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', true, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci il tuo nome',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo al cognome
        $this->addElement('text', 'cognome', array(
            'label'       => 'Cognome',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', true, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci il tuo cognome',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo al sesso
        $this->addElement('select', 'sesso', array(
            'label'        => 'Sesso',
            'multiOptions' => array('1' => 'M', '0' => 'F'), //1=maschio, 0=femmina
            'decorators'   => $this->elementDecorators,
        ));

        //elemento grafico relativo all' etá
        $this->addElement('text', 'eta', array(
            'label'       => 'Etá',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', false, array(3, 20))), //false perché non deve proseguire se non é soddisfatto
            'required'    => true,
            'description' => 'Inserisci il tuo cognome',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo al numero di telefono
        $this->addElement('text', 'telefono', array(
            'label'       => 'Telefono',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', false, array(3, 20))), //false perché non deve proseguire se non é soddisfatto
            'required'    => true,
            'description' => 'Inserisci il tuo numero di telefono',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo all'indirizzo
        $this->addElement('text', 'indirizzo', array(
            'label'       => 'Indirizzo',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', false, array(3, 20))), //false perché non deve proseguire se non é soddisfatto
            'required'    => true,
            'description' => 'Inserisci il tuo indirizzo',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo alla cittá
        $this->addElement('text', 'citta', array(
            'label'       => 'Città',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', false, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci la tua città',
            'decorators'  => $this->elementDecorators,
        ));

        // elemento grafico relativo alla email
        $this->addElement('text', 'email', array(
            'label'      => 'La tua Email',
            'required'   => true,
            'filters'    => array('StringTrim'),
            'decorators' => $this->elementDecorators,
            'validators' => array(
                'EmailAddress',
            )
        ));

        //elemento grafico relativo all'username
        $this->addElement('text', 'username', array(
            'label'       => 'Username',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', true, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci il tuo username scelto',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo alla password
        $this->addElement('text', 'password', array(
            'label'       => 'Password',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', true, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci la tua password scelta',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo alla foto profilo
        $this->addElement('file', 'foto', array(
            'label'       => 'Immagine',
            'destination' => APPLICATION_PATH . '/../public/images/fotoutenti',
            'validators'  => array(
                array('Count', false, 1),
                array('Size', false, 202400), //9 mb per l'img
                array('Extension', false, array('jpg', 'gif'))),
            'decorators'  => $this->fileDecorators,
        ));

        //elemento grafico relativo al bottone conferma
        $this->addElement('submit', 'registrati', array(
            'label'      => 'Conferma e Registrati',
            'decorators' => $this->buttonDecorators,
        ));

        //setto i decorators
        $this->setDecorators(array(
            'FormElements',
            array('HtmlTag', array('tag' => 'table', 'class' => 'zend_form')),
            array('Description', array('placement' => 'prepend', 'class' => 'formerror')),
            'Form'
        ));

    }
}
</code>```

Thanks for help!

答: I think you misspelled the StringLength validator name. You wrote: StringLenght, which really doesn't exists.

Title: Zend framework 1.12 validator error

Body:
I'm getting an error with the StringLength validator in Zend Framework 1.12. The error is:

plugin by name StringLength was not found in the registry;used
  paths:Zend_Validate_:Zend/Validate/

My form is:

<?php

class Application_Form_Public_Registrazione_Registra extends App_Form_Abstract
{

    //definisco la variabile per la connessione al database
    protected $_publicModel;

    public function init()
    {
        $this->_publicModel = new Application_Model_Public();
        $this->setMethod('post');
        $this->setName('registra');
        $this->setAction(''); //vuota in quanto si genera nel Controller

        //per la gestione degli elementi di tipo file
        $this->setAttrib('enctype', 'multipart/form-data');

        //elemento grafico relativo al nome
        $this->addElement('text', 'nome', array(
            'label'       => 'Nome',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', true, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci il tuo nome',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo al cognome
        $this->addElement('text', 'cognome', array(
            'label'       => 'Cognome',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', true, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci il tuo cognome',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo al sesso
        $this->addElement('select', 'sesso', array(
            'label'        => 'Sesso',
            'multiOptions' => array('1' => 'M', '0' => 'F'), //1=maschio, 0=femmina
            'decorators'   => $this->elementDecorators,
        ));

        //elemento grafico relativo all' etá
        $this->addElement('text', 'eta', array(
            'label'       => 'Etá',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', false, array(3, 20))), //false perché non deve proseguire se non é soddisfatto
            'required'    => true,
            'description' => 'Inserisci il tuo cognome',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo al numero di telefono
        $this->addElement('text', 'telefono', array(
            'label'       => 'Telefono',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', false, array(3, 20))), //false perché non deve proseguire se non é soddisfatto
            'required'    => true,
            'description' => 'Inserisci il tuo numero di telefono',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo all'indirizzo
        $this->addElement('text', 'indirizzo', array(
            'label'       => 'Indirizzo',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', false, array(3, 20))), //false perché non deve proseguire se non é soddisfatto
            'required'    => true,
            'description' => 'Inserisci il tuo indirizzo',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo alla cittá
        $this->addElement('text', 'citta', array(
            'label'       => 'Città',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', false, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci la tua città',
            'decorators'  => $this->elementDecorators,
        ));

        // elemento grafico relativo alla email
        $this->addElement('text', 'email', array(
            'label'      => 'La tua Email',
            'required'   => true,
            'filters'    => array('StringTrim'),
            'decorators' => $this->elementDecorators,
            'validators' => array(
                'EmailAddress',
            )
        ));

        //elemento grafico relativo all'username
        $this->addElement('text', 'username', array(
            'label'       => 'Username',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', true, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci il tuo username scelto',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo alla password
        $this->addElement('text', 'password', array(
            'label'       => 'Password',
            'filters'     => array('StringTrim'),
            'validators'  => array(array('StringLenght', true, array(3, 20))),
            'required'    => true,
            'description' => 'Inserisci la tua password scelta',
            'decorators'  => $this->elementDecorators,
        ));

        //elemento grafico relativo alla foto profilo
        $this->addElement('file', 'foto', array(
            'label'       => 'Immagine',
            'destination' => APPLICATION_PATH . '/../public/images/fotoutenti',
            'validators'  => array(
                array('Count', false, 1),
                array('Size', false, 202400), //9 mb per l'img
                array('Extension', false, array('jpg', 'gif'))),
            'decorators'  => $this->fileDecorators,
        ));

        //elemento grafico relativo al bottone conferma
        $this->addElement('submit', 'registrati', array(
            'label'      => 'Conferma e Registrati',
            'decorators' => $this->buttonDecorators,
        ));

        //setto i decorators
        $this->setDecorators(array(
            'FormElements',
            array('HtmlTag', array('tag' => 'table', 'class' => 'zend_form')),
            array('Description', array('placement' => 'prepend', 'class' => 'formerror')),
            'Form'
        ));

    }
}

Thanks for help!


问:
Filter a list by pattern matching
How can I filter a list, keeping the items that match a pattern, removing ones that don't?

For example, if I have a list of lists, I would like a function...

```<code>singleItemLists :: [[Int]] -> [[Int]]
</code>```

... to remove all items that don't match the pattern [x].

Ideally, answers should be fairly straightforward to convert to other patterns.

答:
The idiomatic version based on explicit pattern matching and filter is:

```<code>{-# LANGUAGE LambdaCase #-}

isSingleton :: [x] -> Bool
isSingleton = \case [_] -> True ; _ -> False;

singletonLists :: [[x]] -> [[x]]
singletonLists = filter isSingleton
</code>```

I believe this is more readable. As an added advantage, we get isSingleton, which can be reused for other purposes.

isSingleton is lazy in the spine and elements of the inner lists.

Title: Filter a list by pattern matching

Body:
How can I filter a list, keeping the items that match a pattern, removing ones that don't?

For example, if I have a list of lists, I would like a function...

singleItemLists :: [[Int]] -> [[Int]]

... to remove all items that don't match the pattern [x].

Ideally, answers should be fairly straightforward to convert to other patterns.

Body:
The idiomatic version based on explicit pattern matching and filter is:

{-# LANGUAGE LambdaCase #-}

isSingleton :: [x] -> Bool
isSingleton = \case [_] -> True ; _ -> False;

singletonLists :: [[x]] -> [[x]]
singletonLists = filter isSingleton

I believe this is more readable. As an added advantage, we get isSingleton, which can be reused for other purposes.

isSingleton is lazy in the spine and elements of the inner lists.


问:
hiding elements after a button is clicked - angular2 - ngFor
I am still learning Angular2 and I currently can't find a solution for my problem. I am displaying 1-3 Tiers/Packages using the ngFor, which than looks like this tiers in display mode.
After I click the edit button I only want the clicked element to go into edit mode, currently all of them switch into edit mode, which looks like this tiers in edit mode.

Here is the code, reduced it to the relevant parts.

```<code><h1 class="page-title"><span class="fw-semi-bold">Packages</span></h1>
<div class="row">
  <div class="col-md-4" *ngFor="let tier of tiers; let i=index;">
    <!-- Show Mode -->
    <ul [hidden]="editMode" class="pricing-table">
      <li class="plan-name">
        {{ tier.title }} {{i}}
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <p class="plan-price">{{ tier.price }}</p>
      <li class="plan-action">
        <a class="btn btn-primary" (click)="this.onEdit()">Edit</a>
        <a class="btn btn-success" (click)="this.clickSave()">SaveYes</a>
        <a class="btn btn-warning" >Get</a>
      </li>
    </ul>
    <!-- Edit Mode -->
    <ul [hidden]="!editMode" class="pricing-table-edit">
      <li class="plan-name-edit">
        <input type="text" class="form-control" style=" font-size: 3rem;" placeholder="{{ tier.title }} " formControlName="package_name">

      </li>
      <li >
        <div class="rewards-edit" style="background-color: #3a3d46; ">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <div style="align:center; padding-left: 40%; padding-right: 40%;"><input type="text" id="package_price1" class="form-control plan-price" placeholder="4,99" formControlName="package_price"></div>

      <li class="plan-action">
        <a class="btn btn-primary">Edit</a>
        <a class="btn btn-success">Save</a>
        <a class="btn btn-warning">Publish</a>
      </li>
    </ul>
  </div>
</code>```

Components-File:

```<code>export class PackagesComponent {
  editMode = false;

  onEdit () {
    this.editMode = true;
  }
}
</code>```

Is there a way to use the index variable in my method, so that I know which of the 3 tiers is currently clicked? Or are there any other solutions or maybe ideas?

Thanks a lot :)

UPDATED CODE, thanks to Abrar:

```<code>export class PackagesComponent {  //this has to be renamed to TierComponent for less confusion
  public tierToEdit: Tier;
  editMode = false;
  tiers: Tier[] = [
    new Tier(
      10,
      'First Tier',
      [
        {id: 500, title: 'desc', description: 'crazy description'},
        {id: 501, title: 'desc', description: 'crazy description'},
        {id: 502, title: 'desc', description: 'crazy description'},
        {id: 503, title: 'desc', description: 'crazy description'}
      ],
      5.00),
      *[more code..]*
  ]

  constructor (private tierService: TierService) {}

  ngOnInit() {
  }

  onEdit (tier: Tier) {
    this.editMode = true;
    this.tierToEdit = tier;
  }
</code>```

Template-File:

```<code><h1 class="page-title"><span class="fw-semi-bold">Packages</span></h1>
<div class="row">
  <div class="col-md-4" *ngFor="let tier of tiers; let i=index;">
    <!-- Show Mode -->
    <ul *ngIf="!editMode || tierToEdit != tier" class="pricing-table">
      <li class="plan-name">
        {{ tier.title }} {{i}}
      </li>
     <li class="plan-name">
        {{ tier.title }} {{i}}
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <p class="plan-price">{{ tier.price }}</p>
      <li class="plan-action">
        <a class="btn btn-primary" (click)="onEdit(tier)">Edit</a>
        <a class="btn btn-success" (click)="this.clickSave()">SaveYes</a>
        <a class="btn btn-warning" >Get</a>
      </li>
    </ul>
    <!-- Edit Mode -->
    <ul *ngIf="editMode && tierToEdit == tier " class="pricing-table-edit">
      <li class="plan-name-edit">
        <input type="text" class="form-control" style=" font-size: 3rem;" placeholder="{{ tier.title }} " formControlName="package_name">

      </li>
      <li >
        <div class="rewards-edit" style="background-color: #3a3d46; ">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <div style="align:center; padding-left: 40%; padding-right: 40%;"><input type="text" id="package_price1" class="form-control plan-price" placeholder="4,99" formControlName="package_price"></div>

      <li class="plan-action">
        <a class="btn btn-primary">Edit</a>
        <a class="btn btn-success">Save</a>
        <a class="btn btn-warning">Publish</a>
      </li>
    </ul>
  </div>
</code>```

答: I would assign an ID to the section and in each section trigger its own editMode in ID instead of using the "this" class descriptor.</p>

Body:
I am still learning Angular2 and I currently can't find a solution for my problem. I am displaying 1-3 Tiers/Packages using the ngFor, which than looks like this tiers in display mode.
After I click the edit button I only want the clicked element to go into edit mode, currently all of them switch into edit mode, which looks like this tiers in edit mode.

Here is the code, reduced it to the relevant parts.

Packages

        {{ tier.title }} {{i}}

        description

        description

        description

        description

{{ tier.price }}

        Edit
        SaveYes
        Get

        <input type="text" class="form-control" style=" font-size: 3rem;" placeholder="{{ tier.title }} " formControlName="package_name">

Feature 1

Feature 1

Feature 1

Feature 1

<input type="text" id="package_price1" class="form-control plan-price" placeholder="4,99" formControlName="package_price">

        Edit
        Save
        Publish

Components-File:

export class PackagesComponent {
  editMode = false;

  onEdit () {
    this.editMode = true;
  }
}

Is there a way to use the index variable in my method, so that I know which of the 3 tiers is currently clicked? Or are there any other solutions or maybe ideas?

Thanks a lot :)

UPDATED CODE, thanks to Abrar:

export class PackagesComponent {  //this has to be renamed to TierComponent for less confusion
  public tierToEdit: Tier;
  editMode = false;
  tiers: Tier[] = [
    new Tier(
      10,
      'First Tier',
      [
        {id: 500, title: 'desc', description: 'crazy description'},
        {id: 501, title: 'desc', description: 'crazy description'},
        {id: 502, title: 'desc', description: 'crazy description'},
        {id: 503, title: 'desc', description: 'crazy description'}
      ],
      5.00),
      *[more code..]*
  ]

  constructor (private tierService: TierService) {}

  ngOnInit() {
  }

  onEdit (tier: Tier) {
    this.editMode = true;
    this.tierToEdit = tier;
  }

Template-File:

Packages

        {{ tier.title }} {{i}}

        {{ tier.title }} {{i}}

        description

        description

        description

        description

{{ tier.price }}

        Edit
        SaveYes
        Get

        <input type="text" class="form-control" style=" font-size: 3rem;" placeholder="{{ tier.title }} " formControlName="package_name">

Feature 1

Feature 1

Feature 1

Feature 1

<input type="text" id="package_price1" class="form-control plan-price" placeholder="4,99" formControlName="package_price">

        Edit
        Save
        Publish