问:
HTML Email Styling Issue
I have the current HTML email template to go out automagically to end user.

But the email that arrives seems to be formatted incorrectly..

Here is HTML code I have:

You've been sent a job opportunity

%EMAIL_YOUR_EMAIL% thought you might be interested the following role, currently being advertised on #

%EMAIL_POST_TITLE% advertised by %EMAIL_POST_AUTHOR%

%EMAIL_POST_CONTENT%

© %EMAIL_BLOG_NAME%, 2017

```

Which should include a grey background behind the email. But when recipient receives the email it doesn't include the grey background.. o_O

Here is an image showing the issue I'm facing

Does anyone have any ideas / can help? :)

答:
Try to include everything in a table with your preferred background color and not in a div.

From this article: https://www.arclab.com/en/amlc/how-to-change-background-color-html-newsletter.html

How to change the Background Color of a Message?

Locate the body tag and add/change the background color: e.g.  The color code is HEX #RRGGBB.

Many templates use a background table, because some clients are cutting out the body tag. Make sure you change the color for the background table, too.

Hello World!

```

Title: HTML Email Styling Issue

Body:
I have the current HTML email template to go out automagically to end user.

But the email that arrives seems to be formatted incorrectly..

Here is HTML code I have:

You've been sent a job opportunity

%EMAIL_YOUR_EMAIL% thought you might be interested the following role, currently being advertised on #

%EMAIL_POST_TITLE% advertised by %EMAIL_POST_AUTHOR%

%EMAIL_POST_CONTENT%

© %EMAIL_BLOG_NAME%, 2017

Which should include a grey background behind the email. But when recipient receives the email it doesn't include the grey background.. o_O

Here is an image showing the issue I'm facing

Does anyone have any ideas / can help? :)

Body:
Try to include everything in a table with your preferred background color and not in a div.

From this article: https://www.arclab.com/en/amlc/how-to-change-background-color-html-newsletter.html

How to change the Background Color of a Message?

Locate the body tag and add/change the background color: e.g. <body bgcolor="#FF0000"> The color code is HEX #RRGGBB.

Many templates use a background table, because some clients are cutting out the body tag. Make sure you change the color for the background table, too.

<body bgcolor="#eeeeef" leftmargin="0" marginheight="0" marginwidth="0" offset="0" topmargin="0">
<!-- background table -->
<table bgcolor="#eeeeef" id="bgtable" align="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%">
    <tr>
        <td align="center" valign="top">
            <!-- container 600px -->
            <table border="0" cellpadding="0" cellspacing="0" class="container" width="600">
                <tr>
                    <td align="left">
                        <p>Hello World!</p>
                    </td>
                </tr>
            </table>
            <!-- container 600px -->
        </td>
    </tr>
</table>
<!-- background table -->
</body>


来源: stackexchange

问:
bundle exec - You have already activated json X, but your Gemfile requires json Y
Trying to execute jekyll on cygwin (x64) on Windows when I get this error in spite of using bundle exec prefix.

Shouldn’t the dependency defined in the Gemfile (i.e. 1.8.6) be activated when executing?

Any thoughts on what is going wrong here? I am totally new to the world of Ruby gems.  I have looked at other "You have already activated .. " posts showing similar messages but the answers there didn’t solve my problem.

$ bundle exec jekyll serve

```<code>$ bundle exec jekyll serve
/cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:40:in
 `block in setup': You have already activated json 2.0.2, but your Gemfile requires json 1.8.6.
 Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
</code>```

Environment

Cygwin x86_64 installed on Windows 7

RVM installed on Cygwin

```<code>$ rvm -v
rvm 1.29.0 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io/]

$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-cygwin]
</code>```

Gemfile - for the jekyll project

```<code>source 'https://rubygems.org'

require 'json'
require 'open-uri'
versions = JSON.parse(open('https://pages.github.com/versions.json').read)

gem 'github-pages', group: :jekyll_plugins
gem 'json', '~> 1.8.0'
</code>```

$ gem environment

```<code>$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.6.10
  - RUBY VERSION: 2.4.0 (2016-12-24 patchlevel 0) [x86_64-cygwin]
  - INSTALLATION DIRECTORY: /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0
  - USER INSTALLATION DIRECTORY: /cygdrive/c/Users/mochapenguin/.gem/ruby/2.4.0
  - RUBY EXECUTABLE: /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/bin/ruby.exe
  - EXECUTABLE DIRECTORY: /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/bin
  - SPEC CACHE DIRECTORY: /cygdrive/c/Users/mochapenguin/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/etc
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-cygwin
  - GEM PATHS:
     - /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0
     - /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0@global
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/bin
     - /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0@global/bin
     - /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/bin
     - /usr/local/bin
     - /usr/bin
     - /cygdrive/c/Windows/system32
     - /cygdrive/c/Windows
     - /cygdrive/c/Windows/System32/Wbem
     - /cygdrive/c/Windows/System32/WindowsPowerShell/v1.0
     - /cygdrive/c/Program Files/Java/jdk1.8.0_121/bin
     ..... snip .....
     - /cygdrive/c/Users/mochapenguin/AppData/Local/atom/bin
     - /usr/lib/lapack
     - /cygdrive/c/Users/mochapenguin/.rvm/bin
</code>```

bundle update

```<code>$ bundle update
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/..
Fetching dependency metadata from https://rubygems.org/.
Resolving dependencies...
Using i18n 0.8.1
Using json 1.8.6
Using minitest 5.10.1
Using thread_safe 0.3.6
Using public_suffix 2.0.5
Using coffee-script-source 1.12.2
Using execjs 2.7.0
Using colorator 1.1.0
Using ffi 1.9.18
Using multipart-post 2.0.0
Using forwardable-extended 2.6.0
Using gemoji 3.0.0
Using net-dns 0.8.0
Using sass 3.4.23
Using rb-fsevent 0.9.8
Using kramdown 1.13.2
Using liquid 3.0.6
Using mercenary 0.3.6
Using rouge 1.11.1
Using safe_yaml 1.0.4
Using mini_portile2 2.1.0
Using jekyll-paginate 1.1.0
Using jekyll-swiss 0.4.0
Using minima 2.0.0
Using unicode-display_width 1.1.3
Using bundler 1.14.6
Using tzinfo 1.2.3
Using addressable 2.5.0
Using coffee-script 2.4.1
Using ethon 0.10.1
Using rb-inotify 0.9.8
Using faraday 0.11.0
Using pathutil 0.14.0
Using jekyll-sass-converter 1.5.0
Using nokogiri 1.7.1
Using terminal-table 1.7.3
Using activesupport 4.2.7
Using jekyll-coffeescript 1.0.1
Using typhoeus 0.8.0
Using listen 3.0.6
Using sawyer 0.8.1
Using html-pipeline 2.5.0
Using jekyll-watch 1.5.0
Using octokit 4.6.2
Using jekyll 3.4.3
Using github-pages-health-check 1.3.3
Using jekyll-gist 1.4.0
Using jekyll-avatar 0.4.2
Using jekyll-default-layout 0.1.4
Using jekyll-feed 0.9.2
Using jekyll-github-metadata 2.3.1
Using jekyll-mentions 1.2.0
Using jekyll-optional-front-matter 0.1.2
Using jekyll-readme-index 0.1.0
Using jekyll-redirect-from 0.12.1
Using jekyll-relative-links 0.4.0
Using jekyll-seo-tag 2.1.0
Using jekyll-sitemap 1.0.0
Using jekyll-theme-architect 0.0.3
Using jekyll-theme-cayman 0.0.3
Using jekyll-theme-dinky 0.0.3
Using jekyll-theme-hacker 0.0.3
Using jekyll-theme-leap-day 0.0.3
Using jekyll-theme-merlot 0.0.3
Using jekyll-theme-midnight 0.0.3
Using jekyll-theme-minimal 0.0.3
Using jekyll-theme-modernist 0.0.3
Using jekyll-theme-primer 0.1.7
Using jekyll-theme-slate 0.0.3
Using jekyll-theme-tactile 0.0.3
Using jekyll-theme-time-machine 0.0.3
Using jekyll-titles-from-headings 0.1.5
Using jemoji 0.8.0
Using github-pages 132
Bundle updated!
</code>```

bundle exec - Full error message

```<code>$ bundle exec jekyll serve
/cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:40:in `block in setup': You have already activated json 2.0.2, but your Gemfile requires json 1.8.6. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
        from /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/forwardable.rb:228:in `each'
        from /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/forwardable.rb:228:in `each'
        from /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:25:in `map'
        from /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:25:in `setup'
        from /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler.rb:100:in `setup'
        from /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/setup.rb:10:in `<top (required)>'
        from /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
</code>```

json gems

```<code>$ gem list json

*** LOCAL GEMS ***
json (default: 2.0.2, 1.8.6)
</code>```

bundle show json

```<code>$ bundle show json
/cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/json-1.8.6
</code>```

Can't uninstall a default gem

```<code>$ gem uninstall json -v2.0.2
ERROR:  While executing gem ... (Gem::InstallError)
    gem "json" cannot be uninstalled because it is a default gem
</code>```

UPDATE - 12-Apr-2017

I don't know what the issue is still, but I trimmed down the Gemfile to this and it doesn't fall in a heap. Maybe it somehow works when those particular version dependencies are not enforced.

```<code>source 'https://rubygems.org'

# sample suggested [here](https://jekyllrb.com/docs/github-pages/) and in github help
gem 'github-pages', group: :jekyll_plugins
</code>```

UPDATE - 21-Apr-2017

This issue with bundler and system gems is highlighted at Gem Versioning and Bundler - Doing it right

Bundler's sandbox relies on its ability to be present at the very beginning of the Ruby process, and to therefore have the ability to ensure that the versions of all loaded libraries will reflect the ones listed in the Gemfile.lock. By running a system executable, you are executing Ruby code before Bundler can modify the load path and replace the normal Rubygems loading mechanism, allowing arbitrary unmanaged gems to get loaded into memory. Once that happens, all bets are off.

This is what seems to be happening in this situation.

But, as mentioned above - can't uninstall the system json 2.0.2 gem.

答:
I had the same problem yesterday. I am not an expert but the following worked for me:

I created a new website with Jekyll using:

```<code>$ jekyll new "name_site"
</code>```

