问:
Create multiple select box with output in string format
I'm trying to set up a multiple select box on my project that would provide output into one of my string fields in sql table. So far from what I've figured <% f.select %> with multiple set to true tries to pass an array instead of string, and that doesn't work for my project (in past this was a text field, but now it's required to only allow a selection of preset values to be put in it, and it's on live project, so no drastic changes). I found that doing something like this

```<code>@keywords = params['keywords']['keywords'].join(', ')
</code>```

would solve my problem, but I'm not sure how to implement it in my controller.

Code fragment I currently have for select in views is:

```<code><%= f.select :keywords, ['kw1', 'kw2', 'kw3', 'kw4', 'kw5'], {}, { :multiple => true, :size => 10, :class => 'form-control' } %>
</code>```

code segment from controller for creating new article currently is pretty basic:

```<code>@article = Article.new
</code>```

"keywords" is a string field in article table.

EDIT: Here is whole controller:

```<code>class ArticlesController < ApplicationController
  PRIORITY_COUNTRIES = %w[RU BR IN CN ZA]
  http_basic_authenticate_with name: "***", password: "***", except: [:index, :show]

  def index
    if params[:search] == nil
      @articles = Article.filter(params.slice(:category, :country, :src_url, :date, :lang, :keywords, :title, :rel)).where(is_active: true).order('id DESC').paginate(:page => params[:page])
    else
      @articles = Article.search(params[:search], :without => {:is_active => false}, :page => params[:page], :per_page => 9, :order => :id)
    end

    @countries = ISO3166::Country.countries.sort_by do |country|
      priority_index = PRIORITY_COUNTRIES.index(country.alpha2)
      priority_index.present? ? priority_index.to_s : country.name
    end
  end

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def edit
    @article = Article.find(params[:id])
  end

  def create
    @article = Article.new(article_params)

    if @article.save
      redirect_to @article
    else
      render 'new'
    end
  end

  def update
    @article = Article.find(params[:id])

    if @article.update(article_params)
      redirect_to @article
    else
      render 'edit'
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.update(:is_active => false)

    redirect_to articles_path
  end

  def undelete
    @articles = Article.where(is_active: false).paginate(:per_page => 15, :page => params[:page])
  end

  def undestroy
    @article = Article.find(params[:id])
    @article.update(:is_active => true)

    redirect_to undelete_articles_path
  end

  private
    def article_params
      params.require(:article).permit(:title, :date, :src_url, :country, :author, :category, :keywords, :keywords2, :text, :lang, :rel)
    end
end
</code>```

And model:

```<code>class Article < ApplicationRecord
  before_validation do |article|
    article.keywords.reject!(&:blank?) if article.keywords
  end

  self.per_page = 9
  include Filterable
  validates :country, presence: true, length: { minimum: 2 }
  validates :category, presence: true
  validates :src_url, presence: true

  validates :keywords2, presence: true
  validates :text, presence: true, length: { minimum: 5 }
  validates :date, presence: true

  scope :country, -> (country) { where country: country }
  scope :category, -> (category) { where category: category }
  scope :src_url, -> (src_url) { where('src_url like ?', "%#{src_url}%")}
  scope :date, -> (date) { where date: date }
  scope :keywords, -> (keywords) { where('keywords like ?', "%#{keywords}%")}
  scope :title, -> (title) { where('title LIKE ?', "%#{title}%")}
  scope :rel, -> (rel) { where rel: rel }
end
</code>```

答:
I believe using a multi select for a string field will be formatted as a JSON array when passed to the controller.

So, your params that hit the controller would look something like the following:

{ keywords: { keywords: '["kw1", "kw12"]' } }

Therefore, to store it in the db as a comma separated string, you'll need to parse it first, using something like the following:

JSON.parse(params[:keywords][:keywords]).reject(&:blank?).join(', ')

Couple of gotchas here:

Using a multiselect like this will often (always?) return an empty value first, hence reject(&:blank?).

If the params return nil, trying to parse this raises an error, so you might want to define a method to handle this, such as:

```<code>def string_from_json(vals)
  return unless vals.present?
  JSON.parse(vals).reject(&:blank?).join(', ')
end
</code>```

Or you could rescue JSON::ParseError or something.

Finally, you'd call keywords = string_from_json(params[:keywords][:keywords]) to get the string.

Hope that helps!

Edit:

That'll handle the parsing, and then you can assign this in the controller with a simple @article.keywords = keywords, @article.update_attribute(:keywords, keywords) in the controller, or the approach recommended by Daniel.

Body:
I'm trying to set up a multiple select box on my project that would provide output into one of my string fields in sql table. So far from what I've figured <% f.select %> with multiple set to true tries to pass an array instead of string, and that doesn't work for my project (in past this was a text field, but now it's required to only allow a selection of preset values to be put in it, and it's on live project, so no drastic changes). I found that doing something like this

@keywords = params['keywords']['keywords'].join(', ')

would solve my problem, but I'm not sure how to implement it in my controller.

Code fragment I currently have for select in views is:

<%= f.select :keywords, ['kw1', 'kw2', 'kw3', 'kw4', 'kw5'], {}, { :multiple => true, :size => 10, :class => 'form-control' } %>

code segment from controller for creating new article currently is pretty basic:

@article = Article.new

"keywords" is a string field in article table.

EDIT: Here is whole controller:

class ArticlesController < ApplicationController
  PRIORITY_COUNTRIES = %w[RU BR IN CN ZA]
  http_basic_authenticate_with name: "***", password: "***", except: [:index, :show]

  def index
    if params[:search] == nil
      @articles = Article.filter(params.slice(:category, :country, :src_url, :date, :lang, :keywords, :title, :rel)).where(is_active: true).order('id DESC').paginate(:page => params[:page])
    else
      @articles = Article.search(params[:search], :without => {:is_active => false}, :page => params[:page], :per_page => 9, :order => :id)
    end

    @countries = ISO3166::Country.countries.sort_by do |country|
      priority_index = PRIORITY_COUNTRIES.index(country.alpha2)
      priority_index.present? ? priority_index.to_s : country.name
    end
  end

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def edit
    @article = Article.find(params[:id])
  end

  def create
    @article = Article.new(article_params)

    if @article.save
      redirect_to @article
    else
      render 'new'
    end
  end

  def update
    @article = Article.find(params[:id])

    if @article.update(article_params)
      redirect_to @article
    else
      render 'edit'
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.update(:is_active => false)

    redirect_to articles_path
  end

  def undelete
    @articles = Article.where(is_active: false).paginate(:per_page => 15, :page => params[:page])
  end

  def undestroy
    @article = Article.find(params[:id])
    @article.update(:is_active => true)

    redirect_to undelete_articles_path
  end

  private
    def article_params
      params.require(:article).permit(:title, :date, :src_url, :country, :author, :category, :keywords, :keywords2, :text, :lang, :rel)
    end
end

And model:

class Article < ApplicationRecord
  before_validation do |article|
    article.keywords.reject!(&:blank?) if article.keywords
  end

  self.per_page = 9
  include Filterable
  validates :country, presence: true, length: { minimum: 2 }
  validates :category, presence: true
  validates :src_url, presence: true

  validates :keywords2, presence: true
  validates :text, presence: true, length: { minimum: 5 }
  validates :date, presence: true

  scope :country, -> (country) { where country: country }
  scope :category, -> (category) { where category: category }
  scope :src_url, -> (src_url) { where('src_url like ?', "%#{src_url}%")}
  scope :date, -> (date) { where date: date }
  scope :keywords, -> (keywords) { where('keywords like ?', "%#{keywords}%")}
  scope :title, -> (title) { where('title LIKE ?', "%#{title}%")}
  scope :rel, -> (rel) { where rel: rel }
end

Body:
I believe using a multi select for a string field will be formatted as a JSON array when passed to the controller.

So, your params that hit the controller would look something like the following:

{ keywords: { keywords: '["kw1", "kw12"]' } }

Therefore, to store it in the db as a comma separated string, you'll need to parse it first, using something like the following:

JSON.parse(params[:keywords][:keywords]).reject(&:blank?).join(', ')

Couple of gotchas here:

Using a multiselect like this will often (always?) return an empty value first, hence reject(&:blank?).

If the params return nil, trying to parse this raises an error, so you might want to define a method to handle this, such as:

def string_from_json(vals)
  return unless vals.present?
  JSON.parse(vals).reject(&:blank?).join(', ')
end

Or you could rescue JSON::ParseError or something.

Finally, you'd call keywords = string_from_json(params[:keywords][:keywords]) to get the string.

Hope that helps!

Edit:

That'll handle the parsing, and then you can assign this in the controller with a simple @article.keywords = keywords, @article.update_attribute(:keywords, keywords) in the controller, or the approach recommended by Daniel.


来源: stackexchange

问:
ansible: sudo and change user
Could you please advise how

```<code>sudo su - userb
</code>```

translates into ansible ?

More specifically, I would like to login to linux server X as usera then become userb (with the command above), and then execute all the tasks defined in the playbook as userb

The following are configuration options in ansible.cfg:

```<code>sudo_user      = root
#ask_sudo_pass = True
#ask_pass      = True
#remote_user = root
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
</code>```

An example task would be:

```<code>- name: "Create the version directory of app"
        remote_user: userb
        file: path="{{ app_dir }}/{{ app_version }}" state=directory owner=userb group=xxx
</code>```

EDIT: please note that no sudo password is provided in order to become userb

```<code>usera@serverX:~> sudo su - userb
Last login: Fri Nov 17 15:46:48 CET 2017 on pts/1
-bash-4.2$
</code>```

答:
In order to run any particular tasks as a different user, do the following:

```<code>- name: "Create the version directory of app"
        file: path="{{ app_dir }}/{{ app_version }}" state=directory owner=userb group=userb
        become: yes
        become_user: userb
</code>```

Reference: http://docs.ansible.com/ansible/latest/become.html

Oh and you should change remote_user to the user who you want to log into the server with and that should probably be in the inventory file.

ContentLicense: CC BY-SA 3.0

Title: ansible: sudo and change user

Body:
Could you please advise how

sudo su - userb

translates into ansible ?

More specifically, I would like to login to linux server X as usera then become userb (with the command above), and then execute all the tasks defined in the playbook as userb

The following are configuration options in ansible.cfg:

sudo_user      = root
#ask_sudo_pass = True
#ask_pass      = True
#remote_user = root
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False

An example task would be:

- name: "Create the version directory of app"
        remote_user: userb
        file: path="{{ app_dir }}/{{ app_version }}" state=directory owner=userb group=xxx

EDIT: please note that no sudo password is provided in order to become userb

usera@serverX:~> sudo su - userb
Last login: Fri Nov 17 15:46:48 CET 2017 on pts/1
-bash-4.2$

Body:
In order to run any particular tasks as a different user, do the following:

- name: "Create the version directory of app"
        file: path="{{ app_dir }}/{{ app_version }}" state=directory owner=userb group=userb
        become: yes
        become_user: userb

Reference: http://docs.ansible.com/ansible/latest/become.html

Oh and you should change remote_user to the user who you want to log into the server with and that should probably be in the inventory file.


问:
c# Math/Formula Calculation
I have an interesting problem i am trying to solve in my c# project, my head is hurting so any advice would be greatly appreciated

Basically i have an employee that works on a 3 week cycle

