问:
App freezes after PreferenceSwitch in settings Android Studio
I made settings activity from Android Studio, not manually. I want to make a switch that applies a dark mode in the app. The problem is that when I click the switch there is no animation for movement, only a blink from the app. When I go back in my Main Activity I see that the theme is applied(I have tried earlier only with the main activity), but when I try to go back in the settings everything is frozen! Nothing can be clicked, no reaction at all.
This is my Java code:

```<code>import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference;

public class SettingsActivity extends AppCompatActivity {
    private SwitchPreference darkModeSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.settings, new SettingsFragment())
                .commit();
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);

        }
    }

    public static class SettingsFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
            SwitchPreference darkModeSwitch = (SwitchPreference) findPreference("darkmode");
            assert darkModeSwitch != null;
            darkModeSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                    } else {
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                    }
                    return false;
                }
            });
        }
    }
}
</code>```

This is root_preferences.xml:

```<code><PreferenceScreen
xmlns:app="http://schemas.android.com/apk/res-auto">

<PreferenceCategory
    app:title="General">

    <SwitchPreference
        app:key="darkmode"
        app:title="Dark mode"/>
</PreferenceCategory>
</code>```

And this is the Logcat after applying the theme:

```<code>avc: denied { getattr } for path="/proc/1" dev="proc" ino=3924 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=dir permissive=0
</code>```

I think that it may be because I have not started the activity again after applying the theme, because when I tried the dark mode in main_activity, there were two lines, which in my settings activity cannot be placed, because the class is static... Please help!

```<code>public void onClick(View v) {
                if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                } else {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                }
//These two
            finish();
            startActivity(new Intent(MainActivity.this, MainActivity.this.getClass()));
        }
    });
</code>```

答:
Put this in your preferences.xml:

```<code><?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
    <SwitchPreferenceCompat
        app:defaultValue="false"
        app:key="@string/key_night_mode"
        app:summaryOff="@string/summary_night_mode_off"
        app:summaryOn="@string/summary_night_mode_on"
        app:title="@string/title_night_mode" />
</PreferenceScreen>
</code>```

Then in your SettingsFragment.java which extended PreferenceFragmentCompat inside the onCreatePreference() method:

```<code>    SwitchPreferenceCompat switchPreferenceCompat = findPreference(getString(R.string.key_night_mode));

    switchPreferenceCompat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    boolean isChecked = false;
                    if (newValue instanceof Boolean)
                        isChecked = (Boolean) newValue;
                    if (isChecked) {
                    //these lines so that the preference persists
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.key_night_mode), true).apply();
                    //you do not need to finish and recreate activity
                    //it takes care of any such things that needs to be done
                    //automatically
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                    } else {
                        getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.key_night_mode), false).apply();
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                    }
                    return true;
                }
            });
</code>```

These lines of codes are working for me.

Note:

AppTheme should extends from Theme.AppCompat.DayNight or Theme.MaterialComponents.DayNight if you want to be dependent on platform for your night theme. Otherwise, you can create your separate Day and Night theme which extends from Theme.MaterialComponents.Light and Theme.MaterialComponents respectively(AppCompat has similar set of themes too).

Every time the app starts, it needs to respect the user's preferences and start in the user setted theme accordingly. To achieve this, you can check the preference and set theme in the MyApplication class as follows:

```<code>    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    boolean nightMode = sharedPreferences.getBoolean(getString(R.string.key_night_mode), false);
    if (nightMode)
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    else {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P)
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
        else
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
    }
</code>```

Body:
I made settings activity from Android Studio, not manually. I want to make a switch that applies a dark mode in the app. The problem is that when I click the switch there is no animation for movement, only a blink from the app. When I go back in my Main Activity I see that the theme is applied(I have tried earlier only with the main activity), but when I try to go back in the settings everything is frozen! Nothing can be clicked, no reaction at all.
This is my Java code:

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference;

public class SettingsActivity extends AppCompatActivity {
    private SwitchPreference darkModeSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.settings, new SettingsFragment())
                .commit();
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);

        }
    }

    public static class SettingsFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
            SwitchPreference darkModeSwitch = (SwitchPreference) findPreference("darkmode");
            assert darkModeSwitch != null;
            darkModeSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                    } else {
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                    }
                    return false;
                }
            });
        }
    }
}

This is root_preferences.xml:

<PreferenceScreen
xmlns:app="http://schemas.android.com/apk/res-auto">

<PreferenceCategory
    app:title="General">

    <SwitchPreference
        app:key="darkmode"
        app:title="Dark mode"/>
</PreferenceCategory>

And this is the Logcat after applying the theme:

avc: denied { getattr } for path="/proc/1" dev="proc" ino=3924 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=dir permissive=0

I think that it may be because I have not started the activity again after applying the theme, because when I tried the dark mode in main_activity, there were two lines, which in my settings activity cannot be placed, because the class is static... Please help!

public void onClick(View v) {
                if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                } else {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                }
//These two
            finish();
            startActivity(new Intent(MainActivity.this, MainActivity.this.getClass()));
        }
    });

Body:
Put this in your preferences.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
    <SwitchPreferenceCompat
        app:defaultValue="false"
        app:key="@string/key_night_mode"
        app:summaryOff="@string/summary_night_mode_off"
        app:summaryOn="@string/summary_night_mode_on"
        app:title="@string/title_night_mode" />
</PreferenceScreen>

Then in your SettingsFragment.java which extended PreferenceFragmentCompat inside the onCreatePreference() method:

    SwitchPreferenceCompat switchPreferenceCompat = findPreference(getString(R.string.key_night_mode));

    switchPreferenceCompat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    boolean isChecked = false;
                    if (newValue instanceof Boolean)
                        isChecked = (Boolean) newValue;
                    if (isChecked) {
                    //these lines so that the preference persists
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.key_night_mode), true).apply();
                    //you do not need to finish and recreate activity
                    //it takes care of any such things that needs to be done
                    //automatically
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                    } else {
                        getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.key_night_mode), false).apply();
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                    }
                    return true;
                }
            });

These lines of codes are working for me.

Note:

AppTheme should extends from Theme.AppCompat.DayNight or Theme.MaterialComponents.DayNight if you want to be dependent on platform for your night theme. Otherwise, you can create your separate Day and Night theme which extends from Theme.MaterialComponents.Light and Theme.MaterialComponents respectively(AppCompat has similar set of themes too).

Every time the app starts, it needs to respect the user's preferences and start in the user setted theme accordingly. To achieve this, you can check the preference and set theme in the MyApplication class as follows:

    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    boolean nightMode = sharedPreferences.getBoolean(getString(R.string.key_night_mode), false);
    if (nightMode)
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    else {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P)
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
        else
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
    }


来源: stackexchange

问:
Checkbox is not `checked` after simulate `change` with enzyme
I tried to use enzyme to simulate change event on a checkbox, and use chai-enzyme to assert if it's been checked.

This is my Hello react component:

```<code>import React from 'react';

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: false
    }
  }

  render() {
    const {checked} = this.state;
    return <div>
      <input type="checkbox" defaultChecked={checked} onChange={this._toggle.bind(this)}/>
      {
        checked ? "checked" : "not checked"
      }
    </div>
  }

  _toggle() {
    const {onToggle} = this.props;
    this.setState({checked: !this.state.checked});
    onToggle();
  }
}

export default Hello;
</code>```

And my test:

```<code>import React from "react";
import Hello from "../src/hello.jsx";
import chai from "chai";
import {mount} from "enzyme";
import chaiEnzyme from "chai-enzyme";
import jsdomGlobal from "jsdom-global";
import spies  from 'chai-spies';

function myAwesomeDebug(wrapper) {
  let html = wrapper.html();
  console.log(html);
  return html
}

jsdomGlobal();
chai.should();
chai.use(spies);
chai.use(chaiEnzyme(myAwesomeDebug));

describe('<Hello />', () => {

  it('checks the checkbox', () => {
    const onToggle = chai.spy();
    const wrapper = mount(<Hello onToggle={onToggle}/>);

    var checkbox = wrapper.find('input');
    checkbox.should.not.be.checked();
    checkbox.simulate('change', {target: {checked: true}});
    onToggle.should.have.been.called.once();

    console.log(checkbox.get(0).checked);
    checkbox.should.be.checked();
  });

});
</code>```

When I run this test, the checkbox.get(0).checked is false, and the assertion checkbox.should.be.checked() reports error:

```<code>AssertionError: expected the node in <Hello /> to be checked <input type="checkbox" checked="checked">
</code>```

You can see the message is quite strange since there is already checked="checked" in the output.

I'm not sure where is wrong, since it involves too many things.

You can also see a demo project here: https://github.com/js-demos/react-enzyme-simulate-checkbox-events-demo, notice these lines

答:
Below solution best worked for me:

```<code>it('should check checkbox handleClick event on Child component under Parent', () => {
const handleClick = jest.fn();
const wrapper = mount(
<Parent onChange={handleClick} {...dependencies}/>,); // dependencies, if any
checked = false;
wrapper.setProps({ checked: false });
const viewChildren = wrapper.find(Children);
const checkbox = viewChildren.find('input[type="checkbox"]').first(); // If you've multiple checkbox nodes and want to select first
checkbox.simulate('change', { target: { checked: true } });
expect(handleClick).toHaveBeenCalled();
});
</code>```

Hope this helps.

ContentLicense: CC BY-SA 3.0

Body:
I tried to use enzyme to simulate change event on a checkbox, and use chai-enzyme to assert if it's been checked.

This is my Hello react component:

import React from 'react';

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: false
    }
  }

  render() {
    const {checked} = this.state;
    return

      <input type="checkbox" defaultChecked={checked} onChange={this._toggle.bind(this)}/>
      {
        checked ? "checked" : "not checked"
      }

  }

  _toggle() {
    const {onToggle} = this.props;
    this.setState({checked: !this.state.checked});
    onToggle();
  }
}

export default Hello;

And my test:

import React from "react";
import Hello from "../src/hello.jsx";
import chai from "chai";
import {mount} from "enzyme";
import chaiEnzyme from "chai-enzyme";
import jsdomGlobal from "jsdom-global";
import spies  from 'chai-spies';

function myAwesomeDebug(wrapper) {
  let html = wrapper.html();
  console.log(html);
  return html
}

jsdomGlobal();
chai.should();
chai.use(spies);
chai.use(chaiEnzyme(myAwesomeDebug));

describe('<Hello />', () => {

  it('checks the checkbox', () => {
    const onToggle = chai.spy();
    const wrapper = mount(<Hello onToggle={onToggle}/>);

    var checkbox = wrapper.find('input');
    checkbox.should.not.be.checked();
    checkbox.simulate('change', {target: {checked: true}});
    onToggle.should.have.been.called.once();

    console.log(checkbox.get(0).checked);
    checkbox.should.be.checked();
  });

});