I then copied the new GemFile and GemFile.lock from the new folder to the older (where you have a problem). Then, you run:

```<code>$ jekyll serve
</code>```

in the folder of your current website and it should work. Let me know if it works for you!

ContentLicense: CC BY-SA 3.0

Body:
Trying to execute jekyll on cygwin (x64) on Windows when I get this error in spite of using bundle exec prefix.

Shouldn’t the dependency defined in the Gemfile (i.e. 1.8.6) be activated when executing?

Any thoughts on what is going wrong here? I am totally new to the world of Ruby gems.  I have looked at other "You have already activated .. " posts showing similar messages but the answers there didn’t solve my problem.

$ bundle exec jekyll serve

$ bundle exec jekyll serve
/cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:40:in
 `block in setup': You have already activated json 2.0.2, but your Gemfile requires json 1.8.6.
 Prepending `bundle exec` to your command may solve this. (Gem::LoadError)

Environment

Cygwin x86_64 installed on Windows 7

RVM installed on Cygwin

$ rvm -v
rvm 1.29.0 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io/]

$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-cygwin]

Gemfile - for the jekyll project

source 'https://rubygems.org'

require 'json'
require 'open-uri'
versions = JSON.parse(open('https://pages.github.com/versions.json').read)

gem 'github-pages', group: :jekyll_plugins
gem 'json', '~> 1.8.0'

$ gem environment

$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.6.10
  - RUBY VERSION: 2.4.0 (2016-12-24 patchlevel 0) [x86_64-cygwin]
  - INSTALLATION DIRECTORY: /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0
  - USER INSTALLATION DIRECTORY: /cygdrive/c/Users/mochapenguin/.gem/ruby/2.4.0
  - RUBY EXECUTABLE: /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/bin/ruby.exe
  - EXECUTABLE DIRECTORY: /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/bin
  - SPEC CACHE DIRECTORY: /cygdrive/c/Users/mochapenguin/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/etc
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-cygwin
  - GEM PATHS:
     - /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0
     - /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0@global
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/bin
     - /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0@global/bin
     - /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/bin
     - /usr/local/bin
     - /usr/bin
     - /cygdrive/c/Windows/system32
     - /cygdrive/c/Windows
     - /cygdrive/c/Windows/System32/Wbem
     - /cygdrive/c/Windows/System32/WindowsPowerShell/v1.0
     - /cygdrive/c/Program Files/Java/jdk1.8.0_121/bin
     ..... snip .....
     - /cygdrive/c/Users/mochapenguin/AppData/Local/atom/bin
     - /usr/lib/lapack
     - /cygdrive/c/Users/mochapenguin/.rvm/bin

bundle update

$ bundle update
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/..
Fetching dependency metadata from https://rubygems.org/.
Resolving dependencies...
Using i18n 0.8.1
Using json 1.8.6
Using minitest 5.10.1
Using thread_safe 0.3.6
Using public_suffix 2.0.5
Using coffee-script-source 1.12.2
Using execjs 2.7.0
Using colorator 1.1.0
Using ffi 1.9.18
Using multipart-post 2.0.0
Using forwardable-extended 2.6.0
Using gemoji 3.0.0
Using net-dns 0.8.0
Using sass 3.4.23
Using rb-fsevent 0.9.8
Using kramdown 1.13.2
Using liquid 3.0.6
Using mercenary 0.3.6
Using rouge 1.11.1
Using safe_yaml 1.0.4
Using mini_portile2 2.1.0
Using jekyll-paginate 1.1.0
Using jekyll-swiss 0.4.0
Using minima 2.0.0
Using unicode-display_width 1.1.3
Using bundler 1.14.6
Using tzinfo 1.2.3
Using addressable 2.5.0
Using coffee-script 2.4.1
Using ethon 0.10.1
Using rb-inotify 0.9.8
Using faraday 0.11.0
Using pathutil 0.14.0
Using jekyll-sass-converter 1.5.0
Using nokogiri 1.7.1
Using terminal-table 1.7.3
Using activesupport 4.2.7
Using jekyll-coffeescript 1.0.1
Using typhoeus 0.8.0
Using listen 3.0.6
Using sawyer 0.8.1
Using html-pipeline 2.5.0
Using jekyll-watch 1.5.0
Using octokit 4.6.2
Using jekyll 3.4.3
Using github-pages-health-check 1.3.3
Using jekyll-gist 1.4.0
Using jekyll-avatar 0.4.2
Using jekyll-default-layout 0.1.4
Using jekyll-feed 0.9.2
Using jekyll-github-metadata 2.3.1
Using jekyll-mentions 1.2.0
Using jekyll-optional-front-matter 0.1.2
Using jekyll-readme-index 0.1.0
Using jekyll-redirect-from 0.12.1
Using jekyll-relative-links 0.4.0
Using jekyll-seo-tag 2.1.0
Using jekyll-sitemap 1.0.0
Using jekyll-theme-architect 0.0.3
Using jekyll-theme-cayman 0.0.3
Using jekyll-theme-dinky 0.0.3
Using jekyll-theme-hacker 0.0.3
Using jekyll-theme-leap-day 0.0.3
Using jekyll-theme-merlot 0.0.3
Using jekyll-theme-midnight 0.0.3
Using jekyll-theme-minimal 0.0.3
Using jekyll-theme-modernist 0.0.3
Using jekyll-theme-primer 0.1.7
Using jekyll-theme-slate 0.0.3
Using jekyll-theme-tactile 0.0.3
Using jekyll-theme-time-machine 0.0.3
Using jekyll-titles-from-headings 0.1.5
Using jemoji 0.8.0
Using github-pages 132
Bundle updated!

bundle exec - Full error message

$ bundle exec jekyll serve
/cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:40:in `block in setup': You have already activated json 2.0.2, but your Gemfile requires json 1.8.6. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
        from /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/forwardable.rb:228:in `each'
        from /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/forwardable.rb:228:in `each'
        from /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:25:in `map'
        from /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/runtime.rb:25:in `setup'
        from /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler.rb:100:in `setup'
        from /cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/bundler-1.14.6/lib/bundler/setup.rb:10:in `<top (required)>'
        from /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /cygdrive/c/Users/mochapenguin/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'

json gems

$ gem list json

*** LOCAL GEMS ***
json (default: 2.0.2, 1.8.6)

bundle show json

$ bundle show json
/cygdrive/c/Users/mochapenguin/.rvm/gems/ruby-2.4.0/gems/json-1.8.6

Can't uninstall a default gem

$ gem uninstall json -v2.0.2
ERROR:  While executing gem ... (Gem::InstallError)
    gem "json" cannot be uninstalled because it is a default gem

UPDATE - 12-Apr-2017

I don't know what the issue is still, but I trimmed down the Gemfile to this and it doesn't fall in a heap. Maybe it somehow works when those particular version dependencies are not enforced.

source 'https://rubygems.org'

# sample suggested [here](https://jekyllrb.com/docs/github-pages/) and in github help
gem 'github-pages', group: :jekyll_plugins

UPDATE - 21-Apr-2017

This issue with bundler and system gems is highlighted at Gem Versioning and Bundler - Doing it right

Bundler's sandbox relies on its ability to be present at the very beginning of the Ruby process, and to therefore have the ability to ensure that the versions of all loaded libraries will reflect the ones listed in the Gemfile.lock. By running a system executable, you are executing Ruby code before Bundler can modify the load path and replace the normal Rubygems loading mechanism, allowing arbitrary unmanaged gems to get loaded into memory. Once that happens, all bets are off.

This is what seems to be happening in this situation.

But, as mentioned above - can't uninstall the system json 2.0.2 gem.

Body:
I had the same problem yesterday. I am not an expert but the following worked for me:

I created a new website with Jekyll using:

$ jekyll new "name_site"

I then copied the new GemFile and GemFile.lock from the new folder to the older (where you have a problem). Then, you run:

$ jekyll serve

in the folder of your current website and it should work. Let me know if it works for you!


问:
Chart js Backgroundimage Scaling
Hi i'm quite new to JS and looking for an easy way to show a custom map with my own backgroundimage and several points with x-y-coordinates on it.

At first it worked quite well using the "line"-chart-type of chart.js (v2.5) with disabled showScale()-option and fixed axes-max/min-values.

My problem is that the backgroundimage is not rescaling properly when i change the window-size or show/hide the legend of the chart.

Here is my JS-code for creating the chart:

```<code>function initMap() {
    scatterChart = new Chart(document.getElementById("scatterChart"), {
        responsive: true,
        type: 'line',
        data: {
            /*datasets: [
                {

                }
            ]
            */
        },
        showScale: false,
        options: {
            scales: {
                yAxes: [{
                    display: false,
                    ticks: {
                        max: y_max,
                        min: 0,
                        stepSize: 0.1
                    }
            }],
                xAxes: [{
                    display: false,
                    type: 'linear',
                    position: 'bottom',
                    ticks: {
                        max: x_max,
                        min: 0,
                        stepSize: 0.1
                    }
            }]
            },
            onClick: function (evt) {
                var activePoint = scatterChart.getElementAtEvent(evt);
            },
            legend: {
                position: 'right',
                labels: {
                    fontSize: 15
                }
            },
        }
    });
}
</code>```

HTML:

```<code><canvas id="scatterChart" style="width: 1920px; height: 1080px; background-image:url('media/map_background.jpg'); background-size: 100% 100%;"></canvas>
</code>```

Here are two images showing the effect:

https://1drv.ms/i/s!As59C5Mmd0nahr1zP4rjwI5KobaM3Q

https://1drv.ms/i/s!As59C5Mmd0nahr10KwUCJ4wpvfn4_g

What can i do to get a proper rescaling (points should always be shown on the same position on the map regardless of windowsize or enabled/disabled legend)?

答:
Have you tried using the maintainAspectRatio property and setting it to true? That should hopefully fix your window resize issue.

The only way to fix the legend issue is to use a legend that is external to the canvas because the legend takes up space in the canvas so the chart is squished horizontally (there is no layering concept in a canvas). See this example for how to generate an external legend.

You must use the legendCallback property and the .generateLegend() prototype method.

Title: Chart js Backgroundimage Scaling

Body:
Hi i'm quite new to JS and looking for an easy way to show a custom map with my own backgroundimage and several points with x-y-coordinates on it.