wk 1 - they work mon

wk 2 - they work wed

wk 3 - they work fri

wk 4 - they work mon

wk 5 - they work wed
.. and so on

I need a formula that will show me what day they worked on any given week, ie what day would they work on week 49 of employment?

Any thoughts on how i may solve this equation?

Cheers
Anthony

答:
This will give the desired output:</p>

```<code>using System;
using System.Collections.Generic;

public static void WhichDaysAreTheyWorking()
{
   List<String> daysOfTheWeek = new List<String>();
   daysOfTheWeek.Add("Monday");
   daysOfTheWeek.Add("Tuesday");
   daysOfTheWeek.Add("Wednesday");
   daysOfTheWeek.Add("Thursday");
   daysOfTheWeek.Add("Friday");
   daysOfTheWeek.Add("Saturday");
   daysOfTheWeek.Add("Sunday");
   int i = 0;
   for (int week = 1; week < 50; week++)
   {
      if (daysOfTheWeek[i].Equals("Friday"))
      {
          Console.WriteLine("Week # " + week + " They work " + daysOfTheWeek[i]);
          Console.WriteLine("Week # " + (week + 1) + " They work " + daysOfTheWeek[i - 4]);
          i = 2;
          week = week + 1;
          continue;
      }
      else
      {
          Console.WriteLine("Week # " + week + "They work " + daysOfTheWeek[i]);
          i = i + 2;
      }
   }
   Console.ReadKey();
}
</code>```

Title: c# Math/Formula Calculation

Body:
This will give the desired output:

using System;
using System.Collections.Generic;

public static void WhichDaysAreTheyWorking()
{
   List<String> daysOfTheWeek = new List<String>();
   daysOfTheWeek.Add("Monday");
   daysOfTheWeek.Add("Tuesday");
   daysOfTheWeek.Add("Wednesday");
   daysOfTheWeek.Add("Thursday");
   daysOfTheWeek.Add("Friday");
   daysOfTheWeek.Add("Saturday");
   daysOfTheWeek.Add("Sunday");
   int i = 0;
   for (int week = 1; week < 50; week++)
   {
      if (daysOfTheWeek[i].Equals("Friday"))
      {
          Console.WriteLine("Week # " + week + " They work " + daysOfTheWeek[i]);
          Console.WriteLine("Week # " + (week + 1) + " They work " + daysOfTheWeek[i - 4]);
          i = 2;
          week = week + 1;
          continue;
      }
      else
      {
          Console.WriteLine("Week # " + week + "They work " + daysOfTheWeek[i]);
          i = i + 2;
      }
   }
   Console.ReadKey();
}


问:
SSRS - Calculation expression from two different Dataset
I have a report that has 2 dataset (Dataset1 and Dateset2) both have the same fields.  How can I calculate the difference between DataSet1 - Opted In and Dataset 2 - Opted in?

For example: Dataset 1 - Opted In has 5000; Dataset 2 - Opted In has 10000, in the Opted difference column it should provide 5000 difference.

I tried the expression below, but it is not providing the difference result.

```<code>=Join(Lookup(Fields!Month.Value, Fields!Month.Value,(ReportItems!OptedIn3.Value)-(ReportItems!OptedIn4.Value),"THOR_Monthly"))
</code>```

答:
You can use the query

```<code>=Fields!OptedIn.Value-Lookup(Fields!Month.Value,Fields!Month.Value,Fields!OptedIn.Value,"DataSet1")
</code>```

change the name of the fields if it is different in your tables

Body:
I have a report that has 2 dataset (Dataset1 and Dateset2) both have the same fields.  How can I calculate the difference between DataSet1 - Opted In and Dataset 2 - Opted in?

For example: Dataset 1 - Opted In has 5000; Dataset 2 - Opted In has 10000, in the Opted difference column it should provide 5000 difference.

I tried the expression below, but it is not providing the difference result.

=Join(Lookup(Fields!Month.Value, Fields!Month.Value,(ReportItems!OptedIn3.Value)-(ReportItems!OptedIn4.Value),"THOR_Monthly"))

Body:
You can use the query

=Fields!OptedIn.Value-Lookup(Fields!Month.Value,Fields!Month.Value,Fields!OptedIn.Value,"DataSet1")

change the name of the fields if it is different in your tables


问:
pandas, set value for column y,z on condition of column x with outsource data
there is a data with columns=[x,t,y,z], and I want to fill column [y,z] with outsource data.

The following codes works fine for fill column y.

```<code>    # data I want to fill
df=pd.DataFrame([['x1','t','NaN','Nan'],['x2','t','NaN','Nan'],
                 ['x2','t','NaN','Nan'],['x3','t','NaN','Nan'],
                 ['x3','t','NaN','Nan'],['x4','t','NaN','Nan'],
                 ['x5','t','NaN','Nan']],
                 columns=list(['x','t','y','z']))

# source data
source=pd.DataFrame([['x1','y1','z1'],['x2','y2','z2'],['x3','y3','z3'],
                     ['x4','y4','z4']],columns=list(['x','y','z']))

print('df before\n',df)

def applyFunc(x):
    for i in range(0,len(source)):
        if x==source.at[i,'x']:
            return source.at[i,'y']
    else:
        return 1

df['y']=df['x'].apply(applyFunc)

print('\n\ndf after:\n',df)
</code>```

the result it runs is as following:

```<code>df before
     x  t    y    z
0  x1  t  NaN  Nan
1  x2  t  NaN  Nan
2  x2  t  NaN  Nan
3  x3  t  NaN  Nan
4  x3  t  NaN  Nan
5  x4  t  NaN  Nan
6  x5  t  NaN  Nan

df after:
     x  t   y    z
0  x1  t  y1  Nan
1  x2  t  y2  Nan
2  x2  t  y2  Nan
3  x3  t  y3  Nan
4  x3  t  y3  Nan
5  x4  t  y4  Nan
6  x5  t   1  Nan
</code>```

what I want is filling columns [y,z] at one time.
the result I want to get like this.

```<code>df after:
         x  t   y    z
    0  x1  t  y1  z1
    1  x2  t  y2  z2
    2  x2  t  y2  z2
    3  x3  t  y3  z3
    4  x3  t  y3  z3
    5  x4  t  y4  z4
    6  x5  t   1  1
</code>```

I have tried, but I haven't find a way to get it.I tried the following code

```<code>def applyFunc(x):
    for i in range(0,len(source)):
        if x==source.at[i,'x']:
            return (source.at[i,'y'],source.at[i,'z'])
    else:
        return (1,1)

df['y','z']=df['x'].apply(applyFunc)
</code>```

while the result is like this.

```<code>df after:
     x  t    y    z    (y, z)
0  x1  t  NaN  Nan  (y1, z1)
1  x2  t  NaN  Nan  (y2, z2)
2  x2  t  NaN  Nan  (y2, z2)
3  x3  t  NaN  Nan  (y3, z3)
4  x3  t  NaN  Nan  (y3, z3)
5  x4  t  NaN  Nan  (y4, z4)
6  x5  t  NaN  Nan    (1, 1)
</code>```

答:
You can modify your function like this:

```<code>def applyFunc(x, col):
    for i in range(0, len(source)):
        if x == source.at[i, 'x']:
            return source.at[i, col]
    else:
        return 1
</code>```

And then simply:

```<code>df['y'] = df['x'].apply(applyFunc, col='y')
df['z'] = df['x'].apply(applyFunc, col='z')
</code>```

Of course you can loop across 'y' and 'z' like so:

```<code>for col in ['y', 'z']:
    df[col] = df['x'].apply(applyFunc, col=col)
</code>```

Or, if you really want it in one line:

```<code>df['y'], df['z'] = df['x'].apply(applyFunc, col='y'), df['x'].apply(applyFunc, col='z')
</code>```

Body:
there is a data with columns=[x,t,y,z], and I want to fill column [y,z] with outsource data.

The following codes works fine for fill column y.

    # data I want to fill
df=pd.DataFrame([['x1','t','NaN','Nan'],['x2','t','NaN','Nan'],
                 ['x2','t','NaN','Nan'],['x3','t','NaN','Nan'],
                 ['x3','t','NaN','Nan'],['x4','t','NaN','Nan'],
                 ['x5','t','NaN','Nan']],
                 columns=list(['x','t','y','z']))

# source data
source=pd.DataFrame([['x1','y1','z1'],['x2','y2','z2'],['x3','y3','z3'],
                     ['x4','y4','z4']],columns=list(['x','y','z']))

print('df before\n',df)

def applyFunc(x):
    for i in range(0,len(source)):
        if x==source.at[i,'x']:
            return source.at[i,'y']
    else:
        return 1

df['y']=df['x'].apply(applyFunc)

print('\n\ndf after:\n',df)

the result it runs is as following:

df before
     x  t    y    z
0  x1  t  NaN  Nan
1  x2  t  NaN  Nan
2  x2  t  NaN  Nan
3  x3  t  NaN  Nan
4  x3  t  NaN  Nan
5  x4  t  NaN  Nan
6  x5  t  NaN  Nan

df after:
     x  t   y    z
0  x1  t  y1  Nan
1  x2  t  y2  Nan
2  x2  t  y2  Nan
3  x3  t  y3  Nan
4  x3  t  y3  Nan
5  x4  t  y4  Nan
6  x5  t   1  Nan

what I want is filling columns [y,z] at one time.
the result I want to get like this.

df after:
         x  t   y    z
    0  x1  t  y1  z1
    1  x2  t  y2  z2
    2  x2  t  y2  z2
    3  x3  t  y3  z3
    4  x3  t  y3  z3
    5  x4  t  y4  z4
    6  x5  t   1  1

I have tried, but I haven't find a way to get it.I tried the following code

def applyFunc(x):
    for i in range(0,len(source)):
        if x==source.at[i,'x']:
            return (source.at[i,'y'],source.at[i,'z'])
    else:
        return (1,1)

df['y','z']=df['x'].apply(applyFunc)

while the result is like this.

df after:
     x  t    y    z    (y, z)
0  x1  t  NaN  Nan  (y1, z1)
1  x2  t  NaN  Nan  (y2, z2)
2  x2  t  NaN  Nan  (y2, z2)
3  x3  t  NaN  Nan  (y3, z3)
4  x3  t  NaN  Nan  (y3, z3)
5  x4  t  NaN  Nan  (y4, z4)
6  x5  t  NaN  Nan    (1, 1)

Body:
You can modify your function like this:

def applyFunc(x, col):
    for i in range(0, len(source)):
        if x == source.at[i, 'x']:
            return source.at[i, col]
    else:
        return 1

And then simply:

df['y'] = df['x'].apply(applyFunc, col='y')
df['z'] = df['x'].apply(applyFunc, col='z')

Of course you can loop across 'y' and 'z' like so:

for col in ['y', 'z']:
    df[col] = df['x'].apply(applyFunc, col=col)

Or, if you really want it in one line:

df['y'], df['z'] = df['x'].apply(applyFunc, col='y'), df['x'].apply(applyFunc, col='z')


问:
How can I generate another entry widget when I press enter
I am making a tournament software and I want to make it so when I press enter, another entry widget appears, this is my code</p>