When I run this test, the checkbox.get(0).checked is false, and the assertion checkbox.should.be.checked() reports error:

AssertionError: expected the node in <Hello /> to be checked <input type="checkbox" checked="checked">

You can see the message is quite strange since there is already checked="checked" in the output.

I'm not sure where is wrong, since it involves too many things.

You can also see a demo project here: https://github.com/js-demos/react-enzyme-simulate-checkbox-events-demo, notice these lines

Body:
Below solution best worked for me:

it('should check checkbox handleClick event on Child component under Parent', () => {
const handleClick = jest.fn();
const wrapper = mount(
<Parent onChange={handleClick} {...dependencies}/>,); // dependencies, if any
checked = false;
wrapper.setProps({ checked: false });
const viewChildren = wrapper.find(Children);
const checkbox = viewChildren.find('input[type="checkbox"]').first(); // If you've multiple checkbox nodes and want to select first
checkbox.simulate('change', { target: { checked: true } });
expect(handleClick).toHaveBeenCalled();
});

Hope this helps.

ContentLicense: CC BY-SA 4.0


问:
How to remove Google Meet in the email notification received after creating a Google event?

```<code>class SendInvitation
  def self.new(match_info,current_user)

    begin

      authorization = GoogleRefresh.auth_client(current_user)
      service = Google::Apis::CalendarV3::CalendarService.new
      service.authorization = authorization

      match_date = match_info.match_date.strftime("%F")
      min_time = match_info.min_time.strftime("%T%:z")
      max_time = match_info.max_time.strftime("%T%:z")
      start_time = "#{match_date}T#{min_time}"
      end_time = "#{match_date}T#{max_time}"

      minutes = ((start_time.to_time-Time.now) / 60).to_i

      attendeesList = Match.find(id=match_info.id).users.map{|user| Google::Apis::CalendarV3::EventAttendee.new(email: "#{user.email}")}
      attendeesList<<Google::Apis::CalendarV3::EventAttendee.new(email: "#{User.find(id=match_info.owner_id).email}")

      event = Google::Apis::CalendarV3::Event.new(
          summary: "CalendarMatcher -#{match_info.title}",
          location: match_info.location,
          description: "Descritption: #{match_info.description}",

           start: Google::Apis::CalendarV3::EventDateTime.new(
            date_time: start_time,
            time_zone: 'Europe/Brussels'
            ),
          end: Google::Apis::CalendarV3::EventDateTime.new(
            date_time: end_time,
            time_zone: 'Europe/Brussels'
            ),

        attendees:  attendeesList,

        reminders: Google::Apis::CalendarV3::Event::Reminders.new(
          use_default: false,
          overrides: [
            Google::Apis::CalendarV3::EventReminder.new(
              reminder_method: 'email',
              minutes: minutes
              ),
            Google::Apis::CalendarV3::EventReminder.new(
              reminder_method: 'popup',
              minutes: 30
              )
          ]
          )
        )

        result = service.insert_event('primary', event)

        puts "Event created: #{updated_result.html_link}"

      rescue ::Google::Apis::AuthorizationError => e
      authorization.grant_type = 'refresh_token'
      authorization.access_token = current_user.token
      authorization.refresh_token = current_user.refresh_token
      response = authorization.refresh!
      current_user.token = response['access_token']
      current_user.save

      retry
    end

  end
end

</code>```

I am struggling with google api documentation... I am a really junior developper and hope that someone will be able to help me.

Here is all my method to send the email to the attendees and to add the event in the attendees calendar. It is working fine : it send email and fill their calendar.

But the email include the GoogleMeet link which I would like to remove.
So I read all the documentation on the internet. For what I understood, the GoogleMeet respond to some "conference data" settings...

But when I start adding conference_data_version: 1.
result = service.insert_event('primary', event, conference_data_version: 1);
I get the error saying that "unknown keyword: conference_data_version"

答:
Answer:

You need to set conference_data_version to 1.

Code change:

result = service.insert_event('primary', event, conference_data_version: 0)
```
<p>should be changed to:</p>
<pre class="lang-ruby prettyprint-override"><code>result = service.insert_event('primary', event, conference_data_version: 1)
</code>```

Also, you do not need to specify an empty conference_data: {} object in the event resource.

Here is my full code so you can see how this is done.

The authorize function was taken from the Ruby Quickstart provided by Google, and the Calendar insert was modified based on the client documentation:

require "google/apis/calendar_v3"
require "googleauth"
require "googleauth/stores/file_token_store"
require "date"
require "fileutils"

OOB_URI = "urn:ietf:wg:oauth:2.0:oob".freeze
APPLICATION_NAME = "Google Calendar API Ruby Quickstart".freeze
CREDENTIALS_PATH = "credentials.json".freeze
# The file token.yaml stores the user 's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.

TOKEN_PATH = "token.yaml".freeze
SCOPE = Google::Apis::CalendarV3::AUTH_CALENDAR

##
# Ensure valid credentials, either by restoring from the saved credentials
# files or intitiating an OAuth2 authorization.If authorization is required,
# the user 's default browser will be launched to approve the request.
#
# @return [Google::Auth::UserRefreshCredentials] OAuth2 credentials

def authorize
  client_id = Google::Auth::ClientId.from_file CREDENTIALS_PATH
  token_store = Google::Auth::Stores::FileTokenStore.new file: TOKEN_PATH
  authorizer = Google::Auth::UserAuthorizer.new client_id, SCOPE, token_store
  user_id = "default"
  credentials = authorizer.get_credentials user_id
  if credentials.nil ?
    url = authorizer.get_authorization_url base_url : OOB_URI
    puts "Open the following URL in the browser and enter the "\
         "resulting code after authorization:\n" + url
    code = gets
    credentials = authorizer.get_and_store_credentials_from_code(
      user_id: user_id, code: code, base_url: OOB_URI
    )
  end
  credentials
end

# Initialize the API
service = Google::Apis::CalendarV3::CalendarService.new
service.client_options.application_name = APPLICATION_NAME
service.authorization = authorize

event = Google::Apis::CalendarV3::Event.new(
    summary: "CalendarMatcher -#{match_info.title}",
    location: match_info.location,
    description: "Descritption: #{match_info.description}",
    start: Google::Apis::CalendarV3::EventDateTime.new(
        date_time: start_time,
        time_zone: 'Europe/Brussels'
    ),
    end: Google::Apis::CalendarV3::EventDateTime.new(
        date_time: end_time,
        time_zone: 'Europe/Brussels'
    ),
    attendees: [
        Google::Apis::CalendarV3::EventAttendee.new(
            email: 'email@domain.com'
        ),
        Google::Apis::CalendarV3::EventAttendee.new(
            email: 'email2@domain.com'
        )
    ],
    reminders: Google::Apis::CalendarV3::Event::Reminders.new(
        use_default: false,
        overrides: [
            Google::Apis::CalendarV3::EventReminder.new(
                reminder_method: 'email',
                minutes: minutes
            ),
            Google::Apis::CalendarV3::EventReminder.new(
                reminder_method: 'popup',
                minutes: 30
            )
        ]
    )
)
result = service.insert_event('primary', event, conference_data_version: 1)
```

Make sure to delete your token.yaml file and re-run your program.

Body:
class SendInvitation
  def self.new(match_info,current_user)

    begin

      authorization = GoogleRefresh.auth_client(current_user)
      service = Google::Apis::CalendarV3::CalendarService.new
      service.authorization = authorization

      match_date = match_info.match_date.strftime("%F")
      min_time = match_info.min_time.strftime("%T%:z")
      max_time = match_info.max_time.strftime("%T%:z")
      start_time = "#{match_date}T#{min_time}"
      end_time = "#{match_date}T#{max_time}"

      minutes = ((start_time.to_time-Time.now) / 60).to_i

      attendeesList = Match.find(id=match_info.id).users.map{|user| Google::Apis::CalendarV3::EventAttendee.new(email: "#{user.email}")}
      attendeesList<<Google::Apis::CalendarV3::EventAttendee.new(email: "#{User.find(id=match_info.owner_id).email}")

      event = Google::Apis::CalendarV3::Event.new(
          summary: "CalendarMatcher -#{match_info.title}",
          location: match_info.location,
          description: "Descritption: #{match_info.description}",

           start: Google::Apis::CalendarV3::EventDateTime.new(
            date_time: start_time,
            time_zone: 'Europe/Brussels'
            ),
          end: Google::Apis::CalendarV3::EventDateTime.new(
            date_time: end_time,
            time_zone: 'Europe/Brussels'
            ),

        attendees:  attendeesList,

        reminders: Google::Apis::CalendarV3::Event::Reminders.new(
          use_default: false,
          overrides: [
            Google::Apis::CalendarV3::EventReminder.new(
              reminder_method: 'email',
              minutes: minutes
              ),
            Google::Apis::CalendarV3::EventReminder.new(
              reminder_method: 'popup',
              minutes: 30
              )
          ]
          )
        )

        result = service.insert_event('primary', event)

        puts "Event created: #{updated_result.html_link}"

      rescue ::Google::Apis::AuthorizationError => e
      authorization.grant_type = 'refresh_token'
      authorization.access_token = current_user.token
      authorization.refresh_token = current_user.refresh_token
      response = authorization.refresh!
      current_user.token = response['access_token']
      current_user.save

      retry
    end

  end
end

I am struggling with google api documentation... I am a really junior developper and hope that someone will be able to help me.

Here is all my method to send the email to the attendees and to add the event in the attendees calendar. It is working fine : it send email and fill their calendar.

But the email include the GoogleMeet link which I would like to remove.
So I read all the documentation on the internet. For what I understood, the GoogleMeet respond to some "conference data" settings...

But when I start adding conference_data_version: 1.
result = service.insert_event('primary', event, conference_data_version: 1);
I get the error saying that "unknown keyword: conference_data_version"

Body:
Answer:

You need to set conference_data_version to 1.

Code change:

result = service.insert_event('primary', event, conference_data_version: 0)

should be changed to:

result = service.insert_event('primary', event, conference_data_version: 1)

Also, you do not need to specify an empty conference_data: {} object in the event resource.

Here is my full code so you can see how this is done.

The authorize function was taken from the Ruby Quickstart provided by Google, and the Calendar insert was modified based on the client documentation:

require "google/apis/calendar_v3"
require "googleauth"
require "googleauth/stores/file_token_store"
require "date"
require "fileutils"

OOB_URI = "urn:ietf:wg:oauth:2.0:oob".freeze
APPLICATION_NAME = "Google Calendar API Ruby Quickstart".freeze
CREDENTIALS_PATH = "credentials.json".freeze
# The file token.yaml stores the user 's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.

TOKEN_PATH = "token.yaml".freeze
SCOPE = Google::Apis::CalendarV3::AUTH_CALENDAR

##
# Ensure valid credentials, either by restoring from the saved credentials
# files or intitiating an OAuth2 authorization.If authorization is required,
# the user 's default browser will be launched to approve the request.
#
# @return [Google::Auth::UserRefreshCredentials] OAuth2 credentials

def authorize
  client_id = Google::Auth::ClientId.from_file CREDENTIALS_PATH
  token_store = Google::Auth::Stores::FileTokenStore.new file: TOKEN_PATH
  authorizer = Google::Auth::UserAuthorizer.new client_id, SCOPE, token_store
  user_id = "default"
  credentials = authorizer.get_credentials user_id
  if credentials.nil ?
    url = authorizer.get_authorization_url base_url : OOB_URI
    puts "Open the following URL in the browser and enter the "\
         "resulting code after authorization:\n" + url
    code = gets
    credentials = authorizer.get_and_store_credentials_from_code(
      user_id: user_id, code: code, base_url: OOB_URI
    )
  end
  credentials
end

# Initialize the API
service = Google::Apis::CalendarV3::CalendarService.new
service.client_options.application_name = APPLICATION_NAME
service.authorization = authorize

event = Google::Apis::CalendarV3::Event.new(
    summary: "CalendarMatcher -#{match_info.title}",
    location: match_info.location,
    description: "Descritption: #{match_info.description}",
    start: Google::Apis::CalendarV3::EventDateTime.new(
        date_time: start_time,
        time_zone: 'Europe/Brussels'
    ),
    end: Google::Apis::CalendarV3::EventDateTime.new(
        date_time: end_time,
        time_zone: 'Europe/Brussels'
    ),
    attendees: [
        Google::Apis::CalendarV3::EventAttendee.new(
            email: 'email@domain.com'
        ),
        Google::Apis::CalendarV3::EventAttendee.new(
            email: 'email2@domain.com'
        )
    ],
    reminders: Google::Apis::CalendarV3::Event::Reminders.new(
        use_default: false,
        overrides: [
            Google::Apis::CalendarV3::EventReminder.new(
                reminder_method: 'email',
                minutes: minutes
            ),
            Google::Apis::CalendarV3::EventReminder.new(
                reminder_method: 'popup',
                minutes: 30
            )
        ]
    )
)
result = service.insert_event('primary', event, conference_data_version: 1)

Make sure to delete your token.yaml file and re-run your program.


问:
Running MySQL Query in Wordpress Causes HTML Markup to Disappear?
We're having an issue adding MySQL queries to our page. It seems that whenever something is run at the top of the page, the rest of the markup and php functions to follow don't show up/aren't run.

Here's a sample query that causes this issue:

```<code>global $wpdb;