At first it worked quite well using the "line"-chart-type of chart.js (v2.5) with disabled showScale()-option and fixed axes-max/min-values.

My problem is that the backgroundimage is not rescaling properly when i change the window-size or show/hide the legend of the chart.

Here is my JS-code for creating the chart:

function initMap() {
    scatterChart = new Chart(document.getElementById("scatterChart"), {
        responsive: true,
        type: 'line',
        data: {
            /*datasets: [
                {

                }
            ]
            */
        },
        showScale: false,
        options: {
            scales: {
                yAxes: [{
                    display: false,
                    ticks: {
                        max: y_max,
                        min: 0,
                        stepSize: 0.1
                    }
            }],
                xAxes: [{
                    display: false,
                    type: 'linear',
                    position: 'bottom',
                    ticks: {
                        max: x_max,
                        min: 0,
                        stepSize: 0.1
                    }
            }]
            },
            onClick: function (evt) {
                var activePoint = scatterChart.getElementAtEvent(evt);
            },
            legend: {
                position: 'right',
                labels: {
                    fontSize: 15
                }
            },
        }
    });
}

HTML:

<canvas id="scatterChart" style="width: 1920px; height: 1080px; background-image:url('media/map_background.jpg'); background-size: 100% 100%;"></canvas>

Here are two images showing the effect:

https://1drv.ms/i/s!As59C5Mmd0nahr1zP4rjwI5KobaM3Q

https://1drv.ms/i/s!As59C5Mmd0nahr10KwUCJ4wpvfn4_g

What can i do to get a proper rescaling (points should always be shown on the same position on the map regardless of windowsize or enabled/disabled legend)?


问:
remove items when looping/iterating a list
I see some discussion about how to handle the task of "delete items when looping a list", e.g., this post.

An answer in this link says:

You are not permitted to remove elements from the list while iterating
  over it using a for loop.

It seems I can do it without problem:

```<code>words = ['DROP', 'TABLE', 'table_name']

for ii, word in enumerate(words):

    print(ii)
    print(word)

    if words[ii] == 'DROP' and words[ii + 1] == 'TABLE':
        words[ii] = 'DROP TABLE'
        del words[ii + 1]

print(words)
</code>```

yields:

```<code>0
DROP
1
table_name
['DROP TABLE', 'table_name']
</code>```

Has python changed the restriction and we can remove items when looping now?
I'm using python 3.7.

答:
From the comment of the answer you provided:

"You are not permitted" - sure you are. Python doesn't complain at you, it just gives a slightly (read: completely) different result to what people might expect. – lvc May 19 '12 at 14:00

You could always remove items from for loops, but it will skip the iteration when looping through. Take this example to see what happens (both ran through Python 2.7 and Python 3.5 giving the same result, of course Python 2 had print i):

```<code>i=[1,2,3,4,5,6]

for x in i:
    i.remove(x)

print(i) #[2, 4, 6]
</code>```

Notice how it skips index 2,4,6? it's because when you removed value 1 in index 0, value 2 becomes the new index 0, and the for loop will take value 3 as the next index.

There's nothing new about it. Generally it's a bad idea to remove items directly
 from a list while iterating through it.

The reason why your codes seems fine is cause you purposely dropped the index 1, which is what you desired.

Body:
I see some discussion about how to handle the task of "delete items when looping a list", e.g., this post.

An answer in this link says:

You are not permitted to remove elements from the list while iterating
  over it using a for loop.

It seems I can do it without problem:

words = ['DROP', 'TABLE', 'table_name']

for ii, word in enumerate(words):

    print(ii)
    print(word)

    if words[ii] == 'DROP' and words[ii + 1] == 'TABLE':
        words[ii] = 'DROP TABLE'
        del words[ii + 1]

print(words)

yields:

0
DROP
1
table_name
['DROP TABLE', 'table_name']

Has python changed the restriction and we can remove items when looping now?
I'm using python 3.7.

Body:
From the comment of the answer you provided:

"You are not permitted" - sure you are. Python doesn't complain at you, it just gives a slightly (read: completely) different result to what people might expect. – lvc May 19 '12 at 14:00

You could always remove items from for loops, but it will skip the iteration when looping through. Take this example to see what happens (both ran through Python 2.7 and Python 3.5 giving the same result, of course Python 2 had print i):

i=[1,2,3,4,5,6]

for x in i:
    i.remove(x)

print(i) #[2, 4, 6]

Notice how it skips index 2,4,6? it's because when you removed value 1 in index 0, value 2 becomes the new index 0, and the for loop will take value 3 as the next index.

There's nothing new about it. Generally it's a bad idea to remove items directly
 from a list while iterating through it.

The reason why your codes seems fine is cause you purposely dropped the index 1, which is what you desired.


问:
How to reduce sensitivity of android ScaleGestureDetector.SimpleOnScaleGestureListener
I have a custom SwipeRefreshLayout that has a custom GridView inside it. I want to change the column number of that GridView based on pinch/zoom gesture. I have successfully implemented it. The problem is, the scale is too sensitive.

For example, i have column number 3-5. It is easy to scale to 3 or 5, but to make it 4 is hard, since the scale itself is too sensitive.

Here is my custom SwipeRefreshLayout class

```<code>/**
 * This class contains fix from http://stackoverflow.com/questions/23989910/horizontalscrollview-inside-swiperefreshlayout
 */
public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {

    private int mTouchSlop;
    private float mPrevX;
    private ScaleGestureDetector mScaleGestureDetector;
    private ScaleListener mScaleListener;

    public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    public void setScaleListener(Context context, ScaleListener scaleListener) {
        this.mScaleListener = scaleListener;
        mScaleGestureDetector = new ScaleGestureDetector(context, new MyOnScaleGestureListener());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (mScaleGestureDetector != null) {
            mScaleGestureDetector.onTouchEvent(event);
        }

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_POINTER_DOWN:
                setEnabled(false);
                if (mScaleListener != null) {
                    mScaleListener.onTwoFingerStart();
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                setEnabled(true);
                mPrevX = MotionEvent.obtain(event).getX();
                if (mScaleListener != null) {
                    mScaleListener.onTwoFingerEnd();
                }
                break;
            case MotionEvent.ACTION_DOWN:
                mPrevX = MotionEvent.obtain(event).getX();
                break;

            case MotionEvent.ACTION_MOVE:
                final float eventX = event.getX();
                float xDiff = Math.abs(eventX - mPrevX);

                if (xDiff > mTouchSlop) {
                    return false;
                }
        }

        return super.onInterceptTouchEvent(event);
    }

    class MyOnScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

        private static final String TAG = "MyOnScaleGestureListene";

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            if (mScaleListener != null) {
                // Too sensitive, must change to other approach
                float scaleFactor = detector.getScaleFactor();
                Log.d(TAG, "onScale: " + scaleFactor);
                if (scaleFactor > 1F) {
                    mScaleListener.onScaleUp(scaleFactor);
                } else if (scaleFactor < 1F) {
                    mScaleListener.onScaleDown(scaleFactor);
                } else {
                    // no scale
                }
            }
            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
        }
    }

    public interface ScaleListener {
        void onTwoFingersStart();

        void onTwoFingersEnd();

        void onScaleUp(float scaleFactor);

        void onScaleDown(float scaleFactor);
    }
}
</code>```

Is there any way to reduce the sensitivity of ScaleGestureDetector.SimpleOnScaleGestureListener? If there is no way, is there any alternatives to solve it?

Here is a short video that showed the problem
https://www.youtube.com/watch?v=0MItDNZ_o4c

答:
You should have a tolerance distance, which is called "slop" in Android world. If the gesture is less than that tolerance you should just disregard it.

```<code>private static final int SPAN_SLOP = 7;

...

@Override
public boolean onScale(@NonNull ScaleGestureDetector detector) {
    if (gestureTolerance(detector)) {
        // performing scaling
    }
    return true;
}

private boolean gestureTolerance(@NonNull ScaleGestureDetector detector) {
    final float spanDelta = Math.abs(detector.getCurrentSpan() - detector.getPreviousSpan());
    return spanDelta > SPAN_SLOP;
}
</code>```

As an example you can see showcase open-source app made by @rallat.

Here you can find source code and presentation at GOTO Copenhagen 2016.

Body:
I have a custom SwipeRefreshLayout that has a custom GridView inside it. I want to change the column number of that GridView based on pinch/zoom gesture. I have successfully implemented it. The problem is, the scale is too sensitive.

For example, i have column number 3-5. It is easy to scale to 3 or 5, but to make it 4 is hard, since the scale itself is too sensitive.

Here is my custom SwipeRefreshLayout class

/**
 * This class contains fix from http://stackoverflow.com/questions/23989910/horizontalscrollview-inside-swiperefreshlayout
 */
public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {

    private int mTouchSlop;
    private float mPrevX;
    private ScaleGestureDetector mScaleGestureDetector;
    private ScaleListener mScaleListener;

    public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    public void setScaleListener(Context context, ScaleListener scaleListener) {
        this.mScaleListener = scaleListener;
        mScaleGestureDetector = new ScaleGestureDetector(context, new MyOnScaleGestureListener());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (mScaleGestureDetector != null) {
            mScaleGestureDetector.onTouchEvent(event);
        }

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_POINTER_DOWN:
                setEnabled(false);
                if (mScaleListener != null) {
                    mScaleListener.onTwoFingerStart();
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                setEnabled(true);
                mPrevX = MotionEvent.obtain(event).getX();
                if (mScaleListener != null) {
                    mScaleListener.onTwoFingerEnd();
                }
                break;
            case MotionEvent.ACTION_DOWN:
                mPrevX = MotionEvent.obtain(event).getX();
                break;

            case MotionEvent.ACTION_MOVE:
                final float eventX = event.getX();
                float xDiff = Math.abs(eventX - mPrevX);

                if (xDiff > mTouchSlop) {
                    return false;
                }
        }

        return super.onInterceptTouchEvent(event);
    }

    class MyOnScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

        private static final String TAG = "MyOnScaleGestureListene";

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            if (mScaleListener != null) {
                // Too sensitive, must change to other approach
                float scaleFactor = detector.getScaleFactor();
                Log.d(TAG, "onScale: " + scaleFactor);
                if (scaleFactor > 1F) {
                    mScaleListener.onScaleUp(scaleFactor);
                } else if (scaleFactor < 1F) {
                    mScaleListener.onScaleDown(scaleFactor);
                } else {
                    // no scale
                }
            }
            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
        }
    }

    public interface ScaleListener {
        void onTwoFingersStart();

        void onTwoFingersEnd();

        void onScaleUp(float scaleFactor);

        void onScaleDown(float scaleFactor);
    }
}