```<code>from tkinter import*
import time
import sys
master = Tk()
master.title('Tournament Software')
master.geometry("800x800")
master.configure(background="black")
def end():
    master.destroy()
def click1():
    master.destroy()
    master1 = Tk()
    master1.title("Tournament Software")
    master1.geometry("800x800")
    master1.configure(background="black")
    la=Label(master1, text="Enter Contestant Names:",font="none 50 bold", fg="white", bg="black").pack()
    #I don't know what to put here
    e=Entry(master1, bd=10,width=50).pack()
l=Label(master, text="Tournament Software", font="none 50 bold", bg="black", fg="white").pack()
b=Button(master, text="Start",font="none 50 bold",command = click1).pack(side=LEFT)
b1=Button(master, text="Quit",font="none 55 bold",command = end).pack(side=RIGHT)
mainloop()
</code>```

答:
Below code generates a new entry widget each time Enter is pressed:</p>

```<code>import tkinter as tk

root = tk.Tk()

entryList = list()

def enter_event(event):
    entryList.append(tk.Entry(root))

    entryList[-1].pack()

root.bind("<Return>", enter_event)

root.mainloop()
</code>```

Body:
I am making a tournament software and I want to make it so when I press enter, another entry widget appears, this is my code

from tkinter import*
import time
import sys
master = Tk()
master.title('Tournament Software')
master.geometry("800x800")
master.configure(background="black")
def end():
    master.destroy()
def click1():
    master.destroy()
    master1 = Tk()
    master1.title("Tournament Software")
    master1.geometry("800x800")
    master1.configure(background="black")
    la=Label(master1, text="Enter Contestant Names:",font="none 50 bold", fg="white", bg="black").pack()
    #I don't know what to put here
    e=Entry(master1, bd=10,width=50).pack()
l=Label(master, text="Tournament Software", font="none 50 bold", bg="black", fg="white").pack()
b=Button(master, text="Start",font="none 50 bold",command = click1).pack(side=LEFT)
b1=Button(master, text="Quit",font="none 55 bold",command = end).pack(side=RIGHT)
mainloop()

Body:
Below code generates a new entry widget each time Enter is pressed:

import tkinter as tk

root = tk.Tk()

entryList = list()

def enter_event(event):
    entryList.append(tk.Entry(root))

    entryList[-1].pack()

root.bind("<Return>", enter_event)

root.mainloop()


问:
Java Jframe get input and write to file
I have one project that I want to get input from jframe. I have to input 3 people data in only one time when code was running and write that data into file name person.txt.Those data have Name Nickname Age and when i compile my code, It dosn't work and I just only write one data in person.txt file. Help me please? I can't get those in my project. what should i do ? </p>

```<code> public class JavaGui {
  public String data = "";
  JFrame f;
  JLabel l1, l2, l3;
  JTextField tf1, tf2, tf3;
  JButton b;
  JavaGui() {

   FileWriter fw = null;
   try {
    fw = new FileWriter("person.txt");
   } catch (IOException ex) {
    Logger.getLogger(JavaGui.class.getName()).log(Level.SEVERE, null, ex);
   }

   PrintWriter pw = new PrintWriter(fw);

   f = new JFrame("Java GUI");
   l1 = new JLabel("Name");
   l1.setBounds(20, 50, 80, 30);
   tf1 = new JTextField();
   tf1.setBounds(100, 50, 200, 30);

   l2 = new JLabel("Nickname");
   l2.setBounds(20, 100, 80, 30);
   tf2 = new JTextField();
   tf2.setBounds(100, 100, 200, 30);

   l3 = new JLabel("Age");
   l3.setBounds(20, 150, 80, 30);
   tf3 = new JTextField();
   tf3.setBounds(100, 150, 200, 30);

   b = new JButton("Save");
   b.setBounds(100, 200, 70, 30);

   f.add(l1);
   f.add(tf1);
   f.add(l2);
   f.add(tf2);
   f.add(l3);
   f.add(tf3);
   f.add(b);
   f.setSize(350, 350);
   f.setLayout(null);
   f.setLocationRelativeTo(null);
   f.setResizable(false);
   f.setVisible(true);
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

   for (int i = 0; i < 3; i++) {
    b.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {

      String name = "";
      String nickname = "";
      String ageS = "";
      int age = 0;
      try {
       name = "Name : " + tf1.getText();
       nickname = "Nickname : " + tf2.getText();
       age = Integer.parseInt(tf3.getText());

       if (age > 0 && age < 100) {
        ageS = "Age : " + age;
       } else {
        JOptionPane.showMessageDialog(null, "Please Enter Age field by Positive number Or Less than 100");
       }
      } catch (NumberFormatException ex) {
       JOptionPane.showMessageDialog(null, "Please enter Age field by number type");

      }

      data += name + " " + nickname + " " + ageS;

      pw.println(data);
      pw.close();

     }

    });
   }

  }

  public static void main(String[] args) {
   new JavaGui();
  }

 }
</code>```

答:
Tested and working fine.I have added next button so each time you append new data in StringBuilder and at the end you can save that persons.You can remove the counter(i have added counter to add only 3 persons) and make it without limit.</p>

```<code>import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JavaGui {
JFrame f;
JLabel l1, l2, l3;
JTextField tf1, tf2, tf3;
JButton b,next;
int counter;

StringBuilder data = new StringBuilder();
JavaGui() {}

public static void main(String[] args) {

    FileWriter fw = null;
    try{
        fw = new FileWriter("person.txt");
        PrintWriter pw = new PrintWriter(fw);
        new JavaGui().go(pw);

       }catch (IOException ex) {
        Logger.getLogger(JavaGui.class.getName()).log(Level.SEVERE, null, ex);
    }

}

public void go(PrintWriter pw) {

    f = new JFrame("Java GUI");
    l1 = new JLabel("Name");
    l1.setBounds(20, 50, 80, 30);
    tf1 = new JTextField();
    tf1.setBounds(100, 50, 200, 30);

    l2 = new JLabel("Nickname");
    l2.setBounds(20, 100, 80, 30);
    tf2 = new JTextField();
    tf2.setBounds(100, 100, 200, 30);

    l3 = new JLabel("Age");
    l3.setBounds(20, 150, 80, 30);
    tf3 = new JTextField();
    tf3.setBounds(100, 150, 200, 30);

    next = new JButton("Next");
    next.setBounds(100, 200, 70, 30);

    b = new JButton("Save");
    b.setBounds(180, 200, 70, 30);

    f.add(l1);f.add(tf1);
    f.add(l2);f.add(tf2);
    f.add(l3);f.add(tf3);
    f.add(next);
    f.add(b);
    f.setSize(350, 350);
    f.setLayout(null);
    f.setLocationRelativeTo(null);
    f.setResizable(false);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    next.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            String name = "";
            String nickname = "";
            String ageS = "";
            int age = 0;

              try{
                name = "Name : " + tf1.getText();
                nickname = "Nickname : " + tf2.getText();
                age =Integer.parseInt(tf3.getText());

                if(age > 0 && age < 100) {
                    ageS = "Age : " + age;
                }else{
                    JOptionPane.showMessageDialog(null, "Please Enter Age field by Positive number Or Less than 100");
                }
               }catch(NumberFormatException ex){
                JOptionPane.showMessageDialog(null, "Please enter Age field by number type");
               }

               data.append(name + " " + nickname + " " + ageS);
               data.append(System.getProperty("line.separator"));

               counter++;

               tf1.setText("");
               tf2.setText("");
               tf3.setText("");

               if(counter > 2)
                   next.setEnabled(false);
        }

    });

    b.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){

            pw.print(data.toString());
            pw.close();

        }

    });
 }

}
</code>```

Title: Java Jframe get input and write to file

Body:
I have one project that I want to get input from jframe. I have to input 3 people data in only one time when code was running and write that data into file name person.txt.Those data have Name Nickname Age and when i compile my code, It dosn't work and I just only write one data in person.txt file. Help me please? I can't get those in my project. what should i do ?

 public class JavaGui {
  public String data = "";
  JFrame f;
  JLabel l1, l2, l3;
  JTextField tf1, tf2, tf3;
  JButton b;
  JavaGui() {

   FileWriter fw = null;
   try {
    fw = new FileWriter("person.txt");
   } catch (IOException ex) {
    Logger.getLogger(JavaGui.class.getName()).log(Level.SEVERE, null, ex);
   }

   PrintWriter pw = new PrintWriter(fw);

   f = new JFrame("Java GUI");
   l1 = new JLabel("Name");
   l1.setBounds(20, 50, 80, 30);
   tf1 = new JTextField();
   tf1.setBounds(100, 50, 200, 30);

   l2 = new JLabel("Nickname");
   l2.setBounds(20, 100, 80, 30);
   tf2 = new JTextField();
   tf2.setBounds(100, 100, 200, 30);

   l3 = new JLabel("Age");
   l3.setBounds(20, 150, 80, 30);
   tf3 = new JTextField();
   tf3.setBounds(100, 150, 200, 30);

   b = new JButton("Save");
   b.setBounds(100, 200, 70, 30);

   f.add(l1);
   f.add(tf1);
   f.add(l2);
   f.add(tf2);
   f.add(l3);
   f.add(tf3);
   f.add(b);
   f.setSize(350, 350);
   f.setLayout(null);
   f.setLocationRelativeTo(null);
   f.setResizable(false);
   f.setVisible(true);
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

   for (int i = 0; i < 3; i++) {
    b.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {

      String name = "";
      String nickname = "";
      String ageS = "";
      int age = 0;
      try {
       name = "Name : " + tf1.getText();
       nickname = "Nickname : " + tf2.getText();
       age = Integer.parseInt(tf3.getText());

       if (age > 0 && age < 100) {
        ageS = "Age : " + age;
       } else {
        JOptionPane.showMessageDialog(null, "Please Enter Age field by Positive number Or Less than 100");
       }
      } catch (NumberFormatException ex) {
       JOptionPane.showMessageDialog(null, "Please enter Age field by number type");

      }

      data += name + " " + nickname + " " + ageS;

      pw.println(data);
      pw.close();

     }

    });
   }

  }

  public static void main(String[] args) {
   new JavaGui();
  }

 }

Body:
Tested and working fine.I have added next button so each time you append new data in StringBuilder and at the end you can save that persons.You can remove the counter(i have added counter to add only 3 persons) and make it without limit.