$add_query = "CREATE TABLE thetesttable
        (
           id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
           product VARCHAR(50)
        )";

$wpdb->query($add_query) or die(mysql_error());
</code>```

Loading the page once results in a blank page.

The second time, we see Table 'thetesttable' already exists, which means that our queries are getting through.

There are no other errors on the page or anything else detected by Google Chrome.

What could be causing this problem?

Many thanks,

Justian Meyer

答:
The problem is that your query is returning 0 which is interpreted as false in your statment:

```<code>$wpdb->query($add_query) or die(mysql_error());
</code>```

From the wpdb class reference:

The function returns an integer
  corresponding to the number of rows
  affected/selected. If there is a MySQL
  error, the function will return FALSE.
  (Note: since both 0 and FALSE can be
  returned, make sure you use the
  correct comparison operator: equality
  == vs. identicality ===).

What you should do is something like:

```<code>$result = $wpdb->query($add_query);
if ($result === false)
{
  die('Could not run query');
}
</code>```

Edit: By the way, also note that you should not use mysql_error() like you do when you use the wpdb class. To get the last error, you can use $wpdb->print_error();.

Body:
We're having an issue adding MySQL queries to our page. It seems that whenever something is run at the top of the page, the rest of the markup and php functions to follow don't show up/aren't run.

Here's a sample query that causes this issue:

global $wpdb;

$add_query = "CREATE TABLE thetesttable
        (
           id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
           product VARCHAR(50)
        )";

$wpdb->query($add_query) or die(mysql_error());

Loading the page once results in a blank page.

The second time, we see Table 'thetesttable' already exists, which means that our queries are getting through.

There are no other errors on the page or anything else detected by Google Chrome.

What could be causing this problem?

Many thanks,

Justian Meyer

Body:
The problem is that your query is returning 0 which is interpreted as false in your statment:

$wpdb->query($add_query) or die(mysql_error());

From the wpdb class reference:

The function returns an integer
  corresponding to the number of rows
  affected/selected. If there is a MySQL
  error, the function will return FALSE.
  (Note: since both 0 and FALSE can be
  returned, make sure you use the
  correct comparison operator: equality
  == vs. identicality ===).

What you should do is something like:

$result = $wpdb->query($add_query);
if ($result === false)
{
  die('Could not run query');
}

Edit: By the way, also note that you should not use mysql_error() like you do when you use the wpdb class. To get the last error, you can use $wpdb->print_error();.


问:
Generate an url to a telegram bot command
I want to create a QR code than links to a telegram bot so when people scans this code they can automatically issues certain command

Is that possible?

答:
Using Deep Linking you can start a Telegram bot passing an extra parameter

```<code>https://t.me/my_telegram_bot?start=my_action
</code>```

The link will open the chatbot on Telegram showing the START button: the parameter my_action is passed to the start command.

As far as I know you cannot pass commands dynamically but you can use the /start command as entry point (the parameter will define what to do).

Body:
Using Deep Linking you can start a Telegram bot passing an extra parameter

https://t.me/my_telegram_bot?start=my_action

The link will open the chatbot on Telegram showing the START button: the parameter my_action is passed to the start command.

As far as I know you cannot pass commands dynamically but you can use the /start command as entry point (the parameter will define what to do).


问:
Dockerfile copy to one folder up
I have below structure

```<code>folder1
    Dockerfile
    start.sh
folder2
    config.ini
someotherfiles
</code>```

inside the Dockerfile

i have added

```<code>COPY ../folder2/config.ini /
COPY ../somotherfiles /
</code>```

Now when I build the docker, i'm getting error file not found.

how can I copy the files which is one folder up where the Dockerfile exists?

答:
file not found might be because you are not executing docker build from the same directory as your Dockerfile is.

COPY arguments are interpreted relatively from where you execute docker run, not from where the Dockerfile is.

Title: Dockerfile copy to one folder up

Body:
I have below structure

folder1
    Dockerfile
    start.sh
folder2
    config.ini
someotherfiles

inside the Dockerfile

i have added

COPY ../folder2/config.ini /
COPY ../somotherfiles /

Now when I build the docker, i'm getting error file not found.

how can I copy the files which is one folder up where the Dockerfile exists?


问:
Pull to Refresh and setState not working - React Native
React Native App

I am implementing Pull to refresh in my Flatlist prop "onRefresh"

onRefresh called the function "refreshcontrol()" see code below.

I need to change my state "refreshing" to true before I fetch from my API. But it throws the maximum update error.

```<code>export default class NotificationScreen extends Component {

  constructor(props) {
   super(props)
   this.state = {
      refreshing: false
    }
  }
.
.
.
.
.
  refreshControl() {
    const { refreshing } = this.state;
    this.setState({ refreshing : true )}.    // throws maximum update error

    return (
      <RefreshControl
        refreshing={refreshing}
        onRefresh={fetchNotifications.bind(this)}      //fetch from API only when refreshing is true
        colors={['#2B70AD']}
      />
    );
  };

}
</code>```

How else can I set my state to "refreshing :  true" ??? Help please!!!!

This is how it was fixed. Solution:

```<code>refresh = async() => {
    this.setState({refreshing : true})
    try {
      const notifications = await fetchNotifications();
      this.setState({
        notifications,
        error: null,
        refreshing: false
      });
    } catch (error) {
      this.setState({
        notifications: [],
        error,
        refreshing: false
      });
    }
  }

  refreshControl() {
    const { refreshing } = this.state;

    return (
      <RefreshControl
        refreshing={refreshing}
        onRefresh={this.refresh}
        colors={['#2B70AD']}
      />
    );
  };

</code>```

答:
```<code>  refreshFlatlist = () => {
    this.setState(
      {
        refresh: true,
      },
      () => this.getTodosHandler()
    );
    this.setState({
      refresh: false,
    });
  };