Is there any way to reduce the sensitivity of ScaleGestureDetector.SimpleOnScaleGestureListener? If there is no way, is there any alternatives to solve it?

Here is a short video that showed the problem
https://www.youtube.com/watch?v=0MItDNZ_o4c

Body:
You should have a tolerance distance, which is called "slop" in Android world. If the gesture is less than that tolerance you should just disregard it.

private static final int SPAN_SLOP = 7;

...

@Override
public boolean onScale(@NonNull ScaleGestureDetector detector) {
    if (gestureTolerance(detector)) {
        // performing scaling
    }
    return true;
}

private boolean gestureTolerance(@NonNull ScaleGestureDetector detector) {
    final float spanDelta = Math.abs(detector.getCurrentSpan() - detector.getPreviousSpan());
    return spanDelta > SPAN_SLOP;
}

As an example you can see showcase open-source app made by @rallat.

Here you can find source code and presentation at GOTO Copenhagen 2016.


问:
writing javascript inside Flex
I am currently developing an application in Adobe Flex and i have to use some APIs (Google Earth API, Garmin Communicator Plugin API..) which are written in javascript how can i use js inside Flex.

Thanks !!

答:
You can call a JavaScript-Function with the ExternalInterface.

For example:
In your index.template.html-file you can include javascript-code or define some javascript:

```<code><script type="text/javascript" src="./assets/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="./assets/js/jquery-1.4.2.min.js"></script>

<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
  function launchEditor() {
    $("#editor").hide();
  }
</script>
</code>```

If you want to call the function "launchEditor()" you can do this with the following code:

```<code>// Run editor
ExternalInterface.call("launchEditor");
</code>```

You could now send your data from your Flex-Application to your JavaScript and then call the Javascript API.

In your Flex-Application:

```<code>// Send data to javascript
ExternalInterface.call("garminSender", data1, data2, data3);
</code>```

In your JavaScript:

```<code>function garminSender(data1, data2, data3) {
 ...
}
</code>```

ContentLicense: CC BY-SA 2.5

Title: writing javascript inside Flex

Body:
You can call a JavaScript-Function with the ExternalInterface.

For example:
In your index.template.html-file you can include javascript-code or define some javascript:

<script type="text/javascript" src="./assets/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="./assets/js/jquery-1.4.2.min.js"></script>

<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
  function launchEditor() {
    $("#editor").hide();
  }
</script>

If you want to call the function "launchEditor()" you can do this with the following code:

// Run editor
ExternalInterface.call("launchEditor");

You could now send your data from your Flex-Application to your JavaScript and then call the Javascript API.

In your Flex-Application:

// Send data to javascript
ExternalInterface.call("garminSender", data1, data2, data3);

In your JavaScript:

function garminSender(data1, data2, data3) {
 ...
}


问:
Get information in two steps with javascript
I am trying to get some information from the user in two steps with javascript.
The user will provide this information by clicking on two different buttons.

I am struggling with the fact that the two actions (button clicks) will be triggered separately. Each time I will get a piece of information and I can do the magic only when I have both pieces.

This is what I tried (simplified to get to the core of my problem):

HTML

```<code><div class="container-1">
    <button class="my-btn" id="red">
        Color1
    </button>
    <button class="my-btn" id="green">
        Color2
    </button>
    <button class="my-btn" id="blue">
        Color3
    </button>
</div>
<hr>
<div class="container-2">
    <button class="my-btn" id="dog">
        Animal1
    </button>
    <button class="my-btn" id="cat">
        Animal2
    </button>
    <button class="my-btn" id="mouse">
        Animal3
    </button>
</div>
</code>```

javascript

```<code>sumUp = function(data) {
  first = data.btn1;
  second = data.btn2;
  alert('You chose a ' + first + ' ' + second);
};
$(".my-btn").click(function() {
  var val1 = $(this).attr('id');
  $(".container-2 .my-btn").click(function() {
    var val2 = $(this).attr('id');
  });
  var data = {
    btn1: val1,
    btn2: val2
  };
  sumUp(data);
});
</code>```

This jsfiddle will help to understand better what I am trying. It could be assumed that first the color would always be selected and then the animal.

In this example, I would just need to get the alert saying "You chose a red cat", or whatever combination depending on the buttons clicked.

What am I doing wrong and how could it be done?

答:
This was the quickest solution I could come up with. There are other ways to do it, but this should just work and is easy to implement.</p>

```<code>var option1, option2;

var run_alert = function() {
    if(option1.length && option2.length) {
        alert('You chose a ' + option1 + ' ' + option2);
    }
}

$(".container-1 .my-btn").click(function() {
    option1 = $(this).attr('id');
    run_alert();
});
$(".container-2 .my-btn").click(function() {
    option2 = $(this).attr('id');
    run_alert();
});
</code>```

Body:
I am trying to get some information from the user in two steps with javascript.
The user will provide this information by clicking on two different buttons.

I am struggling with the fact that the two actions (button clicks) will be triggered separately. Each time I will get a piece of information and I can do the magic only when I have both pieces.

This is what I tried (simplified to get to the core of my problem):

HTML

    <button class="my-btn" id="red">
        Color1
    </button>
    <button class="my-btn" id="green">
        Color2
    </button>
    <button class="my-btn" id="blue">
        Color3
    </button>

    <button class="my-btn" id="dog">
        Animal1
    </button>
    <button class="my-btn" id="cat">
        Animal2
    </button>
    <button class="my-btn" id="mouse">
        Animal3
    </button>

javascript

sumUp = function(data) {
  first = data.btn1;
  second = data.btn2;
  alert('You chose a ' + first + ' ' + second);
};
$(".my-btn").click(function() {
  var val1 = $(this).attr('id');
  $(".container-2 .my-btn").click(function() {
    var val2 = $(this).attr('id');
  });
  var data = {
    btn1: val1,
    btn2: val2
  };
  sumUp(data);
});

This jsfiddle will help to understand better what I am trying. It could be assumed that first the color would always be selected and then the animal.

In this example, I would just need to get the alert saying "You chose a red cat", or whatever combination depending on the buttons clicked.

What am I doing wrong and how could it be done?

Body:
This was the quickest solution I could come up with. There are other ways to do it, but this should just work and is easy to implement.

var option1, option2;

var run_alert = function() {
    if(option1.length && option2.length) {
        alert('You chose a ' + option1 + ' ' + option2);
    }
}

$(".container-1 .my-btn").click(function() {
    option1 = $(this).attr('id');
    run_alert();
});
$(".container-2 .my-btn").click(function() {
    option2 = $(this).attr('id');
    run_alert();
});


问:
Fill multidimesional array with values of another array in php
I've this array as query result:

```<code>[0]=>
array(2) {
["id_iscr"]=>
int(2)
["id_pettorina"]=>
NULL
}
[1]=>
array(2) {
["id_iscr"]=>
int(3)
["id_pettorina"]=>
NULL
}
[2]=>
array(2) {
["id_iscr"]=>
int(5)
["id_pettorina"]=>
NULL
}
[3]=>
array(2) {
["id_iscr"]=>
int(7)
["id_pettorina"]=>
NULL
}
...
</code>```

and this as array of distinct value

```<code>[0]=>
int(125)
[1]=>
int(162)
[2]=>
int(65)
[3]=>
int(98)
...
</code>```

Both array have same number of element;
my question is: in which way can I fill each NULL value of the first array with each value of the socond one and insert into mysql db?
Thanks in advance.

答:
I didn't test the code, but what Iam doing here is: Loop entire array1, verifying if the value is null, and if it is, I get the same position from the array2 and fill into id_pettorina position and save into a new resulting array called $resultingArray.

```<code><?php
$resultingArray = array();
foreach ($array1 as $k => $value) {
    if ($value["id_pettorina"] == null) {
        $value["id_pettorina"] = $array2[$k];
    }
    $resultingArray[] = $value;

    //Here in can insert into database, according to your schema
}
</code>```

In the line commented, you may insert the data from $resultingArray inside your database, using the values inside $value array. ex: $query = "INSERT INTO yourdbname SET id_pettorina = '".$value["id_pettorina"]."'";. Then you may pass this query into your statement and execute.

Body:
I've this array as query result:

[0]=>
array(2) {
["id_iscr"]=>
int(2)
["id_pettorina"]=>
NULL
}
[1]=>
array(2) {
["id_iscr"]=>
int(3)
["id_pettorina"]=>
NULL
}
[2]=>
array(2) {
["id_iscr"]=>
int(5)
["id_pettorina"]=>
NULL
}
[3]=>
array(2) {
["id_iscr"]=>
int(7)
["id_pettorina"]=>
NULL
}
...

and this as array of distinct value

[0]=>
int(125)
[1]=>
int(162)
[2]=>
int(65)
[3]=>
int(98)
...

Both array have same number of element;
my question is: in which way can I fill each NULL value of the first array with each value of the socond one and insert into mysql db?
Thanks in advance.

Body:
I didn't test the code, but what Iam doing here is: Loop entire array1, verifying if the value is null, and if it is, I get the same position from the array2 and fill into id_pettorina position and save into a new resulting array called $resultingArray.

<?php
$resultingArray = array();
foreach ($array1 as $k => $value) {
    if ($value["id_pettorina"] == null) {
        $value["id_pettorina"] = $array2[$k];
    }
    $resultingArray[] = $value;

    //Here in can insert into database, according to your schema
}

In the line commented, you may insert the data from $resultingArray inside your database, using the values inside $value array. ex: $query = "INSERT INTO yourdbname SET id_pettorina = '".$value["id_pettorina"]."'";. Then you may pass this query into your statement and execute.


答:
There's a couple of issues. First off, you're binding a new click handler every time you click .my-btn. You only want one binding and reuse it. Next, you need to store your state somewhere between clicks. A simple object would work fine for this.