import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JavaGui {
JFrame f;
JLabel l1, l2, l3;
JTextField tf1, tf2, tf3;
JButton b,next;
int counter;

StringBuilder data = new StringBuilder();
JavaGui() {}

public static void main(String[] args) {

    FileWriter fw = null;
    try{
        fw = new FileWriter("person.txt");
        PrintWriter pw = new PrintWriter(fw);
        new JavaGui().go(pw);

       }catch (IOException ex) {
        Logger.getLogger(JavaGui.class.getName()).log(Level.SEVERE, null, ex);
    }

}

public void go(PrintWriter pw) {

    f = new JFrame("Java GUI");
    l1 = new JLabel("Name");
    l1.setBounds(20, 50, 80, 30);
    tf1 = new JTextField();
    tf1.setBounds(100, 50, 200, 30);

    l2 = new JLabel("Nickname");
    l2.setBounds(20, 100, 80, 30);
    tf2 = new JTextField();
    tf2.setBounds(100, 100, 200, 30);

    l3 = new JLabel("Age");
    l3.setBounds(20, 150, 80, 30);
    tf3 = new JTextField();
    tf3.setBounds(100, 150, 200, 30);

    next = new JButton("Next");
    next.setBounds(100, 200, 70, 30);

    b = new JButton("Save");
    b.setBounds(180, 200, 70, 30);

    f.add(l1);f.add(tf1);
    f.add(l2);f.add(tf2);
    f.add(l3);f.add(tf3);
    f.add(next);
    f.add(b);
    f.setSize(350, 350);
    f.setLayout(null);
    f.setLocationRelativeTo(null);
    f.setResizable(false);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    next.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            String name = "";
            String nickname = "";
            String ageS = "";
            int age = 0;

              try{
                name = "Name : " + tf1.getText();
                nickname = "Nickname : " + tf2.getText();
                age =Integer.parseInt(tf3.getText());

                if(age > 0 && age < 100) {
                    ageS = "Age : " + age;
                }else{
                    JOptionPane.showMessageDialog(null, "Please Enter Age field by Positive number Or Less than 100");
                }
               }catch(NumberFormatException ex){
                JOptionPane.showMessageDialog(null, "Please enter Age field by number type");
               }

               data.append(name + " " + nickname + " " + ageS);
               data.append(System.getProperty("line.separator"));

               counter++;

               tf1.setText("");
               tf2.setText("");
               tf3.setText("");

               if(counter > 2)
                   next.setEnabled(false);
        }

    });

    b.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){

            pw.print(data.toString());
            pw.close();

        }

    });
 }

}


问:
Why do I get this Cloud Firestore Function error?
I get this error in the Cloud Firestore Function log view.

I'm new to JavaScript and Firestore and could use some advice on this

TypeError: event.data.previous.data is not a function at
  exports.onVisitorPres...

```<code>exports.onVisitorPresenceWrite = functions.database
    .ref("/VISITORS_PRESENCE/{uid1}/{uid2}").onWrite((event) => {
        // Get the data written or deleted on the Realtime Database
        var eventStatus = event.data.val();
        const previousData = event.data.previous.data();
        // If the onWrite event is a delete event then use previousData
        if(eventStatus == null){
            eventStatus = previousData;
        }
    });
</code>```