</code>```

This is how I refresh the default state of course is false. the todosHandler always holds the current todos. Its a call to a SQLite DB stored on the phone locally.

Now the flatlist RefreshComponent I used:

```<code>   <FlatList
            refreshControl={
              <RefreshControl
                refreshing={this.state.refresh}
                onRefresh={this.refreshFlatlist}
              />
            }
            extraData={this.state.refresh}
            data={this.state.toDoArray}
            keyExtractor={(item, index) => item.id.toString()}
            renderItem={({ item }) => ( ...
</code>```

Look into it maybe it will help you - this works for me like a charm ;)

Body:
React Native App

I am implementing Pull to refresh in my Flatlist prop "onRefresh"

onRefresh called the function "refreshcontrol()" see code below.

I need to change my state "refreshing" to true before I fetch from my API. But it throws the maximum update error.

export default class NotificationScreen extends Component {

  constructor(props) {
   super(props)
   this.state = {
      refreshing: false
    }
  }
.
.
.
.
.
  refreshControl() {
    const { refreshing } = this.state;
    this.setState({ refreshing : true )}.    // throws maximum update error

    return (
      <RefreshControl
        refreshing={refreshing}
        onRefresh={fetchNotifications.bind(this)}      //fetch from API only when refreshing is true
        colors={['#2B70AD']}
      />
    );
  };

}

How else can I set my state to "refreshing :  true" ??? Help please!!!!

This is how it was fixed. Solution:

refresh = async() => {
    this.setState({refreshing : true})
    try {
      const notifications = await fetchNotifications();
      this.setState({
        notifications,
        error: null,
        refreshing: false
      });
    } catch (error) {
      this.setState({
        notifications: [],
        error,
        refreshing: false
      });
    }
  }

  refreshControl() {
    const { refreshing } = this.state;

    return (
      <RefreshControl
        refreshing={refreshing}
        onRefresh={this.refresh}
        colors={['#2B70AD']}
      />
    );
  };

Body:
  refreshFlatlist = () => {
    this.setState(
      {
        refresh: true,
      },
      () => this.getTodosHandler()
    );
    this.setState({
      refresh: false,
    });
  };

This is how I refresh the default state of course is false. the todosHandler always holds the current todos. Its a call to a SQLite DB stored on the phone locally.

Now the flatlist RefreshComponent I used:

   <FlatList
            refreshControl={
              <RefreshControl
                refreshing={this.state.refresh}
                onRefresh={this.refreshFlatlist}
              />
            }
            extraData={this.state.refresh}
            data={this.state.toDoArray}
            keyExtractor={(item, index) => item.id.toString()}
            renderItem={({ item }) => ( ...

Look into it maybe it will help you - this works for me like a charm ;)


问:
Install pip on mac failed
So I installed different versions of Pythons on my mac and it seems this is the root of all my problems at the moment. I want to import the module named pyperclip in Mueditor but it always says No module named 'pyperclip'

I read a lot of different other threads and tried to sudo /usr/bin/python get-pip.py
But I always get /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python: can't open file 'get-pip.py': [Errno 2] No such file or directory
Which indicates that it is searching in the wrong directory (not sure with the correct terminology here).

I installed Python 3.8 with homebrew and everything is updated fine.

For context: I started programming with anaconda, deleted it downloaded Python from the official website and am using Mueditor right now while following the tasks in the book 'Automate the boring stuff with Python'.

I am even considering setting up my OSX again...
Help is much appreciated!

答:
Check the Python version :

```<code>python --version
python3 --version
</code>```

Install pip using easy_install on MacOS

easy_install is a Python module bundled with setuptools which gives us the ability to download, build, install and manage Python packages

```<code>sudo easy_install pip
</code>```

Install pip using get-pip.py on MacOS

```<code>curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

python get-pip.py
</code>```

or

```<code>python3 get-pip.py
</code>```

Install pip with brew on MacOS

```<code>brew install python
</code>```

If any problems related to the pip usage we will have to relink the python with the following command.

```<code>brew unlink python && brew link python
brew unlink python3 && brew link python3
</code>```

In the end after following any of the above steps, check and verify pip version

```<code>pip -V

pip3 -V
</code>```

Title: Install pip on mac failed

Body:
Check the Python version :

python --version
python3 --version

Install pip using easy_install on MacOS

easy_install is a Python module bundled with setuptools which gives us the ability to download, build, install and manage Python packages

sudo easy_install pip

Install pip using get-pip.py on MacOS

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

python get-pip.py

or

python3 get-pip.py

Install pip with brew on MacOS

brew install python

If any problems related to the pip usage we will have to relink the python with the following command.

brew unlink python && brew link python
brew unlink python3 && brew link python3

In the end after following any of the above steps, check and verify pip version

pip -V

pip3 -V


问:
How to best convert Flash compatible mp4 files with FFMPEG?
I am trying to convert different files to a flash compatible .mp4 file with ffmpeg, but I can't seem to get it to work. Of course the objective is to get the greatest quality with the smallest file size.

So far I have this, which works, but it doesn't play in a flash player for some reason. The result isn't that great, how can I improve this conversion?

This is the command I'm using:

```<code>ffmpeg -i input.file -f mp4 -vcodec mpeg4 -r 25 -b 560000 -s 610x340 -acodec aac -ac 2 -ab 64 -ar 44100 output.file
</code>```

答:
I use a sequence of commands to do this, starting with mencoder.  (see script below).  The trick is that ffmpeg's (and mencoder's) mp4 file output is not generally flash compatible due to the way it's interleaved and they don't offer good control over this behavior.  So, I produce an AVI file and then use mp4box to remux it the way I want.  Here's my complete script, that expects to be given an .avi file, and produces a flash-playable .mp4 file. </p>

```<code>#!/bin/bash
#
ORIGDIR=`pwd`
FILE=$@
VID_OUTPUT=${FILE/.AVI/.tmp.avi}
FINAL_OUTPUT=${FILE/.AVI/.mp4}
MENCODER=~/src/mplayer/svn/mplayer/mencoder
BITRATE=500
RES=640:480
LOG=mencoder.$FILE.log

TEMPDIR=`mktemp -d /tmp/transcode.XXXXXXXX`
pushd $TEMPDIR
echo "Pass 1"

PARAMS=keyint=250:bframes=0:qp_min=10:qp_max=51:turbo=1:mixed_refs=0:frameref=1:deblock=0,0:qblur=0:vbv_bufsize=10000:vbv_maxrate=10000:keyint_min=25:me=hex:me_range=16:ip_factor=1.4:pb_factor=1.3:chroma_qp_offset=0:vbv_init=0.9:ratetol=1.0:cplx_blur=20:nocabac:noweight_b:nob_pyramid:partitions=p8x8,b8x8,i4x4:no8x8dct:nossim:deadzone_inter=21:deadzone_intra=11

EXTRA_PARAMS=subq=5:trellis=0:

$MENCODER $ORIGDIR/$FILE -o $VID_OUTPUT -oac faac -srate 44100 -ovc x264 -x264encopts bitrate=$BITRATE:$PARAMS:pass=1 -vf scale=$RES 2>&1 >> $LOG
echo "Pass 2"
$MENCODER $ORIGDIR/$FILE -o $VID_OUTPUT -oac faac -srate 44100 -ovc x264 -x264encopts bitrate=$BITRATE:$PARAMS:pass=2 -vf scale=$RES 2>&1 >> $LOG
MP4Box -aviraw video $VID_OUTPUT
MP4Box -aviraw audio $VID_OUTPUT
TEMP_AUDIO=${VID_OUTPUT/.avi/}_audio.raw
AAC_AUDIO=${TEMP_AUDIO/.raw/.aac}
H264_VIDEO=${VID_OUTPUT/.avi/}_video.h264
echo TEMP is $TEMP_AUDIO
echo AAC is $AAC_AUDIO
echo H264 is $H264_VIDEO
mv $TEMP_AUDIO $AAC_AUDIO
MP4Box -add $H264_VIDEO:fps=29.97 -add $AAC_AUDIO $FINAL_OUTPUT
mv $LOG $ORIGDIR
mv $FINAL_OUTPUT $ORIGDIR
popd
echo Files left in $TEMPDIR
# rm -fr $TEMPDIR
</code>```

OwnerDisplayName: Espen Christensen

Body:
I am trying to convert different files to a flash compatible .mp4 file with ffmpeg, but I can't seem to get it to work. Of course the objective is to get the greatest quality with the smallest file size.

So far I have this, which works, but it doesn't play in a flash player for some reason. The result isn't that great, how can I improve this conversion?

This is the command I'm using:

ffmpeg -i input.file -f mp4 -vcodec mpeg4 -r 25 -b 560000 -s 610x340 -acodec aac -ac 2 -ab 64 -ar 44100 output.file

LastEditorDisplayName: Roger Pate

Body:
I use a sequence of commands to do this, starting with mencoder.  (see script below).  The trick is that ffmpeg's (and mencoder's) mp4 file output is not generally flash compatible due to the way it's interleaved and they don't offer good control over this behavior.  So, I produce an AVI file and then use mp4box to remux it the way I want.  Here's my complete script, that expects to be given an .avi file, and produces a flash-playable .mp4 file.

#!/bin/bash
#
ORIGDIR=`pwd`
FILE=$@
VID_OUTPUT=${FILE/.AVI/.tmp.avi}
FINAL_OUTPUT=${FILE/.AVI/.mp4}
MENCODER=~/src/mplayer/svn/mplayer/mencoder
BITRATE=500
RES=640:480
LOG=mencoder.$FILE.log

TEMPDIR=`mktemp -d /tmp/transcode.XXXXXXXX`
pushd $TEMPDIR
echo "Pass 1"

PARAMS=keyint=250:bframes=0:qp_min=10:qp_max=51:turbo=1:mixed_refs=0:frameref=1:deblock=0,0:qblur=0:vbv_bufsize=10000:vbv_maxrate=10000:keyint_min=25:me=hex:me_range=16:ip_factor=1.4:pb_factor=1.3:chroma_qp_offset=0:vbv_init=0.9:ratetol=1.0:cplx_blur=20:nocabac:noweight_b:nob_pyramid:partitions=p8x8,b8x8,i4x4:no8x8dct:nossim:deadzone_inter=21:deadzone_intra=11

EXTRA_PARAMS=subq=5:trellis=0:

$MENCODER $ORIGDIR/$FILE -o $VID_OUTPUT -oac faac -srate 44100 -ovc x264 -x264encopts bitrate=$BITRATE:$PARAMS:pass=1 -vf scale=$RES 2>&1 >> $LOG
echo "Pass 2"
$MENCODER $ORIGDIR/$FILE -o $VID_OUTPUT -oac faac -srate 44100 -ovc x264 -x264encopts bitrate=$BITRATE:$PARAMS:pass=2 -vf scale=$RES 2>&1 >> $LOG
MP4Box -aviraw video $VID_OUTPUT
MP4Box -aviraw audio $VID_OUTPUT
TEMP_AUDIO=${VID_OUTPUT/.avi/}_audio.raw
AAC_AUDIO=${TEMP_AUDIO/.raw/.aac}
H264_VIDEO=${VID_OUTPUT/.avi/}_video.h264
echo TEMP is $TEMP_AUDIO
echo AAC is $AAC_AUDIO
echo H264 is $H264_VIDEO
mv $TEMP_AUDIO $AAC_AUDIO
MP4Box -add $H264_VIDEO:fps=29.97 -add $AAC_AUDIO $FINAL_OUTPUT
mv $LOG $ORIGDIR
mv $FINAL_OUTPUT $ORIGDIR
popd
echo Files left in $TEMPDIR
# rm -fr $TEMPDIR

OwnerDisplayName: slacy

ContentLicense: CC BY-SA 2.5


问:
replaceFirst() fails when replacing with "$"
I don't understand why the "$" is special.

```<code>String str = "bla aa";
String tag = "$";
str = str.replaceFirst("aa", tag);

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
</code>```

If I change the tag = "\\$", then it works fine.  But why does it need to be escaped?  thanks in advance.

答: $ matches the end of the line in a regex. So if you need it as a simple character, you need to escape it. You can find more at JAVA Pattern</p>

Body:
I don't understand why the "$" is special.

String str = "bla aa";
String tag = "$";
str = str.replaceFirst("aa", tag);

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1

If I change the tag = "\\$", then it works fine.  But why does it need to be escaped?  thanks in advance.


问:
Delegate Referencing to NULL
I have a problem with delegates and that are referencing to null, I have this:

First I define the delegate which is going to act:

```<code>    public delegate void MandarComponente(int Componente);
    public event MandarComponente MandarComp;
</code>```

As I want this to be in a drag-and-drop operation, I'm going to put some of the important stuff of the code of the drag + drop

```<code>        private void Capacitor_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) //This is a PictureBox Event
    {
        componente = 1;
        Capacitor.DoDragDrop(Capacitor.Image, DragDropEffects.Copy | DragDropEffects.Move);
    }
</code>```

Once I have It, then I'm going to use it in the event

```<code>public void tableLayoutPanel2_DragDrop(object sender, DragEventArgs e)
    {
        Point pl = new Point(this.Location.X + tableLayoutPanel2.Location.X + 10, this.Location.Y + tableLayoutPanel2.Location.Y + 32);
        int R = (int)((e.Y - pl.Y) / pictureBox1.Height);
        int C = (int)((e.X - pl.X) / pictureBox1.Width);
        Console.WriteLine("X=" + e.X + "Y=" + e.Y + " [" + C + ", " + R + "]");

        if (R == tableLayoutPanel2.RowCount) R--;
        if (C == tableLayoutPanel2.ColumnCount) C--;

        PictureBox pictureBox = (PictureBox)tableLayoutPanel2.GetControlFromPosition(C, R);

        if (R == 0 && C == 0 || R == 2 && C == 0 || R == 2 && C == 2 || R == 0 && C == 2)
        {
            MessageBox.Show("¡No puedes poner un componente ahí!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            pictureBox = null;
        }

        if (componente == 1 && pictureBox != null)
        {
                pictureBox.Image = Capacitor.Image;
                MandarComp(componente);
                MandarComp = new MandarComponente(CambiarTexto);

                if (R == 1 && C == 2 || R == 1 && C == 0)
                {
                    pictureBox.Image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                }
        }
</code>```

That is referencing this method:

```<code>    void CambiarTexto(int Componente)
    {
        if(Componente==1)
        {
            label5.Text = "Componente Seleccionado: CAPACITOR";
        }

    }
</code>```

But the part of MandarCom(Componente) always has an exception of NullReferenceException.

Edit: Basically what I'm trying to do is that the delegate MandarComponente(int Componente) saves componente and then send it to the CambiarTexto method so It would do the action in label5.Text.

答:
For using an event, before you invoking it, firstly you have to give it a value, which means the index of your assignemnt and invoking is wrong.
that should be:

```<code>MandarComp += CambiarTexto;//For event, += is used more offen than directly assignment.
MandarComp(Componente);
</code>```

That should work.

Besides, if you are using the latest version of C#, it allows you to write like this MandarComp?.Invoke() to avoid a NullReferenceExcption.

Moreover, I also suggest you to start with some basic using of delegate and event.
If your delegate is just used in the owner class, that's kind of waste. Directly invoking of that method will do the same thing.

Title: Delegate Referencing to NULL

Body:
I have a problem with delegates and that are referencing to null, I have this:

First I define the delegate which is going to act:

    public delegate void MandarComponente(int Componente);
    public event MandarComponente MandarComp;

As I want this to be in a drag-and-drop operation, I'm going to put some of the important stuff of the code of the drag + drop

        private void Capacitor_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) //This is a PictureBox Event
    {
        componente = 1;
        Capacitor.DoDragDrop(Capacitor.Image, DragDropEffects.Copy | DragDropEffects.Move);
    }

Once I have It, then I'm going to use it in the event

public void tableLayoutPanel2_DragDrop(object sender, DragEventArgs e)
    {
        Point pl = new Point(this.Location.X + tableLayoutPanel2.Location.X + 10, this.Location.Y + tableLayoutPanel2.Location.Y + 32);
        int R = (int)((e.Y - pl.Y) / pictureBox1.Height);
        int C = (int)((e.X - pl.X) / pictureBox1.Width);
        Console.WriteLine("X=" + e.X + "Y=" + e.Y + " [" + C + ", " + R + "]");

        if (R == tableLayoutPanel2.RowCount) R--;
        if (C == tableLayoutPanel2.ColumnCount) C--;

        PictureBox pictureBox = (PictureBox)tableLayoutPanel2.GetControlFromPosition(C, R);

        if (R == 0 && C == 0 || R == 2 && C == 0 || R == 2 && C == 2 || R == 0 && C == 2)
        {
            MessageBox.Show("¡No puedes poner un componente ahí!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            pictureBox = null;
        }

        if (componente == 1 && pictureBox != null)
        {
                pictureBox.Image = Capacitor.Image;
                MandarComp(componente);
                MandarComp = new MandarComponente(CambiarTexto);

                if (R == 1 && C == 2 || R == 1 && C == 0)
                {
                    pictureBox.Image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                }
        }

That is referencing this method:

    void CambiarTexto(int Componente)
    {
        if(Componente==1)
        {
            label5.Text = "Componente Seleccionado: CAPACITOR";
        }

    }

But the part of MandarCom(Componente) always has an exception of NullReferenceException.

Edit: Basically what I'm trying to do is that the delegate MandarComponente(int Componente) saves componente and then send it to the CambiarTexto method so It would do the action in label5.Text.

Body:
For using an event, before you invoking it, firstly you have to give it a value, which means the index of your assignemnt and invoking is wrong.
that should be:

MandarComp += CambiarTexto;//For event, += is used more offen than directly assignment.
MandarComp(Componente);

That should work.

Besides, if you are using the latest version of C#, it allows you to write like this MandarComp?.Invoke() to avoid a NullReferenceExcption.

Moreover, I also suggest you to start with some basic using of delegate and event.
If your delegate is just used in the owner class, that's kind of waste. Directly invoking of that method will do the same thing.


问:
Not Loading the value in Real Time
I am using below code to get the total number of documents from the firestore collection and then store it to int countDocument, it does get the value accurately, but when I used to display the same value in the Flutter widget Text Widget which is nested in Scaffold, upon loading the screen it does not show the value, showing null only, only upon hot reload it shows the value on the screen.

To represent the value of countDocument in Text Widget, I did countDocument.toString()' but still it does not show the value upon initial loading of the screen

How should I resolve it?

```<code>void countDocuments() async {
    StreamSubscription<QuerySnapshot> _myDoc = await Firestore.instance.collection('users').snapshots().listen((result) {

         countDocument = result.documents.length;
         print(countDocument);

    });
</code>```

答:
You need to use a StatefulWidget, then using setState, you can change the data of the Text:

```<code>  void countDocuments() async {
    StreamSubscription<QuerySnapshot> _myDoc = await Firestore.instance
        .collection('users')
        .snapshots()
        .listen((result) {
      setState(() {
        countDocument = result.documents.length;
      });
      print(countDocument);
    });
  }
</code>```

setState will call the build method again with the new data. Inside the build method you can do the following:

```<code>Text(countDocument ?? "loading")
</code>```

Title: Not Loading the value in Real Time

Body:
I am using below code to get the total number of documents from the firestore collection and then store it to int countDocument, it does get the value accurately, but when I used to display the same value in the Flutter widget Text Widget which is nested in Scaffold, upon loading the screen it does not show the value, showing null only, only upon hot reload it shows the value on the screen.

To represent the value of countDocument in Text Widget, I did countDocument.toString()' but still it does not show the value upon initial loading of the screen

How should I resolve it?

void countDocuments() async {
    StreamSubscription<QuerySnapshot> _myDoc = await Firestore.instance.collection('users').snapshots().listen((result) {

         countDocument = result.documents.length;
         print(countDocument);

    });

Body:
You need to use a StatefulWidget, then using setState, you can change the data of the Text:

  void countDocuments() async {
    StreamSubscription<QuerySnapshot> _myDoc = await Firestore.instance
        .collection('users')
        .snapshots()
        .listen((result) {
      setState(() {
        countDocument = result.documents.length;
      });
      print(countDocument);
    });
  }

setState will call the build method again with the new data. Inside the build method you can do the following:

Text(countDocument ?? "loading")


问:
bash error when comparing string with slash
Why is it an error if string starts with a slash?

```<code>[[ "/a" -eq "a" ]]
-bash: [[: /a: syntax error: operand expected (error token is "/a")
</code>```

Seems a bit unexpected.

答:
Problem is not / but use of -eq operator, which is used for integer equality in shell.

If you change -eq with = then error will not be there:

```<code>[[ "/a" = "a" ]] && date || pwd
</code>```

Body:
Why is it an error if string starts with a slash?

[[ "/a" -eq "a" ]]
-bash: [[: /a: syntax error: operand expected (error token is "/a")

Seems a bit unexpected.

Body:
Problem is not / but use of -eq operator, which is used for integer equality in shell.

If you change -eq with = then error will not be there:

[[ "/a" = "a" ]] && date || pwd


问:
PowerBI publish to web add parameter
I have a Power BI report that I want to integrate with my outward facing website.

On my website, if the user clicks on the name "Frank" I would like to pass this paramter to my BI Report. Internally this works with

Query00/name eq 'Frank' appended to the report's URL.

However, when I publish this report to the WEB (Public not within the organization) this parameter string does not work. How do I pass a parameter to a published BI report?

答:
INTEGRATION OF POWER BI WITH HTML PAGE AND ESTABLISHING COMMUNICATION BTW HTML PAGE AND POWER BI

In this example we will embed the powerbi content in html page and create button in html page through which the view of the page will change. the below example i have modified as per above question

```<code><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<button class="textLarge" onclick='show("ReportSection", "Frank");' style="display: inline-block;">Frank</button>
</code>```

So here I am using a button click function "show" which has two parameters one is "page name" and other is "filtervalue"

and I have a iframe through which I am embedding my power bi report.
just remember that the filter value and you are putting is similar to the one in the published Bi report. Avoid spelling mistake as there would be character matching on the string.

```<code> <iframe id="embeddedframe" width="2000" height="1000"  src="https://app.powerbi.com/reportEmbed?reportId=(put_your_report_id_here_and remove_parenthesis)&groupId=(put_your_group_id_here_and remove_parenthesis)&autoAuth=true&ctid=(put_your_ct_id_here_and remove_parenthesis)&pageName=" frameborder="0" allowFullScreen="true"></iframe>
</code>```

Basically you don't have to edit the iframe URL, you can directly get it from bi service portal

Then call the below function

In below  function you need to edit the
1) baseURL
2) Table_Nameand Colum_Name
3)iframe_id

```<code><script>

function show(pageName, filterValue)
{

var baseUrl='https://app.powerbi.com/reportEmbed?
reportId=b0f&groupId=e2c&autoAuth=true&ctid=efc8&config=e&pageName='

var newUrl = baseUrl + "&pageName=" + pageName;

if(null != filterValue && "" != filterValue)

{

newUrl += "&$filter=Table_Name/Column_name eq '" + filterValue + "'";

}

//Assumes there's an iFrame on the page with id="iFrame"

var report = document.getElementById("embeddedframe")

report.src = newUrl;

}
</script>
</code>```

Title: PowerBI publish to web add parameter

Body:
INTEGRATION OF POWER BI WITH HTML PAGE AND ESTABLISHING COMMUNICATION BTW HTML PAGE AND POWER BI

In this example we will embed the powerbi content in html page and create button in html page through which the view of the page will change. the below example i have modified as per above question

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<button class="textLarge" onclick='show("ReportSection", "Frank");' style="display: inline-block;">Frank</button>

So here I am using a button click function "show" which has two parameters one is "page name" and other is "filtervalue"

and I have a iframe through which I am embedding my power bi report.
just remember that the filter value and you are putting is similar to the one in the published Bi report. Avoid spelling mistake as there would be character matching on the string.

 <iframe id="embeddedframe" width="2000" height="1000"  src="https://app.powerbi.com/reportEmbed?reportId=(put_your_report_id_here_and remove_parenthesis)&groupId=(put_your_group_id_here_and remove_parenthesis)&autoAuth=true&ctid=(put_your_ct_id_here_and remove_parenthesis)&pageName=" frameborder="0" allowFullScreen="true"></iframe>

Basically you don't have to edit the iframe URL, you can directly get it from bi service portal

Then call the below function

In below  function you need to edit the
1) baseURL
2) Table_Nameand Colum_Name
3)iframe_id

<script>

function show(pageName, filterValue)
{

var baseUrl='https://app.powerbi.com/reportEmbed?
reportId=b0f&groupId=e2c&autoAuth=true&ctid=efc8&config=e&pageName='

var newUrl = baseUrl + "&pageName=" + pageName;

if(null != filterValue && "" != filterValue)

{

newUrl += "&$filter=Table_Name/Column_name eq '" + filterValue + "'";

}

//Assumes there's an iFrame on the page with id="iFrame"

var report = document.getElementById("embeddedframe")

report.src = newUrl;

}
</script>


问:
Reading Json Data from MySql in Golang?
I am facing a case where I had to store dynamic values in the database with key and value pairs given by the user itself.

User gives the key and value, and I interpret it as

{"key": "user Given", "value": "user Given"}

and I add all such things to an array, and I want this array to be read into Go code where the array of objects is read from the Database  table.

答:
You can use the JSON Unmarshaler interface, but depending on how you are retrieving the data from MySql, will vary your implementation. But the idea is the same. For this example, I use https://github.com/go-sql-driver/mysql and assuming you want to store the data in an actual JSON field (Mysql >= 5.7), you could do something like this:</p>

```<code>type MyField struct {
    Key string `json:"key"`
    Value string `json:"value"`
}

type MyModel struct {
    ID uint64
    MyFieldName MyField `json:"my_field_name"`
}

func (m *MyField) Scan(src interface{}) error {
    // The data stored in a JSON field is actually returned as []uint8
    val := src.([]uint8)
    return json.Unmarshal(val, &m)
}

func main() {
    db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1)/dbname")
    if err != nil {
        panic(err.Error())
    }
    defer db.Close()

    results, err := db.Query("SELECT id, my_field_name FROM my_table")

    if err != nil {
        panic(err.Error())
    }

    for results.Next() {
        var row MyModel
        err := results.Scan(&row.ID, &row.MyFieldName)
        if err != nil {
            panic(err.Error())
        }
        fmt.Println(row.MyFieldName.Key)
    }
}
</code>```

Title: Reading Json Data from MySql in Golang?

Body:
You can use the JSON Unmarshaler interface, but depending on how you are retrieving the data from MySql, will vary your implementation. But the idea is the same. For this example, I use https://github.com/go-sql-driver/mysql and assuming you want to store the data in an actual JSON field (Mysql >= 5.7), you could do something like this:

type MyField struct {
    Key string `json:"key"`
    Value string `json:"value"`
}

type MyModel struct {
    ID uint64
    MyFieldName MyField `json:"my_field_name"`
}

func (m *MyField) Scan(src interface{}) error {
    // The data stored in a JSON field is actually returned as []uint8
    val := src.([]uint8)
    return json.Unmarshal(val, &m)
}

func main() {
    db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1)/dbname")
    if err != nil {
        panic(err.Error())
    }
    defer db.Close()

    results, err := db.Query("SELECT id, my_field_name FROM my_table")

    if err != nil {
        panic(err.Error())
    }

    for results.Next() {
        var row MyModel
        err := results.Scan(&row.ID, &row.MyFieldName)
        if err != nil {
            panic(err.Error())
        }
        fmt.Println(row.MyFieldName.Key)
    }
}


问:
?: ?? Operators Instead Of IF|ELSE
```<code>public string Source
{
    get
    {
        /*
        if ( Source == null ){
            return string . Empty;
        } else {
            return Source;
        }
        */
        return Source ?? string.Empty;
    }
    set
    {
        /*
        if ( Source == null ) {
            Source = string . Empty;
        } else {
            if ( Source == value ) {
                Source = Source;
            } else {
                Source = value;
            }
        }
        */
        Source == value ? Source : value ?? string.Empty;
        RaisePropertyChanged ( "Source" );
    }
}
</code>```

Can I use ?: ?? operators EXACTLY as If/Else?

My Question :

How to write the following with ?: ?? operators

[ 1 ]

```<code>if ( Source == null ){
    // Return Nothing
} else {
    return Source;
}
</code>```

[ 2 ]

```<code>if ( Source == value ){
    // Do Nothing
} else {
    Source = value;
    RaisePropertyChanged ( "Source" );
}
</code>```

Briefly : How to do nothing, return nothing and do multiple instructions with ?: ?? operator?

答:
The "do nothing" doesn't really work for ?

if by // Return Nothing you actually mean return null then write

```<code>return Source;
</code>```

if you mean, ignore the codepath then write

```<code> if ( Source != null )
            {
                return Source;
            }
// source is null so continue on.
</code>```

And for the last

```<code> if ( Source != value )
            { Source = value;
                RaisePropertyChanged ( "Source" );
            }

// nothing done.
</code>```

Title: ?: ?? Operators Instead Of IF|ELSE

Body:
public string Source
{
    get
    {
        /*
        if ( Source == null ){
            return string . Empty;
        } else {
            return Source;
        }
        */
        return Source ?? string.Empty;
    }
    set
    {
        /*
        if ( Source == null ) {
            Source = string . Empty;
        } else {
            if ( Source == value ) {
                Source = Source;
            } else {
                Source = value;
            }
        }
        */
        Source == value ? Source : value ?? string.Empty;
        RaisePropertyChanged ( "Source" );
    }
}

Can I use ?: ?? operators EXACTLY as If/Else?

My Question :

How to write the following with ?: ?? operators

[ 1 ]

if ( Source == null ){
    // Return Nothing
} else {
    return Source;
}

[ 2 ]

if ( Source == value ){
    // Do Nothing
} else {
    Source = value;
    RaisePropertyChanged ( "Source" );
}

Briefly : How to do nothing, return nothing and do multiple instructions with ?: ?? operator?

Body:
The "do nothing" doesn't really work for ?

if by // Return Nothing you actually mean return null then write

return Source;

if you mean, ignore the codepath then write

 if ( Source != null )
            {
                return Source;
            }
// source is null so continue on.

And for the last

 if ( Source != value )
            { Source = value;
                RaisePropertyChanged ( "Source" );
            }

// nothing done.


问:
Do you have to flush your BinaryWriter data
In C# I am using BinaryWriter like this:

```<code>BinaryWriter br = new BinaryWriter(myPipe);
var bytes = new byte[5];
br.Write(bytes);
br.Flush();
</code>```

https://msdn.microsoft.com/de-de/library/system.io.binarywriter.flush(v=vs.110).aspx mentions you should use flush your binary writer.

However I noticed that the data already gets send as soon as br.Write is called and I see no need to call br.Flush?

I am wondering if I can remove that 1 (unnecessary) line of code: br.Flush() or if there is more to it?

答:
Calling Flush() with BinaryWriter simply flushes the underlying stream ( BaseStream ).

This is normally done automatically when the underlying stream is closed, so in most cases you do not need to call it explicitly, and if you are writing multiple records using BinaryWriter, and the underlying stream is a FileStream, it will be much more efficient not to call it each time.

You also do not need to call Flush ( for BinaryWriter ) before calling Seek, when writing multiple records to different locations.

For other stream writing classes which do buffer data the situation may be different.

Body:
In C# I am using BinaryWriter like this:

BinaryWriter br = new BinaryWriter(myPipe);
var bytes = new byte[5];
br.Write(bytes);
br.Flush();

https://msdn.microsoft.com/de-de/library/system.io.binarywriter.flush(v=vs.110).aspx mentions you should use flush your binary writer.

However I noticed that the data already gets send as soon as br.Write is called and I see no need to call br.Flush?

I am wondering if I can remove that 1 (unnecessary) line of code: br.Flush() or if there is more to it?


问:
How to keep trailing zeros when dividing a BigDecimal
I have a requirement where I need to divide one BigDecimal number by 100 and show the exact amount that comes up without removing trailing zeros. But zeros are getting trimmed by default. How do I prevent that?

```<code>BigDecimal endDte = new BigDecimal("2609.8200");
BigDecimal startDte = new BigDecimal("100");

BigDecimal finalPerformance = endDte.divide(startDte);
System.out.println(finalPerformance.toString());
</code>```

Output: 26.0982
Expected: 26.098200

答:
What you want is formatting as those 0 does not add to value. You can use this and you will get desired output.

        BigDecimal endDte = new BigDecimal("2609.8200");
        BigDecimal startDte = new BigDecimal("100");

        BigDecimal finalPerformance = endDte.divide(startDte);
        System.out.printf("%2.6f%n", finalPerformance);
```

<p>Other option if you always want to divide by 100, you can just shift the decimal. When you do that, the precision remains the same. In that case the new code to try is</p>

<pre class="lang-java prettyprint-override"><code>
        BigDecimal endDte = new BigDecimal("2609.8200");
        //BigDecimal startDte = new BigDecimal("100");

        BigDecimal finalPerformance = endDte.movePointLeft(2);
        System.out.println(finalPerformance);
</code>```

Body:
I have a requirement where I need to divide one BigDecimal number by 100 and show the exact amount that comes up without removing trailing zeros. But zeros are getting trimmed by default. How do I prevent that?

BigDecimal endDte = new BigDecimal("2609.8200");
BigDecimal startDte = new BigDecimal("100");

BigDecimal finalPerformance = endDte.divide(startDte);
System.out.println(finalPerformance.toString());

Output: 26.0982
Expected: 26.098200

Body:
What you want is formatting as those 0 does not add to value. You can use this and you will get desired output.

        BigDecimal endDte = new BigDecimal("2609.8200");
        BigDecimal startDte = new BigDecimal("100");

        BigDecimal finalPerformance = endDte.divide(startDte);
        System.out.printf("%2.6f%n", finalPerformance);

Other option if you always want to divide by 100, you can just shift the decimal. When you do that, the precision remains the same. In that case the new code to try is

        BigDecimal endDte = new BigDecimal("2609.8200");
        //BigDecimal startDte = new BigDecimal("100");

        BigDecimal finalPerformance = endDte.movePointLeft(2);
        System.out.println(finalPerformance);


问:
How do you check if string ends with another string in Ada?
There are canonical answers to this question for every popular language, even though that answer usually boils down to: "Use string.endsWith() from the standard library". For Ada, as far as I can find in the docs for the Fixed String package, there is no string.endswith function.

So, given two fixed strings A and B, how do you check if A ends with B?

```<code>declare
   A : constant String := "John Johnson";
   B : constant String := "son";
begin
   if A.Ends_With(B) then -- this doesn't compile
      Put_Line ("Yay!");
   end if;
end
</code>```

My intent is to establish a standard answer for Ada.

答:
Well, here's a possible solution:

main.adb

with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;

procedure Main is

   A : constant String := "John Johnson";
   B : constant String := "son";

begin

   if Tail (A, B'Length) = B then
      Put_Line ("Yay!");
   end if;

end Main;
```

<p><strong>output</strong></p>

```$ ./main
Yay!
```

<hr>

<p><strong>UPDATE (2)</strong></p>

<p>Another update (thanks @Brian Drummond for the comment; comment disappeared though), again using <code>Tail</code>. This is now almost identical to @Zerte's answer, except for the dependency on <code>Ada.Strings.Fixed</code>:</p>

<p><strong>main.adb</strong></p>

```with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Assertions;    use Ada.Assertions;

procedure Main is

   function Ends_With (Source, Pattern : String) return Boolean is
   begin
      return Source'Length >= Pattern'Length and then
        Tail (Source, Pattern'Length) = Pattern;
   end Ends_With;

begin

   Assert (Ends_With ("John Johnson", "son")  = True);
   Assert (Ends_With ("hi", "longer than hi") = False);

   Assert (Ends_With (""  , ""  ) = True);
   Assert (Ends_With (" " , ""  ) = True);
   Assert (Ends_With (""  , " " ) = False);
   Assert (Ends_With (" " , " " ) = True);

   Assert (Ends_With ("n ", "n ") = True);
   Assert (Ends_With (" n", "n" ) = True);
   Assert (Ends_With ("n" , " n") = False);
   Assert (Ends_With (" n", " n") = True);

   Put_Line ("All OK.");

end Main;
```

<p><strong>output</strong></p>

<pre class="lang-none prettyprint-override"><code>$ ./main
All OK.
</code>```

Body:
There are canonical answers to this question for every popular language, even though that answer usually boils down to: "Use string.endsWith() from the standard library". For Ada, as far as I can find in the docs for the Fixed String package, there is no string.endswith function.

So, given two fixed strings A and B, how do you check if A ends with B?

declare
   A : constant String := "John Johnson";
   B : constant String := "son";
begin
   if A.Ends_With(B) then -- this doesn't compile
      Put_Line ("Yay!");
   end if;
end

My intent is to establish a standard answer for Ada.

Body:
Well, here's a possible solution:

main.adb

with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;

procedure Main is

   A : constant String := "John Johnson";
   B : constant String := "son";

begin

   if Tail (A, B'Length) = B then
      Put_Line ("Yay!");
   end if;

end Main;

output

$ ./main
Yay!

UPDATE (2)

Another update (thanks @Brian Drummond for the comment; comment disappeared though), again using Tail. This is now almost identical to @Zerte's answer, except for the dependency on Ada.Strings.Fixed:

main.adb

with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Assertions;    use Ada.Assertions;

procedure Main is

   function Ends_With (Source, Pattern : String) return Boolean is
   begin
      return Source'Length >= Pattern'Length and then
        Tail (Source, Pattern'Length) = Pattern;
   end Ends_With;

begin

   Assert (Ends_With ("John Johnson", "son")  = True);
   Assert (Ends_With ("hi", "longer than hi") = False);

   Assert (Ends_With (""  , ""  ) = True);
   Assert (Ends_With (" " , ""  ) = True);
   Assert (Ends_With (""  , " " ) = False);
   Assert (Ends_With (" " , " " ) = True);

   Assert (Ends_With ("n ", "n ") = True);
   Assert (Ends_With (" n", "n" ) = True);
   Assert (Ends_With ("n" , " n") = False);
   Assert (Ends_With (" n", " n") = True);

   Put_Line ("All OK.");

end Main;

output

$ ./main
All OK.


问:
Resolve ambiguity between strings and numbers in lark
I'm writing a grammar for a YAML-like serialization format. I'm using a LALR parser. I've hit a roadblock when parsing scalars. A scalar can be a string or a number (let's keep it simple and make it only decimals or floats). Here's what I have so far, I've kept only what's relevant here:

```<code>pair: pair_key ":" _value
_value: scalar | collection

scalar : (string | number) _NL+
string : WORD+
number : DECIMAL | FLOAT
DECIMAL : /0|[1-9]\d*/i
FLOAT: /((\d+\.\d*|\.\d+)(e[-+]?\d+)?|\d+(e[-+]?\d+))/i
WORD:  /[^-:#()\[\]{}\n\s]+/

// NEWLINE
_NL: /(\r?\n[\t ]*)+/

%import common.WS_INLINE
%ignore WS_INLINE
</code>```

A string is one or more words. A WORD can contain any characters except the ones I put in the negated set of the regex of WORD. I want my strings to be able to contain numbers and still be parsed as strings, that's why there are no digits in my negated set for WORD. The problem lies when a string begins with a number as such:

test_strings = """
a : 28 should be parsed as string
b : 28
"""
```

<p>The parser can't decide between parsing a number or word when it sees 28 at the beginning.</p>

<p>Here's what I get:</p>

```top_map
  pair
    pair_key
      string    a
    scalar
      string
        28
        should
        be
        parsed
        as
        string
  pair
    pair_key
      string    b
    scalar
      string    28
```

<p>Expected:</p>

```top_map
  pair
    pair_key
      string    a
    scalar
      string
        28
        should
        be
        parsed
        as
        string
  pair
    pair_key
      string    b
    scalar
      number    28
```

<p>How do I go about resolving this ambuigity? Is there a way to do this using only the grammar? Note that I don't want my strings to be surrounded with quotes or other symbols to be able to identify them. </p>

<p><strong>Edit</strong></p>

<p>I've solved the problem using higher priorities on my number rule as such:</p>

```string : number WORD+ | WORD+
number.2 : DECIMAL | FLOAT
DECIMAL.2 : /0|[1-9]\d*/i
FLOAT.2: /((\d+\.\d*|\.\d+)(e[-+]?\d+)?|\d+(e[-+]?\d+))/i
WORD:  /[^-:#()\[\]{}\n\s]+/
```

That way a number will be parsed as a number rather than a WORD. And strings that begin with numbers must have WORDs that come after. So there is no string that's just a number in this modified version.

答:
It sounds to me like you should keep the grammar as-is, and convert the strings to numbers, when valid, after the parse is done.

You could still use the explicit number rule where it could affect the context of the parse, but here the ambiguity is something that can be resolved afterwards, and that would be the simplest solution.

Another solution, just for completeness, would be to make the entire string a single regexp (i.e. it will also include the whitespace), and to make sure while writing it that it has to match more than just digits.

Something like:

```<code>CHAR: /[^-:#()\[\]{}\n]/
CHAR_ND: /[^-:#()\[\]{}\n\d]/
STRING:  CHAR_ND CHAR* | CHAR* CHAR_ND
</code>```

Body:
I'm writing a grammar for a YAML-like serialization format. I'm using a LALR parser. I've hit a roadblock when parsing scalars. A scalar can be a string or a number (let's keep it simple and make it only decimals or floats). Here's what I have so far, I've kept only what's relevant here:

pair: pair_key ":" _value
_value: scalar | collection

scalar : (string | number) _NL+
string : WORD+
number : DECIMAL | FLOAT
DECIMAL : /0|[1-9]\d*/i
FLOAT: /((\d+\.\d*|\.\d+)(e[-+]?\d+)?|\d+(e[-+]?\d+))/i
WORD:  /[^-:#()\[\]{}\n\s]+/

// NEWLINE
_NL: /(\r?\n[\t ]*)+/

%import common.WS_INLINE
%ignore WS_INLINE

A string is one or more words. A WORD can contain any characters except the ones I put in the negated set of the regex of WORD. I want my strings to be able to contain numbers and still be parsed as strings, that's why there are no digits in my negated set for WORD. The problem lies when a string begins with a number as such:

test_strings = """
a : 28 should be parsed as string
b : 28
"""

The parser can't decide between parsing a number or word when it sees 28 at the beginning.

Here's what I get:

top_map
  pair
    pair_key
      string    a
    scalar
      string
        28
        should
        be
        parsed
        as
        string
  pair
    pair_key
      string    b
    scalar
      string    28

Expected:

top_map
  pair
    pair_key
      string    a
    scalar
      string
        28
        should
        be
        parsed
        as
        string
  pair
    pair_key
      string    b
    scalar
      number    28

How do I go about resolving this ambuigity? Is there a way to do this using only the grammar? Note that I don't want my strings to be surrounded with quotes or other symbols to be able to identify them.

Edit

I've solved the problem using higher priorities on my number rule as such:

string : number WORD+ | WORD+
number.2 : DECIMAL | FLOAT
DECIMAL.2 : /0|[1-9]\d*/i
FLOAT.2: /((\d+\.\d*|\.\d+)(e[-+]?\d+)?|\d+(e[-+]?\d+))/i
WORD:  /[^-:#()\[\]{}\n\s]+/

That way a number will be parsed as a number rather than a WORD. And strings that begin with numbers must have WORDs that come after. So there is no string that's just a number in this modified version.

Body:
It sounds to me like you should keep the grammar as-is, and convert the strings to numbers, when valid, after the parse is done.

You could still use the explicit number rule where it could affect the context of the parse, but here the ambiguity is something that can be resolved afterwards, and that would be the simplest solution.

Another solution, just for completeness, would be to make the entire string a single regexp (i.e. it will also include the whitespace), and to make sure while writing it that it has to match more than just digits.

Something like:

CHAR: /[^-:#()\[\]{}\n]/
CHAR_ND: /[^-:#()\[\]{}\n\d]/
STRING:  CHAR_ND CHAR* | CHAR* CHAR_ND


问:
be aware of the end of a loop of threads in NodeJS
I have to generate images in my NodeJS app, using Pageres

I do it in a loop. So, I have 2 options:

Option 1:

```<code>async function makePngScreenshot(url, meterId, filename) {
    axios.get(url, null); // Make the request to generate html page
    await new Pageres({delay: 2, filename: filename})
        .src(url, ['1300x650'], {crop: true})
        .dest("public/images/" + operation.data.name + "/" + yearAndMonthFolder + "/" + meterId
        )
        .run();
}
</code>```

And then call it:

```<code>for (let firstDay = monday; firstDay < lastDay; firstDay.add(7, "day")) {
    await makePngScreenshot(url, id, filename);
}
</code>```

This method is ok, but is very slow, as it is generating the screenshots one by one.

Option 2:

The second method intent to generate the screenshots with concurrence:

```<code>function makePngScreenshot(url, meterId, filename) {
    axios.get(url, null); // Make the request to generate html page
    (async () => { // Make screenshot
        await new Pageres({delay: 2, filename: filename})
            .src(url, ['1300x650'], {crop: true})
            .dest("public/images/" + operation.data.name + "/" + yearAndMonthFolder + "/" + meterId
            )
            .run();
    })();
}
</code>```

And calling it:

```<code>for (let firstDay = monday; firstDay < lastDay; firstDay.add(7, "day")) {
        makePngScreenshot(url, id, filename);
    }
console.log("done")
</code>```

This method is much faster, and I would like to use it, but I don't know how to print done after all screenshots has been generated, right now, it prints before generation.

How can be aware of the end of all threads ?

答:
You can use Promise.all() for this purpose. You'll need to return a Promise from makePngScreenShot, which is a minor modification, and also call makePngScreenShot from an async function.

This would look something like so:

```<code>async function makePngScreenshot(url, meterId, filename) {
    await axios.get(url, null); // Make the request to generate html page
    return new Pageres({delay: 2, filename: filename})
        .src(url, ['1300x650'], {crop: true})
        .dest("public/images/" + operation.data.name + "/" + yearAndMonthFolder + "/" + meterId
        )
        .run();
}

async function makeScreenshots() {
    let promises = [];
    for (let firstDay = monday; firstDay < lastDay; firstDay.add(7, "day")) {
        promises.push(makePngScreenshot(url, id, filename));
    }
    // Wait for all promises to resolve
    await Promise.all(promises);
    console.log("done")
}
</code>```

Body:
I have to generate images in my NodeJS app, using Pageres

I do it in a loop. So, I have 2 options:

Option 1:

async function makePngScreenshot(url, meterId, filename) {
    axios.get(url, null); // Make the request to generate html page
    await new Pageres({delay: 2, filename: filename})
        .src(url, ['1300x650'], {crop: true})
        .dest("public/images/" + operation.data.name + "/" + yearAndMonthFolder + "/" + meterId
        )
        .run();
}

And then call it:

for (let firstDay = monday; firstDay < lastDay; firstDay.add(7, "day")) {
    await makePngScreenshot(url, id, filename);
}

This method is ok, but is very slow, as it is generating the screenshots one by one.

Option 2:

The second method intent to generate the screenshots with concurrence:

function makePngScreenshot(url, meterId, filename) {
    axios.get(url, null); // Make the request to generate html page
    (async () => { // Make screenshot
        await new Pageres({delay: 2, filename: filename})
            .src(url, ['1300x650'], {crop: true})
            .dest("public/images/" + operation.data.name + "/" + yearAndMonthFolder + "/" + meterId
            )
            .run();
    })();
}

And calling it:

for (let firstDay = monday; firstDay < lastDay; firstDay.add(7, "day")) {
        makePngScreenshot(url, id, filename);
    }
console.log("done")

This method is much faster, and I would like to use it, but I don't know how to print done after all screenshots has been generated, right now, it prints before generation.

How can be aware of the end of all threads ?

Body:
You can use Promise.all() for this purpose. You'll need to return a Promise from makePngScreenShot, which is a minor modification, and also call makePngScreenShot from an async function.

This would look something like so:

async function makePngScreenshot(url, meterId, filename) {
    await axios.get(url, null); // Make the request to generate html page
    return new Pageres({delay: 2, filename: filename})
        .src(url, ['1300x650'], {crop: true})
        .dest("public/images/" + operation.data.name + "/" + yearAndMonthFolder + "/" + meterId
        )
        .run();
}

async function makeScreenshots() {
    let promises = [];
    for (let firstDay = monday; firstDay < lastDay; firstDay.add(7, "day")) {
        promises.push(makePngScreenshot(url, id, filename));
    }
    // Wait for all promises to resolve
    await Promise.all(promises);
    console.log("done")
}


问:
Exchange Online and EWS with Basic Auth stopped working
I want to use EWS managed API with basic authentication to connect to Exchange Online.

But in my application the EWS AutodiscoverService is unable to retrive mailbox settings (GetUserSettings) from Exchange Online when using basic authentication, but oAuth works just fine.

I get a Microsoft.Exchange.WebServices.Data.ServiceRequestException with the message "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 40.101.50.162:444"

I have been using basic auth for several years and a few days ago it just stopped working. Is it no longer possible to use basic authentication with Exchange Online and EWS?

Code sample

```<code>var ads = new AutodiscoverService
             {
                 RedirectionUrlValidationCallback = url => true,
                 EnableScpLookup = false
             };
ads.Credentials = new NetworkCredential( svcUsr, svcPwd ); // using these will throw an exception
ads.Credentials = new OAuthCredentials( token.AccessToken ); // these works
var res = ads.GetUserSettings( mailBox, UserSettingName.GroupingInformation );
</code>```

The Exception

```<code>Microsoft.Exchange.WebServices.Data.ServiceRequestException: The request failed. Unable to connect to the remote server ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 40.101.28.194:444
       at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
       at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
       --- End of inner exception stack trace ---
       at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
       at System.Net.HttpWebRequest.GetRequestStream()
       at Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.Microsoft.Exchange.WebServices.Data.IEwsHttpWebRequest.GetRequestStream()
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverRequest.InternalExecute()
       --- End of inner exception stack trace ---
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverRequest.InternalExecute()
       at Microsoft.Exchange.WebServices.Autodiscover.GetUserSettingsRequest.Execute()
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.InternalGetUserSettings(List`1 smtpAddresses, List`1 settings, Nullable`1 requestedVersion, Uri& autodiscoverUrl)
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.GetSettings[TGetSettingsResponseCollection,TSettingName](List`1 identities, List`1 settings, Nullable`1 requestedVersion, GetSettingsMethod`2 getSettingsMethod, Func`1 getDomainMethod)
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.GetUserSettings(List`1 smtpAddresses, List`1 settings)
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.InternalGetSoapUserSettings(String smtpAddress, List`1 requestedSettings)
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.GetUserSettings(String userSmtpAddress, UserSettingName[] userSettingNames)
       at EWSAutoDiscovery.Program.Main(String[] args) in C:\Program.cs:line 57
</code>```

Things tested and verified [Update 1]

I have verified that some EWS operations still work with basic auth,
e.g. SyncFolderItems.

I have verified that the service account user nor the EXO General Config has an Authentication Policy.

I have created an Authentication Policy that enables BasicAuth on all protocols and assigned it to the EXO Organization Config DefaultAuthenticationPolicy parameter.

I have assigned the Authentication Policy to the service account as well as the target user.

I have removed and reapplied the ApplicationImpersonation role on the service account.

答:
Autodiscovery with Basic Authentication started to work again during the night, for all O365/Azure tenants using my application.

Microsoft must have fixed something on their side that they broke a few days ago.

Body:
I want to use EWS managed API with basic authentication to connect to Exchange Online.

But in my application the EWS AutodiscoverService is unable to retrive mailbox settings (GetUserSettings) from Exchange Online when using basic authentication, but oAuth works just fine.

I get a Microsoft.Exchange.WebServices.Data.ServiceRequestException with the message "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 40.101.50.162:444"

I have been using basic auth for several years and a few days ago it just stopped working. Is it no longer possible to use basic authentication with Exchange Online and EWS?

Code sample

var ads = new AutodiscoverService
             {
                 RedirectionUrlValidationCallback = url => true,
                 EnableScpLookup = false
             };
ads.Credentials = new NetworkCredential( svcUsr, svcPwd ); // using these will throw an exception
ads.Credentials = new OAuthCredentials( token.AccessToken ); // these works
var res = ads.GetUserSettings( mailBox, UserSettingName.GroupingInformation );

The Exception

Microsoft.Exchange.WebServices.Data.ServiceRequestException: The request failed. Unable to connect to the remote server ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 40.101.28.194:444
       at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
       at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
       --- End of inner exception stack trace ---
       at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
       at System.Net.HttpWebRequest.GetRequestStream()
       at Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.Microsoft.Exchange.WebServices.Data.IEwsHttpWebRequest.GetRequestStream()
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverRequest.InternalExecute()
       --- End of inner exception stack trace ---
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverRequest.InternalExecute()
       at Microsoft.Exchange.WebServices.Autodiscover.GetUserSettingsRequest.Execute()
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.InternalGetUserSettings(List`1 smtpAddresses, List`1 settings, Nullable`1 requestedVersion, Uri& autodiscoverUrl)
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.GetSettings[TGetSettingsResponseCollection,TSettingName](List`1 identities, List`1 settings, Nullable`1 requestedVersion, GetSettingsMethod`2 getSettingsMethod, Func`1 getDomainMethod)
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.GetUserSettings(List`1 smtpAddresses, List`1 settings)
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.InternalGetSoapUserSettings(String smtpAddress, List`1 requestedSettings)
       at Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService.GetUserSettings(String userSmtpAddress, UserSettingName[] userSettingNames)
       at EWSAutoDiscovery.Program.Main(String[] args) in C:\Program.cs:line 57

Things tested and verified [Update 1]

I have verified that some EWS operations still work with basic auth,
e.g. SyncFolderItems.

I have verified that the service account user nor the EXO General Config has an Authentication Policy.

I have created an Authentication Policy that enables BasicAuth on all protocols and assigned it to the EXO Organization Config DefaultAuthenticationPolicy parameter.

I have assigned the Authentication Policy to the service account as well as the target user.

I have removed and reapplied the ApplicationImpersonation role on the service account.