let choices = {
  color: null,
  animal: null
};

function useChoices() {
  // Don't do anything if the user hasn't selected a value
  // from both categories
  if (choices.color === null || choices.animal === null) {
    return;
  }

  alert('You are a ' + choices.color + ' ' + choices.animal);
}

$('.color').click(function() {
  // Save the selected color
  choices.color = $(this).val();

  // Attempt to use the combined data
  useChoices();
});

$('.animal').click(function() {
  // Save the selected animal
  choices.animal = $(this).val();

  // Attempt to use the combined data
  useChoices();
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="color" value="red">Red</button>
<button class="color" value="green">Green</button>
<button class="color" value="blue">Blue</button>
<br />
<button class="animal" value="cat">Cat</button>
<button class="animal" value="dog">Dog</button>
<button class="animal" value="bird">Bird</button></code>```

You could have just saved your choices in independent variables rather than an object but by putting them inside of an object, you never have to worry about re-using that variable name somewhere else.

Title: Get information in two steps with javascript

Body:
There's a couple of issues. First off, you're binding a new click handler every time you click .my-btn. You only want one binding and reuse it. Next, you need to store your state somewhere between clicks. A simple object would work fine for this.

let choices = {
  color: null,
  animal: null
};

function useChoices() {
  // Don't do anything if the user hasn't selected a value
  // from both categories
  if (choices.color === null || choices.animal === null) {
    return;
  }

  alert('You are a ' + choices.color + ' ' + choices.animal);
}

$('.color').click(function() {
  // Save the selected color
  choices.color = $(this).val();

  // Attempt to use the combined data
  useChoices();
});

$('.animal').click(function() {
  // Save the selected animal
  choices.animal = $(this).val();

  // Attempt to use the combined data
  useChoices();
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="color" value="red">Red</button>
<button class="color" value="green">Green</button>
<button class="color" value="blue">Blue</button>
<br />
<button class="animal" value="cat">Cat</button>
<button class="animal" value="dog">Dog</button>
<button class="animal" value="bird">Bird</button>

You could have just saved your choices in independent variables rather than an object but by putting them inside of an object, you never have to worry about re-using that variable name somewhere else.


问:
How to retweet users' tweets in Python (and not their followers' tweets/RTs)
I am building a bot that will copy and paste tweets from several users (candidates to a presidential election).
When I run the code, my bot is actually copying supporters' tweets and retweets thus creating insane traffic on my page - all I want to copy is what the candidates themselves tweet from their account.

Anyone know how to do that?

I thought this:
if tweetText.startswith('RT @'):
pass
would solve the RT issue but apparently not...

Here is my code:

```<code>import twitter, sys, json, csv, time

# this app is being run by cast laboratory..@CASTlaboratory (4003669463)
consumer_key=""
consumer_secret=""
access_token=""
access_token_secret=""

auth = twitter.oauth.OAuth(access_token, access_token_secret,consumer_key, consumer_secret)
twitter_api = twitter.Twitter(auth=auth)

#Users we are following: Nicolas Dupont-Aignan, Francois Asselineau, Francois Fillon, Philippe Poutou, Jacques Cheminade, Emmanuel Macron, Nathalie Arthaud, Marine le Pen, Benoit Hamon, Jean Lassalle, Jean Luc Melenchon.

u = "38170599, 200659061, 551669623, 374392774, 150201042, 1976143068, 1003575248, 217749896, 14389177, 102722347, 80820758"

print >>sys.stderr, 'Retweeting everything for users="%s"' % (u)
twitter_stream = twitter.TwitterStream(auth=twitter_api.auth)
stream = twitter_stream.statuses.filter(follow=u)

for tweet in stream:

    tweetText = tweet['text'].encode('utf-8')
    print tweetText
    user = tweet['user']['screen_name']

    if tweetText.startswith('RT @'):
        pass

    else:

        print tweetText
        twitter_api.statuses.update(status = tweetText)
        time.sleep(60)
</code>```

Thank you!

答:
To filter the tweets to only match those coming from the users you're looking at, you should be able to do something like the following:

```<code>for tweet in stream:
    tweet_text = tweet['text'].encode('utf-8')
    user_id = tweet['user']['id']
    user_name = tweet['user']['screen_name']

    if user_id in u:
        print '@{}: {}'.format(user_name, tweet_text)
        time.sleep(60)
    else:
        pass
</code>```

As discussed in the comments, you should not be blanket-reposting tweets from different accounts. If this is something you've been explicitly asked to do in your assignment, maybe you should highlight this in your answer.

Body:
I am building a bot that will copy and paste tweets from several users (candidates to a presidential election).
When I run the code, my bot is actually copying supporters' tweets and retweets thus creating insane traffic on my page - all I want to copy is what the candidates themselves tweet from their account.

Anyone know how to do that?

I thought this:
if tweetText.startswith('RT @'):
pass
would solve the RT issue but apparently not...

Here is my code:

import twitter, sys, json, csv, time

# this app is being run by cast laboratory..@CASTlaboratory (4003669463)
consumer_key=""
consumer_secret=""
access_token=""
access_token_secret=""

auth = twitter.oauth.OAuth(access_token, access_token_secret,consumer_key, consumer_secret)
twitter_api = twitter.Twitter(auth=auth)

#Users we are following: Nicolas Dupont-Aignan, Francois Asselineau, Francois Fillon, Philippe Poutou, Jacques Cheminade, Emmanuel Macron, Nathalie Arthaud, Marine le Pen, Benoit Hamon, Jean Lassalle, Jean Luc Melenchon.

u = "38170599, 200659061, 551669623, 374392774, 150201042, 1976143068, 1003575248, 217749896, 14389177, 102722347, 80820758"

print >>sys.stderr, 'Retweeting everything for users="%s"' % (u)
twitter_stream = twitter.TwitterStream(auth=twitter_api.auth)
stream = twitter_stream.statuses.filter(follow=u)

for tweet in stream:

    tweetText = tweet['text'].encode('utf-8')
    print tweetText
    user = tweet['user']['screen_name']

    if tweetText.startswith('RT @'):
        pass

    else:

        print tweetText
        twitter_api.statuses.update(status = tweetText)
        time.sleep(60)

Thank you!

Body:
To filter the tweets to only match those coming from the users you're looking at, you should be able to do something like the following:

for tweet in stream:
    tweet_text = tweet['text'].encode('utf-8')
    user_id = tweet['user']['id']
    user_name = tweet['user']['screen_name']

    if user_id in u:
        print '@{}: {}'.format(user_name, tweet_text)
        time.sleep(60)
    else:
        pass

As discussed in the comments, you should not be blanket-reposting tweets from different accounts. If this is something you've been explicitly asked to do in your assignment, maybe you should highlight this in your answer.


问:
Save a PATH to a file
I got a simple problem, but I do not know how to solve it.
I need to save some files in a directory, but I need to save the path to it.
Because, when I restart the program, I want that my program looks the folder where I left my files, and build a TreeView in JavaFX. Like eclipse IDE does.

Can someone help me with this?

答:
You can use OS AppData folders. For example, for Windows it would be  /User/AppData/, for Linux you can use /home/{username}/.your_app_name/
Create config file, XML or any format you want.

```<code>String configPath = "/home/enchantinggg4/.javaFxApplication/";
File config = new File(configPath + "config.xml");
config.createNewFile();
FileWriter writer = new FileWriter(config);
writer.write(....);
writer.close();
</code>```

Then you can read it after relaunch or smf.

Title: Save a PATH to a file

Body:
You can use OS AppData folders. For example, for Windows it would be  /User/AppData/, for Linux you can use /home/{username}/.your_app_name/
Create config file, XML or any format you want.

String configPath = "/home/enchantinggg4/.javaFxApplication/";
File config = new File(configPath + "config.xml");
config.createNewFile();
FileWriter writer = new FileWriter(config);
writer.write(....);
writer.close();

Then you can read it after relaunch or smf.


问:
Change $(img).offset() when image is moved onclick()
I have an image which changes position randomly when I click on it. I want to play one of three possible different sounds depending on if the click is:

on the image

50px away from the image

more than 50px away from the image.

To do so I need to save the image's coordinates so that they are updated every time the image is moved. I have this code:

function move() {
  var audio = document.getElementById("audio");
  var img = document.getElementById("myImage");

  //FIND CENTER OF IMAGE
  var offset = $(img).offset();
  var width = $(img).width();
  var height = $(img).height();

  // PLAY DIFFERENT SOUND
  document.addEventListener("click", function(e) {
    if (e.target === img) {
      audio.src = "sound1.mp3";
      audio.play();
    } else if (e.clientX < (offset.left - 50) || e.clientX > (offset.left + width + 50) || e.clientY < (offset.top - 50) || e.clientY > (offset.top + height + 50)) {
      audio.src = "sound2.mp3";
      audio.play();
    } else {
      audio.src = "sound3.mp3";
      audio.play();
    }
    // GENERATE RANDOM LOCATION
    // Fix this part
    var x = Math.floor(Math.random() * 400);
    var y = Math.floor(Math.random() * 400);

    img.style.top = x + "px";
    img.style.left = y + "px";
    img.style.bottom = x - "px";
    img.style.right = y - "px";
  }, false);
}
```

There must some small mistakes in updating the coordinates of the image. Any ideas why?

答:
It seems, that you have your variable offset cached for each click, try moving assignment to the click handler. Also extract the event listener from your move function to avoid memory leaks. In your case, each time you fire the move function, a new event listener is attached. Ensure your  has position set for fixed or absolute to a relative element. In case you use a relative element you have to change $window to your relative elements to get the right size.

  var $audio = $('#audio');
  var $img = $("#myImage");
  var $window = $(window);

  var width = $img.width();
  var height = $img.height();
  var maxX = $window.width() - width;
  var maxY = $window.height() - height;

  function move() {
    //Get a new position, use modulo operation to get x from range (0, windowWidth - imageWidth) and y from range (0, windowHeight - imageHeight)
    var x = Math.floor(Math.random() * 10000) % maxX;
    var y = Math.floor(Math.random() * 10000) % maxY;

    $img.css('left', x + 'px');
    $img.css('top', y + 'px');
  }

  document.addEventListener("click", function(e) {
    //get the img offset
    var offset = $img.offset();
    if (e.target === $img[0]) {
      audio.src = "sound1.mp3";
      audio.play();
    } else if (e.clientX < (offset.left - 50) || e.clientX > (offset.left + width + 50) || e.clientY < (offset.top - 50) || e.clientY > (offset.top + height + 50)) {
      audio.src = "sound2.mp3";
      audio.play();
    } else {
      audio.src = "sound3.mp3";
      audio.play();
    }

    move();
  }, false);```

Body:
I have an image which changes position randomly when I click on it. I want to play one of three possible different sounds depending on if the click is:

on the image

50px away from the image

more than 50px away from the image.

To do so I need to save the image's coordinates so that they are updated every time the image is moved. I have this code:

function move() {
  var audio = document.getElementById("audio");
  var img = document.getElementById("myImage");

  //FIND CENTER OF IMAGE
  var offset = $(img).offset();
  var width = $(img).width();
  var height = $(img).height();

  // PLAY DIFFERENT SOUND
  document.addEventListener("click", function(e) {
    if (e.target === img) {
      audio.src = "sound1.mp3";
      audio.play();
    } else if (e.clientX < (offset.left - 50) || e.clientX > (offset.left + width + 50) || e.clientY < (offset.top - 50) || e.clientY > (offset.top + height + 50)) {
      audio.src = "sound2.mp3";
      audio.play();
    } else {
      audio.src = "sound3.mp3";
      audio.play();
    }
    // GENERATE RANDOM LOCATION
    // Fix this part
    var x = Math.floor(Math.random() * 400);
    var y = Math.floor(Math.random() * 400);

    img.style.top = x + "px";
    img.style.left = y + "px";
    img.style.bottom = x - "px";
    img.style.right = y - "px";
  }, false);
}

There must some small mistakes in updating the coordinates of the image. Any ideas why?

Body:
It seems, that you have your variable offset cached for each click, try moving assignment to the click handler. Also extract the event listener from your move function to avoid memory leaks. In your case, each time you fire the move function, a new event listener is attached. Ensure your <img id="myImage" /> has position set for fixed or absolute to a relative element. In case you use a relative element you have to change $window to your relative elements to get the right size.

  var $audio = $('#audio');
  var $img = $("#myImage");
  var $window = $(window);

  var width = $img.width();
  var height = $img.height();
  var maxX = $window.width() - width;
  var maxY = $window.height() - height;

  function move() {
    //Get a new position, use modulo operation to get x from range (0, windowWidth - imageWidth) and y from range (0, windowHeight - imageHeight)
    var x = Math.floor(Math.random() * 10000) % maxX;
    var y = Math.floor(Math.random() * 10000) % maxY;

    $img.css('left', x + 'px');
    $img.css('top', y + 'px');
  }

  document.addEventListener("click", function(e) {
    //get the img offset
    var offset = $img.offset();
    if (e.target === $img[0]) {
      audio.src = "sound1.mp3";
      audio.play();
    } else if (e.clientX < (offset.left - 50) || e.clientX > (offset.left + width + 50) || e.clientY < (offset.top - 50) || e.clientY > (offset.top + height + 50)) {
      audio.src = "sound2.mp3";
      audio.play();
    } else {
      audio.src = "sound3.mp3";
      audio.play();
    }

    move();
  }, false);


问:
How Do I Evaluate My Self Trained MATCONNET CNN network
I am trying to build my own CNN (Alexnet Model) for traffic sign recognition using MATCONVNET. I used the image dataset from the German Traffic Sign Recognition Benchmark (GTSRB) website (http://benchmark.ini.rub.de/?section=gtsrb&subsection=datase) to create my own IMDB which consists of well-labeled training, validation and test data for 43 classes of road traffic signs.

Now I am having two challenges.

My network is not converging. I have an about steady error of 0.977

I am trying to evaluate my trained network even with this error rate, but thats where I have my biggest challenge. I havent been able to figure out how to evaluate self trainined networks in MATCONVNET and there are very little helpful materials out there to help.

Someone please help out if you have an idea on what I need to change or do better?

答:
I'm not too familiar with MATCONVNET in particular so I may be misinterpreting your issue, but a general rule for evaluating classifiers is cross-validate (i.e. train and test on different subsets and repeat across multiple subset configurations).

For one configuration

To generate one configuration of data you can use

```<code>nObservations = size(data,1);
y_act = ... ; % class labels for each observation
ratio = .5;
net = ... %your net definition

[Train,Test] = crossvalind('HoldOut',nObservations,ratio);
[net,...] = train(net,data(Train,:))
y_exp = predict(net,data(Test,:))
rate = length(find(y_exp == y_act(Test)))/...
       numel(y_act(Test));
</code>```

Rate is a better indicator than your original one. Depending on your model, you probably want to make sure that the classes are distributing at an even proportion (or maybe even equal amounts, which would require you to toss some observations so you have equal class totals). To ensure this you can divide each class independently with crossvalind and then merge to form your Train/Test sets.

You can also play around with your train:test ratio. .5 is a fine place to start. Gradually increase if you have trouble classifying your test set.

Permute configurations

One issue with this analysis is only evaluates one configuration. For massive datasets or sets where generalization is not important that might be ok. But you can combat this by permutating the above analysis across

all combinations within a set configuration

Say you divide the dataset into A,B,C, and D. You can   train([A,B,C])-test(D), train(A,B,D)-test(C), ... train(B,C,D)-test(A) and average the prediction rates

This is usually 'good enough' but you have to acknowledge that in small datasets you could have a skewed representations in one of your sets

all possible configurations within a set

Using nchoosek(...) you can represent all possible configurations and test each one for train-test. Becomes impossibly long very quickly. Choosing an arbitrary, large number of these configurations works too. If you have really low observation numbers this is useful at a low costs,especially when validated with bootstrapping. Probably not relevant for your analysis.

Body:
I'm not too familiar with MATCONVNET in particular so I may be misinterpreting your issue, but a general rule for evaluating classifiers is cross-validate (i.e. train and test on different subsets and repeat across multiple subset configurations).

For one configuration

To generate one configuration of data you can use

nObservations = size(data,1);
y_act = ... ; % class labels for each observation
ratio = .5;
net = ... %your net definition

[Train,Test] = crossvalind('HoldOut',nObservations,ratio);
[net,...] = train(net,data(Train,:))
y_exp = predict(net,data(Test,:))
rate = length(find(y_exp == y_act(Test)))/...
       numel(y_act(Test));

Rate is a better indicator than your original one. Depending on your model, you probably want to make sure that the classes are distributing at an even proportion (or maybe even equal amounts, which would require you to toss some observations so you have equal class totals). To ensure this you can divide each class independently with crossvalind and then merge to form your Train/Test sets.

You can also play around with your train:test ratio. .5 is a fine place to start. Gradually increase if you have trouble classifying your test set.

Permute configurations

One issue with this analysis is only evaluates one configuration. For massive datasets or sets where generalization is not important that might be ok. But you can combat this by permutating the above analysis across

all combinations within a set configuration

Say you divide the dataset into A,B,C, and D. You can   train([A,B,C])-test(D), train(A,B,D)-test(C), ... train(B,C,D)-test(A) and average the prediction rates

This is usually 'good enough' but you have to acknowledge that in small datasets you could have a skewed representations in one of your sets

all possible configurations within a set

Using nchoosek(...) you can represent all possible configurations and test each one for train-test. Becomes impossibly long very quickly. Choosing an arbitrary, large number of these configurations works too. If you have really low observation numbers this is useful at a low costs,especially when validated with bootstrapping. Probably not relevant for your analysis.


答:
Just put data and sumUp() inside the .container-2 click handler callback function. Also, make sure you are using .off() on the .container-2 click handler, so you do not register numerous handlers and have duplicate processing.

The reason you are able to access val1 inside the container-2 click handler callback is because of a concept called JavaScript Closures

var sumUp = function(data) {
  first = data.btn1;
  second = data.btn2;
  alert('You chose a ' + first + ' ' + second);
};
$(".my-btn").click(function() {
  var val1 = $(this).attr('id');
  $(".container-2 .my-btn").off("click.myclick");
  $(".container-2 .my-btn").on("click.myclick", function() {
    var val2 = $(this).attr('id');
    var data = {
      btn1: val1,
      btn2: val2
    };
    sumUp(data);
  });
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-1">
    <button class="my-btn" id="red">
        Color1
    </button>
    <button class="my-btn" id="green">
        Color2
    </button>
    <button class="my-btn" id="blue">
        Color3
    </button>
</div>
<hr>
<div class="container-2">
    <button class="my-btn" id="dog">
        Animal1
    </button>
    <button class="my-btn" id="cat">
        Animal2
    </button>
    <button class="my-btn" id="mouse">
        Animal3
    </button>
</div></code>```

Body:
Just put data and sumUp() inside the .container-2 click handler callback function. Also, make sure you are using .off() on the .container-2 click handler, so you do not register numerous handlers and have duplicate processing.

The reason you are able to access val1 inside the container-2 click handler callback is because of a concept called JavaScript Closures

var sumUp = function(data) {
  first = data.btn1;
  second = data.btn2;
  alert('You chose a ' + first + ' ' + second);
};
$(".my-btn").click(function() {
  var val1 = $(this).attr('id');
  $(".container-2 .my-btn").off("click.myclick");
  $(".container-2 .my-btn").on("click.myclick", function() {
    var val2 = $(this).attr('id');
    var data = {
      btn1: val1,
      btn2: val2
    };
    sumUp(data);
  });
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-1">
    <button class="my-btn" id="red">
        Color1
    </button>
    <button class="my-btn" id="green">
        Color2
    </button>
    <button class="my-btn" id="blue">
        Color3
    </button>
</div>
<hr>
<div class="container-2">
    <button class="my-btn" id="dog">
        Animal1
    </button>
    <button class="my-btn" id="cat">
        Animal2
    </button>
    <button class="my-btn" id="mouse">
        Animal3
    </button>
</div>


问:
How to unwrap textfield.text without using the " ! " - Swift 3
I've been searching stackoverflow and would like to know what the best practice is to unwrap the textfield.text optional without force unwrapping. It works doing this, but I've been told to never force unwrap. But when I assign textfield.text to something, I'm only just passing the optional string. Can someone explain what would be best for this? Thanks!

Edit:

```<code>    func configuredMailComposeViewController() -> MFMailComposeViewController {

    let passTextField = TextField.text

    let mailComposerVC = MFMailComposeViewController()
    mailComposerVC.mailComposeDelegate = self

    mailComposerVC.setToRecipients(["email@email.com"])
    mailComposerVC.setSubject(passTextField!)
    mailComposerVC.setMessageBody("Some Text", isHTML: false)

    return mailComposerVC
}
</code>```

I'm trying to pass a textfield text and pass it to the email subject. The force unwrap doesn't cause an error, but I would like to know what the best practice is to pass this string

Edit 2:

```<code> func configuredMailComposeViewController() -> MFMailComposeViewController {

    let mailComposerVC = MFMailComposeViewController()
    mailComposerVC.mailComposeDelegate = self

    mailComposerVC.setToRecipients(["email@email.com"])
        if let passTextField = textfield.text {
           mailComposerVC.setSubject(passTextField)
         }
    mailComposerVC.setMessageBody("Some Text", isHTML: false)

    return mailComposerVC
}
</code>```

答:
you can always unwrap a variable if you know for sure that it's already been defined, and you may need to take different action if the field has not been defined

```<code>var someVariableWithWideScope : String = ""

if myTextField.text != nil {
    someVariableWithWideScope = myTextField.text!
} else {
    // do something specific for nil values
}
</code>```

of course, if all you're going to do for nil is assign a default value, you can do it one step as discussed elsewhere

```<code>let someVariable = myTextField.text ?? "default"
</code>```

but that approach doesn't let you change execution flow

Body:
I've been searching stackoverflow and would like to know what the best practice is to unwrap the textfield.text optional without force unwrapping. It works doing this, but I've been told to never force unwrap. But when I assign textfield.text to something, I'm only just passing the optional string. Can someone explain what would be best for this? Thanks!

Edit:

    func configuredMailComposeViewController() -> MFMailComposeViewController {

    let passTextField = TextField.text

    let mailComposerVC = MFMailComposeViewController()
    mailComposerVC.mailComposeDelegate = self

    mailComposerVC.setToRecipients(["email@email.com"])
    mailComposerVC.setSubject(passTextField!)
    mailComposerVC.setMessageBody("Some Text", isHTML: false)

    return mailComposerVC
}

I'm trying to pass a textfield text and pass it to the email subject. The force unwrap doesn't cause an error, but I would like to know what the best practice is to pass this string

Edit 2:

 func configuredMailComposeViewController() -> MFMailComposeViewController {

    let mailComposerVC = MFMailComposeViewController()
    mailComposerVC.mailComposeDelegate = self

    mailComposerVC.setToRecipients(["email@email.com"])
        if let passTextField = textfield.text {
           mailComposerVC.setSubject(passTextField)
         }
    mailComposerVC.setMessageBody("Some Text", isHTML: false)

    return mailComposerVC
}

Body:
you can always unwrap a variable if you know for sure that it's already been defined, and you may need to take different action if the field has not been defined

var someVariableWithWideScope : String = ""

if myTextField.text != nil {
    someVariableWithWideScope = myTextField.text!
} else {
    // do something specific for nil values
}

of course, if all you're going to do for nil is assign a default value, you can do it one step as discussed elsewhere

let someVariable = myTextField.text ?? "default"

but that approach doesn't let you change execution flow


问:
PHPMailer smtp connect missing 220
I have a problem connecting to SMTP-Server via PHPMailer.

```<code><?php
$mail = new PHPMailer();
$mail->isSMTP();

$mail->SMTPDebug = true;

$mail->Host = "ip.ip.ip.ip";
$mail->Port = "25";
$mail->Helo = "";
$mail->SMTPAutoTLS = false;
$mail->SMTPSecure = "";
$mail->SMTPAuth = false;
$mail->Timeout = 10;

$mail->From = "sender@example.com";
$mail->FromName = "Sender Name";

$mail->addAddress("receiver@example.com");

$mail->isHTML(true);
$mail->Subject = "Test";
$mail->Body = "<h1>Test</h1>";

if(!$mail->Send()) {
    echo $mail->ErrorInfo;
} else {
    echo "Mail sent...";
}
</code>```

I figured out the main problem:
After successfully connect the server is NOT sending a "220 announcement" directly. It is sending nothing but waiting for a EHLO. After any client input the server sends a "220 announcement"! I tested it with telnet.

I newer saw it before and i don't know if it respects the rfc.

The 220 AFTER the EHLO makes PHPMailer completely crashing. Any following communication is "misunderstood". I saw that PHPMailer is waiting for a 220 announcement after connecting. But this fails because the server is not sending anything. When the timeout is reached the client sends a EHLO. After that it receives a 220 but the following communication fails.

Here is the full communication output:

```<code>2017-03-30 13:38:48     Connection: opening to ip.ip.ip.ip:587, timeout=10, options=array (
                                          )
2017-03-30 13:38:48     Connection: opened
2017-03-30 13:38:58     SMTP -> get_lines(): $data is ""
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  ""
2017-03-30 13:38:58     SMTP -> get_lines(): timed-out (10 sec)
2017-03-30 13:38:58     SERVER -> CLIENT:
2017-03-30 13:38:58     CLIENT -> SERVER: EHLO conweb1.example.de
2017-03-30 13:38:58     SMTP -> get_lines(): $data is ""
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "220 EX-02.example.loc Microsoft ESMTP MAIL Service ready at Thu, 30 Mar 2017 15:38:58 +0200
                                          "
2017-03-30 13:38:58     SERVER -> CLIENT: 220 EX-02.example.loc Microsoft ESMTP MAIL Service ready at Thu, 30 Mar 2017 15:38:58 +0200
2017-03-30 13:38:58     SMTP ERROR: EHLO command failed: 220 EX-02.example.loc Microsoft ESMTP MAIL Service ready at Thu, 30 Mar 2017 15:38:58 +0200
2017-03-30 13:38:58     CLIENT -> SERVER: HELO conweb1.example.de
2017-03-30 13:38:58     SMTP -> get_lines(): $data is ""
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-SIZE 36700160
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-PIPELINING
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-DSN
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-ENHANCEDSTATUSCODES
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-STARTTLS
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-AUTH LOGIN
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          250-AUTH LOGIN
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-8BITMIME
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          250-AUTH LOGIN
                                          250-8BITMIME
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-BINARYMIME
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          250-AUTH LOGIN
                                          250-8BITMIME
                                          250-BINARYMIME
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250 CHUNKING
                                          "
2017-03-30 13:38:58     SERVER -> CLIENT: 250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          250-AUTH LOGIN
                                          250-8BITMIME
                                          250-BINARYMIME
                                          250 CHUNKING
2017-03-30 13:38:58     CLIENT -> SERVER: MAIL FROM:<personal@example.com>
2017-03-30 13:39:03     SMTP -> get_lines(): $data is ""
2017-03-30 13:39:03     SMTP -> get_lines(): $str is  "250 EX-02.example.loc Hello [ip.ip.ip.ip]
                                          "
2017-03-30 13:39:03     SERVER -> CLIENT: 250 EX-02.example.loc Hello [ip.ip.ip.ip]
2017-03-30 13:39:03     CLIENT -> SERVER: RCPT TO:<tm@example.com>
2017-03-30 13:39:03     SMTP -> get_lines(): $data is ""
2017-03-30 13:39:03     SMTP -> get_lines(): $str is  "250 2.1.0 Sender OK
                                          "
2017-03-30 13:39:03     SERVER -> CLIENT: 250 2.1.0 Sender OK
2017-03-30 13:39:03     CLIENT -> SERVER: DATA
2017-03-30 13:39:03     SMTP -> get_lines(): $data is ""
2017-03-30 13:39:03     SMTP -> get_lines(): $str is  "250 2.1.5 Recipient OK
                                          "
2017-03-30 13:39:03     SERVER -> CLIENT: 250 2.1.5 Recipient OK
2017-03-30 13:39:03     SMTP ERROR: DATA command failed: 250 2.1.5 Recipient OK
2017-03-30 13:39:03     SMTP Error: data not accepted.
SMTP Error: data not accepted.SMTP server error: DATA command failed Detail: Recipient OK
 SMTP code: 250 Additional SMTP info: 2.1.52017-03-30 13:39:03  CLIENT -> SERVER: QUIT
2017-03-30 13:39:03     SMTP -> get_lines(): $data is ""
2017-03-30 13:39:03     SMTP -> get_lines(): $str is  "354 Start mail input; end with <CRLF>.<CRLF>
2017-03-30 13:39:03     SMTP ERROR: QUIT command failed: 354 Start mail input; end with <CRLF>.<CRLF>
2017-03-30 13:39:03     Connection: closed
</code>```

The main question is:
Is the error caused by a wrong protocol implementation of PHP-Mailer?
Or is the SMTP Server misconfigured?

答:
Don't do this:

```<code>$mail->Timeout = 10;
</code>```

RFC2821 specifies a timeout of 300sec (5 minutes) on the initial greeting, and some servers impose a long delay here (known as a "greet delay") specifically to trap non-conforming clients, usually spambots. PHPMailer respects this exactly with its default Timeout setting of 300 sec. If you shorten it, you're preventing it from waiting for long enough. Does it work if you set it to 300 or leave at its default setting?

If you say "but I don't want to wait that long during page processing!" - welcome to the world of SMTP - it's not designed for real-time use; use a local mail server relay to remove this delay and let the mail server worry about it.

Title: PHPMailer smtp connect missing 220

Body:
I have a problem connecting to SMTP-Server via PHPMailer.

<?php
$mail = new PHPMailer();
$mail->isSMTP();

$mail->SMTPDebug = true;

$mail->Host = "ip.ip.ip.ip";
$mail->Port = "25";
$mail->Helo = "";
$mail->SMTPAutoTLS = false;
$mail->SMTPSecure = "";
$mail->SMTPAuth = false;
$mail->Timeout = 10;

$mail->From = "sender@example.com";
$mail->FromName = "Sender Name";

$mail->addAddress("receiver@example.com");

$mail->isHTML(true);
$mail->Subject = "Test";
$mail->Body = "
Test
";

if(!$mail->Send()) {
    echo $mail->ErrorInfo;
} else {
    echo "Mail sent...";
}

I figured out the main problem:
After successfully connect the server is NOT sending a "220 announcement" directly. It is sending nothing but waiting for a EHLO. After any client input the server sends a "220 announcement"! I tested it with telnet.

I newer saw it before and i don't know if it respects the rfc.

The 220 AFTER the EHLO makes PHPMailer completely crashing. Any following communication is "misunderstood". I saw that PHPMailer is waiting for a 220 announcement after connecting. But this fails because the server is not sending anything. When the timeout is reached the client sends a EHLO. After that it receives a 220 but the following communication fails.

Here is the full communication output:

2017-03-30 13:38:48     Connection: opening to ip.ip.ip.ip:587, timeout=10, options=array (
                                          )
2017-03-30 13:38:48     Connection: opened
2017-03-30 13:38:58     SMTP -> get_lines(): $data is ""
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  ""
2017-03-30 13:38:58     SMTP -> get_lines(): timed-out (10 sec)
2017-03-30 13:38:58     SERVER -> CLIENT:
2017-03-30 13:38:58     CLIENT -> SERVER: EHLO conweb1.example.de
2017-03-30 13:38:58     SMTP -> get_lines(): $data is ""
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "220 EX-02.example.loc Microsoft ESMTP MAIL Service ready at Thu, 30 Mar 2017 15:38:58 +0200
                                          "
2017-03-30 13:38:58     SERVER -> CLIENT: 220 EX-02.example.loc Microsoft ESMTP MAIL Service ready at Thu, 30 Mar 2017 15:38:58 +0200
2017-03-30 13:38:58     SMTP ERROR: EHLO command failed: 220 EX-02.example.loc Microsoft ESMTP MAIL Service ready at Thu, 30 Mar 2017 15:38:58 +0200
2017-03-30 13:38:58     CLIENT -> SERVER: HELO conweb1.example.de
2017-03-30 13:38:58     SMTP -> get_lines(): $data is ""
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-SIZE 36700160
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-PIPELINING
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-DSN
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-ENHANCEDSTATUSCODES
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-STARTTLS
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-AUTH LOGIN
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          250-AUTH LOGIN
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-8BITMIME
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          250-AUTH LOGIN
                                          250-8BITMIME
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250-BINARYMIME
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $data is "250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          250-AUTH LOGIN
                                          250-8BITMIME
                                          250-BINARYMIME
                                          "
2017-03-30 13:38:58     SMTP -> get_lines(): $str is  "250 CHUNKING
                                          "
2017-03-30 13:38:58     SERVER -> CLIENT: 250-EX-02.example.loc Hello [ip.ip.ip.ip]
                                          250-SIZE 36700160
                                          250-PIPELINING
                                          250-DSN
                                          250-ENHANCEDSTATUSCODES
                                          250-STARTTLS
                                          250-AUTH LOGIN
                                          250-8BITMIME
                                          250-BINARYMIME
                                          250 CHUNKING
2017-03-30 13:38:58     CLIENT -> SERVER: MAIL FROM:<personal@example.com>
2017-03-30 13:39:03     SMTP -> get_lines(): $data is ""
2017-03-30 13:39:03     SMTP -> get_lines(): $str is  "250 EX-02.example.loc Hello [ip.ip.ip.ip]
                                          "
2017-03-30 13:39:03     SERVER -> CLIENT: 250 EX-02.example.loc Hello [ip.ip.ip.ip]
2017-03-30 13:39:03     CLIENT -> SERVER: RCPT TO:<tm@example.com>
2017-03-30 13:39:03     SMTP -> get_lines(): $data is ""
2017-03-30 13:39:03     SMTP -> get_lines(): $str is  "250 2.1.0 Sender OK
                                          "
2017-03-30 13:39:03     SERVER -> CLIENT: 250 2.1.0 Sender OK
2017-03-30 13:39:03     CLIENT -> SERVER: DATA
2017-03-30 13:39:03     SMTP -> get_lines(): $data is ""
2017-03-30 13:39:03     SMTP -> get_lines(): $str is  "250 2.1.5 Recipient OK
                                          "
2017-03-30 13:39:03     SERVER -> CLIENT: 250 2.1.5 Recipient OK
2017-03-30 13:39:03     SMTP ERROR: DATA command failed: 250 2.1.5 Recipient OK
2017-03-30 13:39:03     SMTP Error: data not accepted.
SMTP Error: data not accepted.SMTP server error: DATA command failed Detail: Recipient OK
 SMTP code: 250 Additional SMTP info: 2.1.52017-03-30 13:39:03  CLIENT -> SERVER: QUIT
2017-03-30 13:39:03     SMTP -> get_lines(): $data is ""
2017-03-30 13:39:03     SMTP -> get_lines(): $str is  "354 Start mail input; end with <CRLF>.<CRLF>
2017-03-30 13:39:03     SMTP ERROR: QUIT command failed: 354 Start mail input; end with <CRLF>.<CRLF>
2017-03-30 13:39:03     Connection: closed

The main question is:
Is the error caused by a wrong protocol implementation of PHP-Mailer?
Or is the SMTP Server misconfigured?

Body:
Don't do this:

$mail->Timeout = 10;

RFC2821 specifies a timeout of 300sec (5 minutes) on the initial greeting, and some servers impose a long delay here (known as a "greet delay") specifically to trap non-conforming clients, usually spambots. PHPMailer respects this exactly with its default Timeout setting of 300 sec. If you shorten it, you're preventing it from waiting for long enough. Does it work if you set it to 300 or leave at its default setting?

If you say "but I don't want to wait that long during page processing!" - welcome to the world of SMTP - it's not designed for real-time use; use a local mail server relay to remove this delay and let the mail server worry about it.


答: That statement is technically wrong but reasonable for most use cases. You most certainly can remove items from a list while enumerating but be aware that you will end up skipping elements if you do so. You want that to happen in your case - the enumeration skips the 'TABLE' entry by doing a lookahead into the not-yet-enumerated list (words[ii + 1] == 'TABLE') and trimming. But that is an uncommon use case.

Title: remove items when looping/iterating a list

Body:
I see some discussion about how to handle the task of "delete items when looping a list", e.g., this post.

An answer in this link says:

You are not permitted to remove elements from the list while iterating
  over it using a for loop.

It seems I can do it without problem:

words = ['DROP', 'TABLE', 'table_name']

for ii, word in enumerate(words):

    print(ii)
    print(word)

    if words[ii] == 'DROP' and words[ii + 1] == 'TABLE':
        words[ii] = 'DROP TABLE'
        del words[ii + 1]

print(words)

yields:

0
DROP
1
table_name
['DROP TABLE', 'table_name']

Has python changed the restriction and we can remove items when looping now?
I'm using python 3.7.


问:
Window 7, PHP, Unable to load dynamic libary 'C:\PHP\ext\php_oci8.dll'
I installed PHP in window 7, running simple PHP without issue.
when I want to connect oracle db 11g XE, using $conn = oci_connect ($user, $pawd, 'localhost/XE'); I get the following errors:

```<code>Unable to load dynamic library 'C:\PHP\ext\php_oci8.dll' ...
Unable to load dynamic library 'C:\PHP\ext\php_oci8_11g.dll' ...
PHP Fatal error: Call to undefined function oci_connect (..);
</code>```

I checked that C:\PHP\ext\php_oci8.dll is there and I changed the following in php.ini file.

```<code>extension_dir = "C:\PHP\exe";
extension=php_bz2.dll;
extension=php_curl.dll;
extension=php_oci8.dll;
extension=php_oci8_11g.dll;
</code>```

what is the issue behind this?

答: try to copy the files orannzsbb11.dll , oci.dll and oraociei11.dll to c:\windows\system32</p>

Body:
I installed PHP in window 7, running simple PHP without issue.
when I want to connect oracle db 11g XE, using $conn = oci_connect ($user, $pawd, 'localhost/XE'); I get the following errors:

Unable to load dynamic library 'C:\PHP\ext\php_oci8.dll' ...
Unable to load dynamic library 'C:\PHP\ext\php_oci8_11g.dll' ...
PHP Fatal error: Call to undefined function oci_connect (..);

I checked that C:\PHP\ext\php_oci8.dll is there and I changed the following in php.ini file.

extension_dir = "C:\PHP\exe";
extension=php_bz2.dll;
extension=php_curl.dll;
extension=php_oci8.dll;
extension=php_oci8_11g.dll;

what is the issue behind this?


问:
Access attributes of a matplotlib plot made through pandas plot function
Say I have a pandas dataframe and I plot it with matplotlib via the pandas built-in function plot:

```<code>mydata = list(zip([1, 2, 3], [4, 5, 6]))
dataframe = pandas.DataFrame(mydata)
barchart = dataframe.plot(kind = 'bar')
</code>```

How do I access the color of the bars?

More generally, how do I access all the attributes?

E.g. I can get the background color with barchart.get_axis_bgcolor() and I can set it to grey with barchart.set_axis_bgcolor('grey'), but what about all the other attributes?

答:
To change the color of a series you can do this with colors,

```<code>mydata = list(zip([1, 2, 3], [4, 5, 6]))
dataframe = pd.DataFrame(mydata)
barchart = dataframe.plot(kind = 'bar',color=['maroon','purple'])
</code>```

However, with the barchart variable you have a handle on the axes, now you can use get_children() to get a hold of any patches, text, axis, or any other object in the chart to modify just about anything you want.

Body:
Say I have a pandas dataframe and I plot it with matplotlib via the pandas built-in function plot:

mydata = list(zip([1, 2, 3], [4, 5, 6]))
dataframe = pandas.DataFrame(mydata)
barchart = dataframe.plot(kind = 'bar')

How do I access the color of the bars?

More generally, how do I access all the attributes?

E.g. I can get the background color with barchart.get_axis_bgcolor() and I can set it to grey with barchart.set_axis_bgcolor('grey'), but what about all the other attributes?

Body:
To change the color of a series you can do this with colors,

mydata = list(zip([1, 2, 3], [4, 5, 6]))
dataframe = pd.DataFrame(mydata)
barchart = dataframe.plot(kind = 'bar',color=['maroon','purple'])

However, with the barchart variable you have a handle on the axes, now you can use get_children() to get a hold of any patches, text, axis, or any other object in the chart to modify just about anything you want.