What I want to do is using the .onWrite((event) on a Firebase Realtime databas key and Firestore Function trigger when the key items get deleted and when new items are added.
I thought I could check the eventStatus == null and that is when data is deleted I simply use the previousData (before it got delete??)

答:
The event variable is an instance of Event and therefore calling event.data will return a DeltaDocumentSnapshot for Firestore and a DeltaSnapshot for the Realtime Database.

With a these delta snapshots, you can obtain the previous value with previous which will return another DeltaDocumentSnapshot or DeltaSnapshot containing the previous state from before the write event was triggered.

In your example, you're using a Firebase Realtime Database trigger, which means event.data.previous will return a DeltaSnapshot, which does not support data(), but instead supports val().

In this case, as you've done with var eventStatus = event.data.val();, you need to call val() on previous:

```<code>const previousData = event.data.previous.val();
</code>```

If instead you are trying to use a Firestore trigger, you need to change this:

```<code>functions.database.ref("[...]")
</code>```

To this:

```<code>functions.firestore.document("[...]")
</code>```

And then you can use event.data.previous.data().

Body:
I get this error in the Cloud Firestore Function log view.

I'm new to JavaScript and Firestore and could use some advice on this

TypeError: event.data.previous.data is not a function at
  exports.onVisitorPres...

exports.onVisitorPresenceWrite = functions.database
    .ref("/VISITORS_PRESENCE/{uid1}/{uid2}").onWrite((event) => {
        // Get the data written or deleted on the Realtime Database
        var eventStatus = event.data.val();
        const previousData = event.data.previous.data();
        // If the onWrite event is a delete event then use previousData
        if(eventStatus == null){
            eventStatus = previousData;
        }
    });

What I want to do is using the .onWrite((event) on a Firebase Realtime databas key and Firestore Function trigger when the key items get deleted and when new items are added.
I thought I could check the eventStatus == null and that is when data is deleted I simply use the previousData (before it got delete??)

Body:
The event variable is an instance of Event and therefore calling event.data will return a DeltaDocumentSnapshot for Firestore and a DeltaSnapshot for the Realtime Database.

With a these delta snapshots, you can obtain the previous value with previous which will return another DeltaDocumentSnapshot or DeltaSnapshot containing the previous state from before the write event was triggered.

In your example, you're using a Firebase Realtime Database trigger, which means event.data.previous will return a DeltaSnapshot, which does not support data(), but instead supports val().

In this case, as you've done with var eventStatus = event.data.val();, you need to call val() on previous:

const previousData = event.data.previous.val();

If instead you are trying to use a Firestore trigger, you need to change this:

functions.database.ref("[...]")

To this:

functions.firestore.document("[...]")

And then you can use event.data.previous.data().


问:
How to override sass variable value in other scss file
Suppose I have a application name called MYAPP so here I want to override variable values which are present in _varialble.scss and this is imported in myapplication.scss file, So I want to override the values in new.scss file of variables mentioned in_variable.scss and I should compile this new file if I the URL is having some new parameter like mySite or something...</p>

答:
Simply define the variable again after loading the _variable.scss file. Be sure do define it before any usages though. For example your main.scss could look something like this:

myapplication.scss:

```<code>@import "_variables";
// overwrite your variables from _variables here in new.scss:
@import "new"
// now import the rest of your scss files where you use the variables
@import "site";
@import "module1";
// etc
</code>```

Body:
Simply define the variable again after loading the _variable.scss file. Be sure do define it before any usages though. For example your main.scss could look something like this:

myapplication.scss:

@import "_variables";
// overwrite your variables from _variables here in new.scss:
@import "new"
// now import the rest of your scss files where you use the variables
@import "site";
@import "module1";
// etc


问:
Asynchronicity of a Mongoose Promise
First, pardon my slightly ambiguous title; I could not find a more appropriate one:

Scenario

I am using Mongoose to fetch some data and then render them with ejs. For the sake of illustration, consider the following:

```<code>// Schema
var UserSchema = mongoose.Schema({
  Username: String,
  City: String
})
// Model
var User = mongoose.model('User', UserSchema);
</code>```

From my server file:

```<code>app.get('/view', function (req, res) {
  // What I am trying to do
  User.find({}).exec().then(vals=>{
            res.send(vals)
        })
</code>```

The Problem

The above code works as intended but, to the code accessible to other files as well as making upgrades easier, I want to move it another file, then require() that file.

handler.js

```<code>// Promise: Get All Names
function FetchData(){
    return User
    .find({})
    .exec();
}

module.exports = {
    Get: function(){
        val = User.find({}).exec()
        .then(vals=>{
            // Expected to return only after the above is complete
            return vals
        })
    }

}
</code>```

Then, from my server file:

```<code>var handler = require('handler')

app.get('/view', function (req, res) {
  res.send(handler.Get())
});
</code>```

Unfortunately, this code does not work as intended

My thoughts

I varied the parameters and tweaked the code around a few times but am unable to figure out what is going wrong.
It seems that the values from Get() is being returned even before the promise is consumed (which is puzzling).

Any help would be greatly welcomed :)

答:
I think you should be something like this:

module.exports = {
  Get: function() {
    return User.find({}).exec()
      .then(vals => {
        // Expected to return only after the above is complete
        return vals
      })
  }
}
```

<p>and then</p>

<pre class="lang-javascript prettyprint-override"><code>app.get('/view', function (req, res) {
  handler.Get().then((response) => {
    res.send(response);
  });
});
</code>```

So, return promise from Get and then use its then API.

Title: Asynchronicity of a Mongoose Promise

Body:
First, pardon my slightly ambiguous title; I could not find a more appropriate one:

Scenario

I am using Mongoose to fetch some data and then render them with ejs. For the sake of illustration, consider the following:

// Schema
var UserSchema = mongoose.Schema({
  Username: String,
  City: String
})
// Model
var User = mongoose.model('User', UserSchema);

From my server file:

app.get('/view', function (req, res) {
  // What I am trying to do
  User.find({}).exec().then(vals=>{
            res.send(vals)
        })

The Problem

The above code works as intended but, to the code accessible to other files as well as making upgrades easier, I want to move it another file, then require() that file.

handler.js

// Promise: Get All Names
function FetchData(){
    return User
    .find({})
    .exec();
}

module.exports = {
    Get: function(){
        val = User.find({}).exec()
        .then(vals=>{
            // Expected to return only after the above is complete
            return vals
        })
    }

}

Then, from my server file:

var handler = require('handler')

app.get('/view', function (req, res) {
  res.send(handler.Get())
});

Unfortunately, this code does not work as intended

My thoughts

I varied the parameters and tweaked the code around a few times but am unable to figure out what is going wrong.
It seems that the values from Get() is being returned even before the promise is consumed (which is puzzling).

Any help would be greatly welcomed :)

Body:
I think you should be something like this:

module.exports = {
  Get: function() {
    return User.find({}).exec()
      .then(vals => {
        // Expected to return only after the above is complete
        return vals
      })
  }
}

and then

app.get('/view', function (req, res) {
  handler.Get().then((response) => {
    res.send(response);
  });
});

So, return promise from Get and then use its then API.


问:
How to take a Picture using CameraKit?
I've been building a project that uses the CameraKit by Flurge, and I have a rather annoying issue. I don't actually know how to take a picture. I have a shutter button that when pressed is supposed to activate an OnPicturetaken Listener, but I don't know if it works or not, or whether it is being saved or not. When I click the shutter button on my phone, the logcat returns the dimensions of the picture, which is 13 Mp, but it doesn't save it.

This is the code that runs when the shutter button is pressed:

```<code>cameraView.captureImage();
cameraView.setCameraListener(new CameraListener() {
    @Override
    public void onPictureTaken(byte[] picture) {
        super.onPictureTaken(picture);

        Bitmap result = BitmapFactory.decodeByteArray(picture, 0, picture.length);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        result.compress(Bitmap.CompressFormat.JPEG, 40, stream);
    }
});
</code>```

I tried to set the JPEG quality to 40 to decrease the freeze of the app as it processes the image, but it doesn't help at all. The only output I get is in the logcat of the full resolution of the image, which is 13Mp.

答:
You need to call captureImage(); below the listener.

It looks like you are capturing an image before the listener is even set up. It should look like this.

```<code>cameraView.setCameraListener(new CameraListener() {
    @Override
    public void onPictureTaken(byte[] picture) {
        super.onPictureTaken(picture);

            Bitmap result = BitmapFactory.decodeByteArray(picture, 0,picture.length);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            result.compress(Bitmap.CompressFormat.JPEG, 40, stream);

    }
});
cameraView.captureImage();
</code>```

ContentLicense: CC BY-SA 4.0

Title: How to take a Picture using CameraKit?

Body:
I've been building a project that uses the CameraKit by Flurge, and I have a rather annoying issue. I don't actually know how to take a picture. I have a shutter button that when pressed is supposed to activate an OnPicturetaken Listener, but I don't know if it works or not, or whether it is being saved or not. When I click the shutter button on my phone, the logcat returns the dimensions of the picture, which is 13 Mp, but it doesn't save it.

This is the code that runs when the shutter button is pressed:

cameraView.captureImage();
cameraView.setCameraListener(new CameraListener() {
    @Override
    public void onPictureTaken(byte[] picture) {
        super.onPictureTaken(picture);

        Bitmap result = BitmapFactory.decodeByteArray(picture, 0, picture.length);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        result.compress(Bitmap.CompressFormat.JPEG, 40, stream);
    }
});

I tried to set the JPEG quality to 40 to decrease the freeze of the app as it processes the image, but it doesn't help at all. The only output I get is in the logcat of the full resolution of the image, which is 13Mp.

Body:
You need to call captureImage(); below the listener.

It looks like you are capturing an image before the listener is even set up. It should look like this.

cameraView.setCameraListener(new CameraListener() {
    @Override
    public void onPictureTaken(byte[] picture) {
        super.onPictureTaken(picture);

            Bitmap result = BitmapFactory.decodeByteArray(picture, 0,picture.length);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            result.compress(Bitmap.CompressFormat.JPEG, 40, stream);

    }
});
cameraView.captureImage();


问:
Javascript if else timer on specific days
I am using this code

Here is a codePen to see it. https://codepen.io/celli/pen/jaBrpP But the console doesn't seem to log any of my if else statements, except for the first log. What is wrong in the code, where it is not firing each of my conditions ?

function showDateContent() {
  var d = new Date();
  console.log(d.getDate(), d.getMonth());
  if (d.getDate() >= 4 && d.getDate() <= 17 && d.getMonth() + 1 == 12) {
    console.log("date is between 12/4 and 12/17");
  } else if (d.getDate() >= 18 && d.getDate() <= 30 && d.getMonth() + 1 == 12) {
    console.log("date is between 12/18 and 12/30");
  } else if (d.getDate() >= 31 && d.getMonth() + 1 == 12 || d.getDate() >= 1 && d.getMonth() + 1 == 1) {
    console.log("date is after 12/31/2017 or we are in the New Year of 2018");
  }
}
showDateContent();```

答: Because you are also checking if the month is 12 or 1, while we are currently the eleventh month of the year.


问:
Ionic 2 Error while trying to add platform
My ionic 2 project is running properly when I am doing ionic serve --lab but I am getting the error while I am trying to add Platform in my Ionic 2 Project.

Error While Trying to add iOS

```<code>sudipta$ ionic cordova platform add ios
cordova platform add ios --save

You have been opted out of telemetry. To change this, run: cordova telemetry on.
Using cordova-fetch for cordova-ios@^4.4.0

Error: Failed to fetch platform cordova-ios@^4.4.0
Probably this is either a connection problem, or platform spec is incorrect.
Check your connection and platform name/version/URL.
Error: npm: Command failed with exit code 1 Error output:
npm ERR! Darwin 17.2.0
npm ERR! argv "/usr/local/bin/node" "/Users/sudipta/musicapp/node_modules/.bin/npm" "install" "cordova-ios@^4.4.0" "--production" "--save-exact"
npm ERR! node v6.10.3
npm ERR! npm  v2.15.12
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package @ionic-native/core@3.10.2 does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer @ionic-native/device@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/email-composer@4.4.0 wants @ionic-native/core@^4.2.0
npm ERR! peerinvalid Peer @ionic-native/facebook@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/file@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/media@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/native-audio@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/splash-screen@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/status-bar@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/toast@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/transfer@3.14.0 wants @ionic-native/core@^3.6.0

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/sudipta/musicapp/npm-debug.log

[ERROR] Exception:
sudipta$
</code>```

Error while trying to add Android

```<code>sudipta$ ionic cordova platform add android
> cordova platform add android --save
Using cordova-fetch for cordova-android@6.2.3

Error: Failed to fetch platform cordova-android@6.2.3
Probably this is either a connection problem, or platform spec is incorrect.
Check your connection and platform name/version/URL.
Error: npm: Command failed with exit code 1 Error output:
npm ERR! Darwin 17.2.0
npm ERR! argv "/usr/local/bin/node" "/Users/sudipta/musicapp/node_modules/.bin/npm" "install" "cordova-android@6.2.3" "--production" "--save-exact"
npm ERR! node v6.10.3
npm ERR! npm  v2.15.12
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package @ionic-native/core@3.10.2 does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer @ionic-native/device@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/email-composer@4.4.0 wants @ionic-native/core@^4.2.0
npm ERR! peerinvalid Peer @ionic-native/facebook@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/file@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/media@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/native-audio@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/splash-screen@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/status-bar@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/toast@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/transfer@3.14.0 wants @ionic-native/core@^3.6.0

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/sudipta/musicapp/npm-debug.log

[ERROR] Exception:
sudipta$
</code>```

Error While Trying to browser

```<code>sudipta$ ionic cordova platform add browser
> cordova platform add browser --save
Using cordova-fetch for cordova-browser@^4.1.0

Error: Failed to fetch platform cordova-browser@^4.1.0
Probably this is either a connection problem, or platform spec is incorrect.
Check your connection and platform name/version/URL.
Error: npm: Command failed with exit code 1 Error output:
npm ERR! Darwin 17.2.0
npm ERR! argv "/usr/local/bin/node" "/Users/sudipta/musicapp/node_modules/.bin/npm" "install" "cordova-browser@^4.1.0" "--production" "--save-exact"
npm ERR! node v6.10.3
npm ERR! npm  v2.15.12
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package @ionic-native/core@3.10.2 does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer @ionic-native/device@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/email-composer@4.4.0 wants @ionic-native/core@^4.2.0
npm ERR! peerinvalid Peer @ionic-native/facebook@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/file@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/media@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/native-audio@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/splash-screen@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/status-bar@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/toast@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/transfer@3.14.0 wants @ionic-native/core@^3.6.0

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/sudipta/musicapp/npm-debug.log

[ERROR] Exception:
sudipta$
</code>```

I am using following versions

```<code>sudipta$ ionic -version
3.18.0
sudipta$ node -v
v6.10.3
sudipta$ npm -v
5.5.1
sudipta$ cordova -version
7.1.0
sudipta$
</code>```

my package.json (Updated)

```<code>{
"name": "xxxxxxxxxxx",
"version": "1.0.0",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
},
"dependencies": {
    "@angular/common": "^5.0.2",
    "@angular/compiler": "^5.0.2",
    "@angular/compiler-cli": "^5.0.2",
    "@angular/core": "^5.0.2",
    "@angular/forms": "^5.0.2",
    "@angular/http": "^5.0.2",
    "@angular/platform-browser": "^5.0.2",
    "@angular/platform-browser-dynamic": "^5.0.2",
    "@angular/tsc-wrapped": "^4.4.6",
    "@ionic-native/core": "^4.4.2",
    "@ionic-native/device": "^4.4.2",
    "@ionic-native/email-composer": "^4.4.2",
    "@ionic-native/facebook": "^4.4.2",
    "@ionic-native/file": "^4.4.2",
    "@ionic-native/media": "^4.4.2",
    "@ionic-native/native-audio": "^4.4.2",
    "@ionic-native/splash-screen": "^4.4.2",
    "@ionic-native/status-bar": "^4.4.2",
    "@ionic-native/toast": "^4.4.2",
    "@ionic-native/transfer": "^3.12.1",
    "@ionic/cloud-angular": "^0.12.0",
    "@ionic/pro": "^1.0.16",
    "@ionic/storage": "^2.1.3",
    "angularfire2": "^5.0.0-rc.3",
    "cordova": "^7.0.1",
    "cordova-android": "^6.4.0",
    "cordova-browser": "^5.0.1",
    "cordova-fabric-plugin": "git+https://github.com/sarriaroman/FabricPlugin.git",
    "cordova-ios": "^4.4.0",
    "cordova-plugin-add-swift-support": "^1.7.0",
    "cordova-plugin-compat": "^1.1.0",
    "cordova-plugin-device": "^1.1.7",
    "cordova-plugin-email-composer": "^0.8.7",
    "cordova-plugin-facebook4": "^1.9.1",
    "cordova-plugin-file": "^5.0.0",
    "cordova-plugin-file-transfer": "^1.7.0",
    "cordova-plugin-ionic": "^2.0.3",
    "cordova-plugin-media": "^4.0.0",
    "cordova-plugin-nativeaudio": "^3.0.9",
    "cordova-plugin-splashscreen": "^4.1.0",
    "cordova-plugin-statusbar": "^2.3.0",
    "cordova-plugin-whitelist": "^1.3.3",
    "cordova-plugin-x-toast": "^2.6.0",
    "emulator": "^0.1.0",
    "firebase": "^4.5.0",
    "ionic-angular": "^3.9.2",
    "ionic-plugin-deploy": "^0.6.7",
    "ionic-plugin-keyboard": "^2.2.1",
    "ionicons": "3.0.0",
    "phonegap-plugin-push": "^2.1.0",
    "promise-polyfill": "^6.0.2",
    "react-native": "^0.50.3",
    "rxjs": "^5.5.2",
    "superagent": "^3.8.0",
    "sw-toolbox": "3.6.0",
    "zone.js": "^0.8.18"
},
"devDependencies": {
    "@ionic/app-scripts": "^3.1.2",
    "ionic": "3.18.0",
    "typescript": "^2.6.1"
},
"description": "An Ionic project",
"cordova": {
    "plugins": {
        "cordova-plugin-x-toast": {},
        "cordova-plugin-file-transfer": {},
        "cordova-plugin-file": {},
        "cordova-plugin-console": {},
        "cordova-plugin-device": {},
        "cordova-plugin-splashscreen": {},
        "cordova-plugin-statusbar": {},
        "cordova-plugin-whitelist": {},
        "ionic-plugin-keyboard": {},
        "cordova-plugin-nativeaudio": {},
        "cordova-plugin-facebook4": {
            "APP_ID": "xxxxxxxxxxx",
            "APP_NAME": "MusicApp"
        },
        "cordova-plugin-media": {
            "MICROPHONE_USAGE_DESCRIPTION": " "
        },
        "ionic-plugin-deploy": {},
        "cordova-fabric-plugin": {
            "FABRIC_API_KEY": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "FABRIC_API_SECRET": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        },
        "cordova-plugin-email-composer": {},
        "cordova-plugin-ionic": {
            "APP_ID": "xxxxxxxxxxx",
            "CHANNEL_NAME": "Master",
            "UPDATE_METHOD": "auto",
            "UPDATE_API": "https://api.ionicjs.com",
            "MAX_STORE": "2"
        }
    },
    "platforms": [
        "android",
        "browser",
        "ios"
    ]
}
}
</code>```

Output of ionic info

```<code>sudipta$ ionic info

cli packages: (/Users/sudipta/musicapp/node_modules)

    @ionic/cli-utils  : 1.18.0
    ionic (Ionic CLI) : 3.18.0

global packages:

    cordova (Cordova CLI) : 7.1.0

local packages:

    @ionic/app-scripts : 3.1.2
    Cordova Platforms  : none
    Ionic Framework    : ionic-angular 3.9.2

System:

    Node  : v6.10.3
    npm   : 5.5.1
    OS    : macOS High Sierra
    Xcode : Xcode 8.3.1 Build version 8E1000a

Environment Variables:

    ANDROID_HOME : not set

Misc:

    backend : pro

sudipta$
</code>```

So, I am not able to build the app.
Thanks in advance for your help.

答:
Downgrade all package to 3.12.1 and the problem solved

```<code>{
  "name": "musicapp",
  "version": "1.0.0",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "4.1.3",
    "@angular/compiler": "4.1.3",
    "@angular/compiler-cli": "4.1.3",
    "@angular/core": "4.1.3",
    "@angular/forms": "4.1.3",
    "@angular/http": "4.1.3",
    "@angular/platform-browser": "4.1.3",
    "@angular/platform-browser-dynamic": "4.1.3",
    "@angular/tsc-wrapped": "^4.4.6",
    "@ionic-native/core": "3.10.2",
    "@ionic-native/device": "^3.12.1",
    "@ionic-native/email-composer": "^3.12.1",
    "@ionic-native/facebook": "^3.12.1",
    "@ionic-native/file": "^3.12.1",
    "@ionic-native/media": "^3.13.1",
    "@ionic-native/native-audio": "^3.12.1",
    "@ionic-native/splash-screen": "3.10.2",
    "@ionic-native/status-bar": "3.10.2",
    "@ionic-native/toast": "^3.12.1",
    "@ionic-native/transfer": "^3.12.1",
    "@ionic/cloud-angular": "^0.12.0",
    "@ionic/pro": "^1.0.12",
    "@ionic/storage": "2.0.1",
    "angularfire2": "^5.0.0-rc.3",
    "cordova": "^7.0.1",
    "cordova-browser": "^4.1.0",
    "cordova-fabric-plugin": "git+https://github.com/sarriaroman/FabricPlugin.git",
    "cordova-plugin-add-swift-support": "^1.7.0",
    "cordova-plugin-compat": "^1.1.0",
    "cordova-plugin-console": "^1.0.5",
    "cordova-plugin-device": "^1.1.4",
    "cordova-plugin-email-composer": "^0.8.7",
    "cordova-plugin-facebook4": "^1.9.1",
    "cordova-plugin-file": "~4.3.3",
    "cordova-plugin-file-transfer": "^1.7.0",
    "cordova-plugin-ionic": "^2.0.3",
    "cordova-plugin-media": "^3.0.1",
    "cordova-plugin-nativeaudio": "^3.0.9",
    "cordova-plugin-splashscreen": "^4.0.3",
    "cordova-plugin-statusbar": "^2.2.2",
    "cordova-plugin-whitelist": "^1.3.1",
    "cordova-plugin-x-toast": "^2.6.0",
    "emulator": "^0.1.0",
    "firebase": "^4.5.0",
    "ionic-angular": "3.4.0",
    "ionic-plugin-deploy": "^0.6.7",
    "ionic-plugin-keyboard": "^2.2.1",
    "ionicons": "3.0.0",
    "phonegap-plugin-push": "^1.10.5",
    "promise-polyfill": "^6.0.2",
    "react-native": "^0.17.0",
    "rxjs": "5.4.0",
    "superagent": "^3.8.0",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.12",
    "cordova-ios": "~4.5.3"
  },
  "devDependencies": {
    "@ionic/app-scripts": "^2.1.4",
    "ionic": "3.18.0",
    "typescript": "2.3.3"
  },
  "description": "An Ionic project",
  "cordova": {
    "plugins": {
      "cordova-plugin-x-toast": {},
      "cordova-plugin-file-transfer": {},
      "cordova-plugin-file": {},
      "cordova-plugin-console": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-statusbar": {},
      "cordova-plugin-whitelist": {},
      "ionic-plugin-keyboard": {},
      "cordova-plugin-nativeaudio": {},
      "cordova-plugin-facebook4": {
        "APP_ID": "1385780158175812",
        "APP_NAME": "MusicApp"
      },
      "cordova-plugin-media": {
        "MICROPHONE_USAGE_DESCRIPTION": " "
      },
      "ionic-plugin-deploy": {},
      "cordova-fabric-plugin": {
        "FABRIC_API_KEY": "6ba227e76d0f8627261d0d3bc96d43e6e4916c12",
        "FABRIC_API_SECRET": "2ac1b92ef246209e5611aacdd20e89d988597eac09a8ccc88c9a550748192e47"
      },
      "cordova-plugin-email-composer": {},
      "cordova-plugin-ionic": {
        "APP_ID": "2c035184",
        "CHANNEL_NAME": "Master",
        "UPDATE_METHOD": "auto",
        "UPDATE_API": "https://api.ionicjs.com",
        "MAX_STORE": "2"
      }
    },
    "platforms": [
      "browser",
      "ios"
    ]
  }
}
</code>```

Body:
My ionic 2 project is running properly when I am doing ionic serve --lab but I am getting the error while I am trying to add Platform in my Ionic 2 Project.

Error While Trying to add iOS

sudipta$ ionic cordova platform add ios
cordova platform add ios --save

You have been opted out of telemetry. To change this, run: cordova telemetry on.
Using cordova-fetch for cordova-ios@^4.4.0

Error: Failed to fetch platform cordova-ios@^4.4.0
Probably this is either a connection problem, or platform spec is incorrect.
Check your connection and platform name/version/URL.
Error: npm: Command failed with exit code 1 Error output:
npm ERR! Darwin 17.2.0
npm ERR! argv "/usr/local/bin/node" "/Users/sudipta/musicapp/node_modules/.bin/npm" "install" "cordova-ios@^4.4.0" "--production" "--save-exact"
npm ERR! node v6.10.3
npm ERR! npm  v2.15.12
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package @ionic-native/core@3.10.2 does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer @ionic-native/device@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/email-composer@4.4.0 wants @ionic-native/core@^4.2.0
npm ERR! peerinvalid Peer @ionic-native/facebook@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/file@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/media@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/native-audio@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/splash-screen@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/status-bar@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/toast@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/transfer@3.14.0 wants @ionic-native/core@^3.6.0

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/sudipta/musicapp/npm-debug.log

[ERROR] Exception:
sudipta$

Error while trying to add Android

sudipta$ ionic cordova platform add android
> cordova platform add android --save
Using cordova-fetch for cordova-android@6.2.3

Error: Failed to fetch platform cordova-android@6.2.3
Probably this is either a connection problem, or platform spec is incorrect.
Check your connection and platform name/version/URL.
Error: npm: Command failed with exit code 1 Error output:
npm ERR! Darwin 17.2.0
npm ERR! argv "/usr/local/bin/node" "/Users/sudipta/musicapp/node_modules/.bin/npm" "install" "cordova-android@6.2.3" "--production" "--save-exact"
npm ERR! node v6.10.3
npm ERR! npm  v2.15.12
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package @ionic-native/core@3.10.2 does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer @ionic-native/device@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/email-composer@4.4.0 wants @ionic-native/core@^4.2.0
npm ERR! peerinvalid Peer @ionic-native/facebook@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/file@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/media@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/native-audio@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/splash-screen@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/status-bar@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/toast@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/transfer@3.14.0 wants @ionic-native/core@^3.6.0

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/sudipta/musicapp/npm-debug.log

[ERROR] Exception:
sudipta$

Error While Trying to browser

sudipta$ ionic cordova platform add browser
> cordova platform add browser --save
Using cordova-fetch for cordova-browser@^4.1.0

Error: Failed to fetch platform cordova-browser@^4.1.0
Probably this is either a connection problem, or platform spec is incorrect.
Check your connection and platform name/version/URL.
Error: npm: Command failed with exit code 1 Error output:
npm ERR! Darwin 17.2.0
npm ERR! argv "/usr/local/bin/node" "/Users/sudipta/musicapp/node_modules/.bin/npm" "install" "cordova-browser@^4.1.0" "--production" "--save-exact"
npm ERR! node v6.10.3
npm ERR! npm  v2.15.12
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package @ionic-native/core@3.10.2 does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer @ionic-native/device@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/email-composer@4.4.0 wants @ionic-native/core@^4.2.0
npm ERR! peerinvalid Peer @ionic-native/facebook@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/file@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/media@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/native-audio@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/splash-screen@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/status-bar@3.10.2 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/toast@3.14.0 wants @ionic-native/core@^3.6.0
npm ERR! peerinvalid Peer @ionic-native/transfer@3.14.0 wants @ionic-native/core@^3.6.0

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/sudipta/musicapp/npm-debug.log

[ERROR] Exception:
sudipta$

I am using following versions

sudipta$ ionic -version
3.18.0
sudipta$ node -v
v6.10.3
sudipta$ npm -v
5.5.1
sudipta$ cordova -version
7.1.0
sudipta$

my package.json (Updated)

{
"name": "xxxxxxxxxxx",
"version": "1.0.0",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
},
"dependencies": {
    "@angular/common": "^5.0.2",
    "@angular/compiler": "^5.0.2",
    "@angular/compiler-cli": "^5.0.2",
    "@angular/core": "^5.0.2",
    "@angular/forms": "^5.0.2",
    "@angular/http": "^5.0.2",
    "@angular/platform-browser": "^5.0.2",
    "@angular/platform-browser-dynamic": "^5.0.2",
    "@angular/tsc-wrapped": "^4.4.6",
    "@ionic-native/core": "^4.4.2",
    "@ionic-native/device": "^4.4.2",
    "@ionic-native/email-composer": "^4.4.2",
    "@ionic-native/facebook": "^4.4.2",
    "@ionic-native/file": "^4.4.2",
    "@ionic-native/media": "^4.4.2",
    "@ionic-native/native-audio": "^4.4.2",
    "@ionic-native/splash-screen": "^4.4.2",
    "@ionic-native/status-bar": "^4.4.2",
    "@ionic-native/toast": "^4.4.2",
    "@ionic-native/transfer": "^3.12.1",
    "@ionic/cloud-angular": "^0.12.0",
    "@ionic/pro": "^1.0.16",
    "@ionic/storage": "^2.1.3",
    "angularfire2": "^5.0.0-rc.3",
    "cordova": "^7.0.1",
    "cordova-android": "^6.4.0",
    "cordova-browser": "^5.0.1",
    "cordova-fabric-plugin": "git+https://github.com/sarriaroman/FabricPlugin.git",
    "cordova-ios": "^4.4.0",
    "cordova-plugin-add-swift-support": "^1.7.0",
    "cordova-plugin-compat": "^1.1.0",
    "cordova-plugin-device": "^1.1.7",
    "cordova-plugin-email-composer": "^0.8.7",
    "cordova-plugin-facebook4": "^1.9.1",
    "cordova-plugin-file": "^5.0.0",
    "cordova-plugin-file-transfer": "^1.7.0",
    "cordova-plugin-ionic": "^2.0.3",
    "cordova-plugin-media": "^4.0.0",
    "cordova-plugin-nativeaudio": "^3.0.9",
    "cordova-plugin-splashscreen": "^4.1.0",
    "cordova-plugin-statusbar": "^2.3.0",
    "cordova-plugin-whitelist": "^1.3.3",
    "cordova-plugin-x-toast": "^2.6.0",
    "emulator": "^0.1.0",
    "firebase": "^4.5.0",
    "ionic-angular": "^3.9.2",
    "ionic-plugin-deploy": "^0.6.7",
    "ionic-plugin-keyboard": "^2.2.1",
    "ionicons": "3.0.0",
    "phonegap-plugin-push": "^2.1.0",
    "promise-polyfill": "^6.0.2",
    "react-native": "^0.50.3",
    "rxjs": "^5.5.2",
    "superagent": "^3.8.0",
    "sw-toolbox": "3.6.0",
    "zone.js": "^0.8.18"
},
"devDependencies": {
    "@ionic/app-scripts": "^3.1.2",
    "ionic": "3.18.0",
    "typescript": "^2.6.1"
},
"description": "An Ionic project",
"cordova": {
    "plugins": {
        "cordova-plugin-x-toast": {},
        "cordova-plugin-file-transfer": {},
        "cordova-plugin-file": {},
        "cordova-plugin-console": {},
        "cordova-plugin-device": {},
        "cordova-plugin-splashscreen": {},
        "cordova-plugin-statusbar": {},
        "cordova-plugin-whitelist": {},
        "ionic-plugin-keyboard": {},
        "cordova-plugin-nativeaudio": {},
        "cordova-plugin-facebook4": {
            "APP_ID": "xxxxxxxxxxx",
            "APP_NAME": "MusicApp"
        },
        "cordova-plugin-media": {
            "MICROPHONE_USAGE_DESCRIPTION": " "
        },
        "ionic-plugin-deploy": {},
        "cordova-fabric-plugin": {
            "FABRIC_API_KEY": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "FABRIC_API_SECRET": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        },
        "cordova-plugin-email-composer": {},
        "cordova-plugin-ionic": {
            "APP_ID": "xxxxxxxxxxx",
            "CHANNEL_NAME": "Master",
            "UPDATE_METHOD": "auto",
            "UPDATE_API": "https://api.ionicjs.com",
            "MAX_STORE": "2"
        }
    },
    "platforms": [
        "android",
        "browser",
        "ios"
    ]
}
}

Output of ionic info

sudipta$ ionic info

cli packages: (/Users/sudipta/musicapp/node_modules)

    @ionic/cli-utils  : 1.18.0
    ionic (Ionic CLI) : 3.18.0

global packages:

    cordova (Cordova CLI) : 7.1.0

local packages:

    @ionic/app-scripts : 3.1.2
    Cordova Platforms  : none
    Ionic Framework    : ionic-angular 3.9.2

System:

    Node  : v6.10.3
    npm   : 5.5.1
    OS    : macOS High Sierra
    Xcode : Xcode 8.3.1 Build version 8E1000a

Environment Variables:

    ANDROID_HOME : not set

Misc:

    backend : pro

sudipta$

So, I am not able to build the app.
Thanks in advance for your help.

Body:
Downgrade all package to 3.12.1 and the problem solved

{
  "name": "musicapp",
  "version": "1.0.0",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "4.1.3",
    "@angular/compiler": "4.1.3",
    "@angular/compiler-cli": "4.1.3",
    "@angular/core": "4.1.3",
    "@angular/forms": "4.1.3",
    "@angular/http": "4.1.3",
    "@angular/platform-browser": "4.1.3",
    "@angular/platform-browser-dynamic": "4.1.3",
    "@angular/tsc-wrapped": "^4.4.6",
    "@ionic-native/core": "3.10.2",
    "@ionic-native/device": "^3.12.1",
    "@ionic-native/email-composer": "^3.12.1",
    "@ionic-native/facebook": "^3.12.1",
    "@ionic-native/file": "^3.12.1",
    "@ionic-native/media": "^3.13.1",
    "@ionic-native/native-audio": "^3.12.1",
    "@ionic-native/splash-screen": "3.10.2",
    "@ionic-native/status-bar": "3.10.2",
    "@ionic-native/toast": "^3.12.1",
    "@ionic-native/transfer": "^3.12.1",
    "@ionic/cloud-angular": "^0.12.0",
    "@ionic/pro": "^1.0.12",
    "@ionic/storage": "2.0.1",
    "angularfire2": "^5.0.0-rc.3",
    "cordova": "^7.0.1",
    "cordova-browser": "^4.1.0",
    "cordova-fabric-plugin": "git+https://github.com/sarriaroman/FabricPlugin.git",
    "cordova-plugin-add-swift-support": "^1.7.0",
    "cordova-plugin-compat": "^1.1.0",
    "cordova-plugin-console": "^1.0.5",
    "cordova-plugin-device": "^1.1.4",
    "cordova-plugin-email-composer": "^0.8.7",
    "cordova-plugin-facebook4": "^1.9.1",
    "cordova-plugin-file": "~4.3.3",
    "cordova-plugin-file-transfer": "^1.7.0",
    "cordova-plugin-ionic": "^2.0.3",
    "cordova-plugin-media": "^3.0.1",
    "cordova-plugin-nativeaudio": "^3.0.9",
    "cordova-plugin-splashscreen": "^4.0.3",
    "cordova-plugin-statusbar": "^2.2.2",
    "cordova-plugin-whitelist": "^1.3.1",
    "cordova-plugin-x-toast": "^2.6.0",
    "emulator": "^0.1.0",
    "firebase": "^4.5.0",
    "ionic-angular": "3.4.0",
    "ionic-plugin-deploy": "^0.6.7",
    "ionic-plugin-keyboard": "^2.2.1",
    "ionicons": "3.0.0",
    "phonegap-plugin-push": "^1.10.5",
    "promise-polyfill": "^6.0.2",
    "react-native": "^0.17.0",
    "rxjs": "5.4.0",
    "superagent": "^3.8.0",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.12",
    "cordova-ios": "~4.5.3"
  },
  "devDependencies": {
    "@ionic/app-scripts": "^2.1.4",
    "ionic": "3.18.0",
    "typescript": "2.3.3"
  },
  "description": "An Ionic project",
  "cordova": {
    "plugins": {
      "cordova-plugin-x-toast": {},
      "cordova-plugin-file-transfer": {},
      "cordova-plugin-file": {},
      "cordova-plugin-console": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-statusbar": {},
      "cordova-plugin-whitelist": {},
      "ionic-plugin-keyboard": {},
      "cordova-plugin-nativeaudio": {},
      "cordova-plugin-facebook4": {
        "APP_ID": "1385780158175812",
        "APP_NAME": "MusicApp"
      },
      "cordova-plugin-media": {
        "MICROPHONE_USAGE_DESCRIPTION": " "
      },
      "ionic-plugin-deploy": {},
      "cordova-fabric-plugin": {
        "FABRIC_API_KEY": "6ba227e76d0f8627261d0d3bc96d43e6e4916c12",
        "FABRIC_API_SECRET": "2ac1b92ef246209e5611aacdd20e89d988597eac09a8ccc88c9a550748192e47"
      },
      "cordova-plugin-email-composer": {},
      "cordova-plugin-ionic": {
        "APP_ID": "2c035184",
        "CHANNEL_NAME": "Master",
        "UPDATE_METHOD": "auto",
        "UPDATE_API": "https://api.ionicjs.com",
        "MAX_STORE": "2"
      }
    },
    "platforms": [
      "browser",
      "ios"
    ]
  }
}


问:
Failed to Attach to Process ID Xcode
Anyone has experienced this problem?
Yesterday I still can run my app in simulator but now I cannot run my app since Xcode prints this error in console:

```<code>error: failed to attach to process ID <ID number>
</code>```

I have tried to reinstall, do this post and create new project but returns no luck.
Anyone can resolve this issue?

I use Xcode 4.5 Preview 2 and try to run iOS simulator 6

答:
On Xcode 9+ do the following:
Go to the Xcode menu: Product-Scheme - Edit Scheme and under Run tab be sure that the Debug Executable checkbox is checked! That's it!

Title: Failed to Attach to Process ID Xcode

Body:
Anyone has experienced this problem?
Yesterday I still can run my app in simulator but now I cannot run my app since Xcode prints this error in console:

error: failed to attach to process ID <ID number>

I have tried to reinstall, do this post and create new project but returns no luck.
Anyone can resolve this issue?

I use Xcode 4.5 Preview 2 and try to run iOS simulator 6


问:
Convert text to timestamp in redshift
I have a text field "presence_changed_at" with text values i.e. '2014/12/17 08:05:28 +0000. I need to convert this into timestamp. In postgreSQL there is function TO_TIMESTAMP(), however in redshift this does not seem to be supported. I can get the date without time by

```<code>TO_DATE("presence_changed_at",'YYYY/MM/DD HH24:MI:SS')
</code>```

which produces

```<code>2014-12-12
</code>```

but i can't find any way to get TIMESTAMP format.

Thanks in advance for solving this

答:
```<code>cast(column as timestamp)
</code>```

worked for me on redshift. See http://devdocs.io/postgresql~9.4/sql-expressions#SQL-SYNTAX-TYPE-CASTS

Title: Convert text to timestamp in redshift

Body:
I have a text field "presence_changed_at" with text values i.e. '2014/12/17 08:05:28 +0000. I need to convert this into timestamp. In postgreSQL there is function TO_TIMESTAMP(), however in redshift this does not seem to be supported. I can get the date without time by

TO_DATE("presence_changed_at",'YYYY/MM/DD HH24:MI:SS')

which produces

2014-12-12

but i can't find any way to get TIMESTAMP format.

Thanks in advance for solving this

Body:
cast(column as timestamp)

worked for me on redshift. See http://devdocs.io/postgresql~9.4/sql-expressions#SQL-SYNTAX-TYPE-CASTS


问:
history of programming language names?
do anyone know the history of programming language names? where they come from?
a,b,c, java, python, scheme, prolog, ada, fortran, algol, cobol, assembly, pascal, lisp, perl, haskell, php, javascript, c#, ruby, c++ and so on.</p>

答:
I would suggest searching Wikipedia :)

But for Python I can answer the question, it comes from "Monty Python", the entertainment/comedy group - not the animal. In Python examples often there are references to Monty Python like "SPAMSPAMSPAM" and "NI NI NI".

ContentLicense: CC BY-SA 2.5

Title: history of programming language names?


问:
Exclude Java System properties and environment variables from SpringBoot configuration
Regarding the property resolution of SpringBoot explained here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

I want to exclude from the mechanism:

```<code>9.  Java System properties (System.getProperties()).
10. OS environment variables.
</code>```

Is it possible?

Thanks

答:
You can provide your own implementation of StandardEnvironment when instancing your Spring Boot application.

For example:

```<code>public static void main(String[] args) {
    SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(Application.class)
            .environment(new StandardEnvironment(){
                @Override
                protected void customizePropertySources(MutablePropertySources propertySources) {
                    // do not add system or env properties to the set of property sources
                }
            });
    applicationBuilder.run(args);
}
</code>```

Or alternatively:

```<code>public static void main(String[] args) {
    SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(Application.class)
            .environment(new StandardEnvironment(){
                @Override
                public Map<String, Object> getSystemEnvironment() {
                    return new HashMap<>();
                }

                @Override
                public Map<String, Object> getSystemProperties() {
                    return new HashMap<>();
                }
            });
    applicationBuilder.run(args);
}
</code>```

Either way, you ensure that your application's properties do not contain any system or environment properties.

Body:
Regarding the property resolution of SpringBoot explained here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

I want to exclude from the mechanism:

9.  Java System properties (System.getProperties()).
10. OS environment variables.

Is it possible?

Thanks

Body:
You can provide your own implementation of StandardEnvironment when instancing your Spring Boot application.

For example:

public static void main(String[] args) {
    SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(Application.class)
            .environment(new StandardEnvironment(){
                @Override
                protected void customizePropertySources(MutablePropertySources propertySources) {
                    // do not add system or env properties to the set of property sources
                }
            });
    applicationBuilder.run(args);
}

Or alternatively:

public static void main(String[] args) {
    SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(Application.class)
            .environment(new StandardEnvironment(){
                @Override
                public Map<String, Object> getSystemEnvironment() {
                    return new HashMap<>();
                }

                @Override
                public Map<String, Object> getSystemProperties() {
                    return new HashMap<>();
                }
            });
    applicationBuilder.run(args);
}

Either way, you ensure that your application's properties do not contain any system or environment properties.


问:
Sum values in one column of all rows which match one or more of multiple criteria
I have some table data in which I'd like to sum all the values in a specific column of all rows where column A contains string A and/or column B contains string B. How can I achieve this?

This works for one criterium:

```<code>=SUM(FILTER(G:G,REGEXMATCH(F:F,"stringA")))
</code>```

I tried this, but it didn't work:

```<code>=SUM(FILTER(G:G,OR(ISTEXT(REGEXMATCH(F:F,"stringA")),ISTEXT(REGEXMATCH(C:C,"stringB")))))
</code>```

答:
Please try:

=SUM(FILTER(G:G,REGEXMATCH(F:F,"stringA")+REGEXMATCH(C:C,"stringB")))

+ works for or logic. ISTEXT is not needed because REGEXMATCH gives true or false.

OR does not work because filter is an arrayformula, use + in array formulas.

Body:
I have some table data in which I'd like to sum all the values in a specific column of all rows where column A contains string A and/or column B contains string B. How can I achieve this?

This works for one criterium:

=SUM(FILTER(G:G,REGEXMATCH(F:F,"stringA")))

I tried this, but it didn't work:

=SUM(FILTER(G:G,OR(ISTEXT(REGEXMATCH(F:F,"stringA")),ISTEXT(REGEXMATCH(C:C,"stringB")))))


问:
Making a countDownTimer pause on button presses
I'm trying to make a basic app where I can press a button to start a countdown, and the text on that same button changes between "START", "PAUSE", or "RESUME" depending on which state the button was in when pressed. Currently the pressing the button does nothing and I'm not sure why.

The button starts out with the text "start"

This is the code for the button listener in onCreate()

None of the 'if' statements seem to ever be true, even though the starting text on the button is "start"

```<code>clockText = findViewById(R.id.timer);
final Button startButton = findViewById(R.id.timerBtn);
    startButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if(clockText.getText().toString().toLowerCase().equals("resume")) {
                startTimer(milliLeft);
                clock.start();
                startButton.setText("resume");
            }
            else if(clockText.getText().toString().toLowerCase().equals("pause")){
                clock.cancel();
                clockText.setText(formatTime);
                startButton.setText("resume");
            }
            else if(clockText.getText().toString().toLowerCase().equals("start")){
                startTimer(30000);
                startButton.setText("pause");
                clock.start();
            }

        }
    });
</code>```

Here is the startTimer() method,

```<code>public int sec,min,fracSec;
public String formatTime;
public TextView clockText;
public CountDownTimer clock;
public long milliLeft;
public void startTimer(long time) {
    clock = new CountDownTimer(time, 100) {
        @Override
        public void onTick(long millisUntilFinished) {

                milliLeft = millisUntilFinished;
                min = (int) Math.floor(millisUntilFinished / 60000);
                sec = (int) (millisUntilFinished / 1000) % 60;
                fracSec = ((int) millisUntilFinished - sec * 1000) / 100;
                formatTime = min + ":" + sec + ":" + fracSec;
                clockText.setText(formatTime);

        }

        @Override
        public void onFinish() {
            clockText.setText("Finished");
        }
    };
}
</code>```

答:
You are comparing 'clockText':

```<code>if(clockText.getText().toString().toLowerCase().equals("resume"))
</code>```

But you are setting the value in your button :

```<code>startButton.setText("resume");
</code>```

Change your conditional

Body:
I'm trying to make a basic app where I can press a button to start a countdown, and the text on that same button changes between "START", "PAUSE", or "RESUME" depending on which state the button was in when pressed. Currently the pressing the button does nothing and I'm not sure why.

The button starts out with the text "start"

This is the code for the button listener in onCreate()

None of the 'if' statements seem to ever be true, even though the starting text on the button is "start"

clockText = findViewById(R.id.timer);
final Button startButton = findViewById(R.id.timerBtn);
    startButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if(clockText.getText().toString().toLowerCase().equals("resume")) {
                startTimer(milliLeft);
                clock.start();
                startButton.setText("resume");
            }
            else if(clockText.getText().toString().toLowerCase().equals("pause")){
                clock.cancel();
                clockText.setText(formatTime);
                startButton.setText("resume");
            }
            else if(clockText.getText().toString().toLowerCase().equals("start")){
                startTimer(30000);
                startButton.setText("pause");
                clock.start();
            }

        }
    });

Here is the startTimer() method,

public int sec,min,fracSec;
public String formatTime;
public TextView clockText;
public CountDownTimer clock;
public long milliLeft;
public void startTimer(long time) {
    clock = new CountDownTimer(time, 100) {
        @Override
        public void onTick(long millisUntilFinished) {

                milliLeft = millisUntilFinished;
                min = (int) Math.floor(millisUntilFinished / 60000);
                sec = (int) (millisUntilFinished / 1000) % 60;
                fracSec = ((int) millisUntilFinished - sec * 1000) / 100;
                formatTime = min + ":" + sec + ":" + fracSec;
                clockText.setText(formatTime);

        }

        @Override
        public void onFinish() {
            clockText.setText("Finished");
        }
    };
}

Body:
You are comparing 'clockText':

if(clockText.getText().toString().toLowerCase().equals("resume"))

But you are setting the value in your button :

startButton.setText("resume");

Change your conditional


问:
searching for a character throughout 4 strings in c using strchr
I'm having some trouble figuring out why when I run the program it won't let me scan the character I want to search for. It just jumps straight to the last printf statement.</p>

```<code>int main()
{
char s1[100], s2[100], s3[100], s4[100];
char character
char *charSearch[3] = {s1, s2, s3, s4};
int counter = 0;
int i;

printf("Enter 4 lines of text: \n");
scanf("%s %s %s %s", &s1, &s2, &s3, &s4);
printf("Enter a any character to search:\n");

scanf("%c", &character);

for(i = 0; i < 3; i++)
{
while(charSearch[i] = strchr(  charSearch, character ))
{
counter++;
charsearch[i]++;
}
}
printf("Total occurrences of character %c is %d", character, counter);

return 0;
}
</code>```

答:
First things first, you declared an array of char pointers of size 3 while giving it 4 elements :
char *charSearch[3] = {s1, s2, s3, s4};

This should be : char *charSearch[4] = {s1, s2, s3, s4};
This declaration should also be done after scanning the contents of the 4 char array {s1,s2,s3,s4} and not before.

The name of any array is a pointer to its first element, thus when using scanf() with char arrays, you already pass the desired address by doing so : scanf("%s %s %s %s", s1, s2, s3, s4);

What you did here : scanf("%s %s %s %s", &s1, &s2, &s3, &s4); passed the address of the first address (sounds weird I know xD).

There is also that irritating bug with scanf("%c", &character); which if you've previously scanned anything ending with a new line, the character will take this \n as its input. To over come this, it should be written as : scanf(" %c", &character);

Now to strchr(), this functions takes two parameters, a char pointerto a string and the character to search for in the string and it returns another char pointer to the location of the character if it was found and NULL otherwise.

We'll need to do the following instead:

```<code>char *ptr = strchr( charSearch[i], character );
    while(ptr!=NULL)
    {
        ptr = strchr( ptr+1, character );
        counter++;
    }
</code>```

What it does is that at the beginning of each iteration of the for loop, it declares a char pointer and initialize it to the return value of the strchr() function. Then we loop while this pointer is not equal to NULL and in each iteration increment our counter and our pointer to make it pointing to the next character in the string.

The final working version of your code should look like :

```<code>#include <stdio.h>
#include <string.h>
int main()
{
char s1[100], s2[100], s3[100], s4[100];
char character;
int counter = 0;
int i;

printf("Enter 4 lines of text: \n");
scanf("%s %s %s %s", s1, s2, s3, s4);
char *charSearch[4] = {s1, s2, s3, s4};
printf("Enter a any character to search:\n");

scanf(" %c", &character);

for(i = 0; i < 4; i++)
{
    char *ptr = strchr( charSearch[i], character );
    while(ptr!=NULL)
    {
        ptr = strchr( ptr+1, character );
    counter++;
    }
}
printf("Total occurrences of character %c is %d\n", character, counter);

return 0;
}
</code>```

Body:
I'm having some trouble figuring out why when I run the program it won't let me scan the character I want to search for. It just jumps straight to the last printf statement.

int main()
{
char s1[100], s2[100], s3[100], s4[100];
char character
char *charSearch[3] = {s1, s2, s3, s4};
int counter = 0;
int i;

printf("Enter 4 lines of text: \n");
scanf("%s %s %s %s", &s1, &s2, &s3, &s4);
printf("Enter a any character to search:\n");

scanf("%c", &character);

for(i = 0; i < 3; i++)
{
while(charSearch[i] = strchr(  charSearch, character ))
{
counter++;
charsearch[i]++;
}
}
printf("Total occurrences of character %c is %d", character, counter);

return 0;
}

Body:
First things first, you declared an array of char pointers of size 3 while giving it 4 elements :
char *charSearch[3] = {s1, s2, s3, s4};

This should be : char *charSearch[4] = {s1, s2, s3, s4};
This declaration should also be done after scanning the contents of the 4 char array {s1,s2,s3,s4} and not before.

The name of any array is a pointer to its first element, thus when using scanf() with char arrays, you already pass the desired address by doing so : scanf("%s %s %s %s", s1, s2, s3, s4);

What you did here : scanf("%s %s %s %s", &s1, &s2, &s3, &s4); passed the address of the first address (sounds weird I know xD).

There is also that irritating bug with scanf("%c", &character); which if you've previously scanned anything ending with a new line, the character will take this \n as its input. To over come this, it should be written as : scanf(" %c", &character);

Now to strchr(), this functions takes two parameters, a char pointerto a string and the character to search for in the string and it returns another char pointer to the location of the character if it was found and NULL otherwise.

We'll need to do the following instead:

char *ptr = strchr( charSearch[i], character );
    while(ptr!=NULL)
    {
        ptr = strchr( ptr+1, character );
        counter++;
    }

What it does is that at the beginning of each iteration of the for loop, it declares a char pointer and initialize it to the return value of the strchr() function. Then we loop while this pointer is not equal to NULL and in each iteration increment our counter and our pointer to make it pointing to the next character in the string.

The final working version of your code should look like :

#include <stdio.h>
#include <string.h>
int main()
{
char s1[100], s2[100], s3[100], s4[100];
char character;
int counter = 0;
int i;

printf("Enter 4 lines of text: \n");
scanf("%s %s %s %s", s1, s2, s3, s4);
char *charSearch[4] = {s1, s2, s3, s4};
printf("Enter a any character to search:\n");

scanf(" %c", &character);

for(i = 0; i < 4; i++)
{
    char *ptr = strchr( charSearch[i], character );
    while(ptr!=NULL)
    {
        ptr = strchr( ptr+1, character );
    counter++;
    }
}
printf("Total occurrences of character %c is %d\n", character, counter);

return 0;
}