问:
How to get the new Position of Filtered Data from RecycleView Android
I've Implemented a search Filter in RecycleView by Edittext. I've set onClickListener to the lists.  Everything is working fine when I search by editext, the data showing perfectly. But when I clicked the Filtered Data. it taking the position from the old list, like 0.

my Adapter class

```<code>package com.gujja.ajay.coronovirus;

public class WorldDataAdapter extends RecyclerView.Adapter<WorldDataAdapter.WorldDataViewHolder> {

   private final Context context;
   private ArrayList<CovidCountry> covidCountries;
   private OnItemClickListener covidListener;

public interface OnItemClickListener{
    void onItemClick(int position);
}

public void setOnItemClickListener(OnItemClickListener listener){
    covidListener = listener;
}

public WorldDataAdapter(Context context, ArrayList<CovidCountry> covidCountries) {
    this.covidCountries = covidCountries;
    this.context = context;
}

@NonNull
@Override
public WorldDataViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.activity_world_data_list, parent, false);

    return new WorldDataViewHolder(view,covidListener);
}

@Override
public void onBindViewHolder(@NonNull WorldDataViewHolder holder, int position) {

    CovidCountry covidCountry = covidCountries.get(position);
    String countryFlagUrl = covidCountry.getmCovidCountryImages();

    holder.worldDataTitle.setText(covidCountry.getmCovidCountry());
    holder.worldDataCasesCount.setText(covidCountry.getmCovidCases());
    holder.worldDataDeathCount.setText(covidCountry.getmCovidDeath());

    Picasso.get().load(countryFlagUrl).fit().centerInside().into(holder.countryFlags);

}

@Override
public int getItemCount() {
    return covidCountries.size();
}

public void filteredList(ArrayList<CovidCountry> filteredCountries) {
    covidCountries = new ArrayList<>();
    covidCountries.addAll(filteredCountries);
    notifyDataSetChanged();
}

public static class WorldDataViewHolder extends RecyclerView.ViewHolder {
    TextView worldDataTitle, worldDataDeathCount, worldDataCasesCount, worldNewCasesData;
    ImageView countryFlags;

    public WorldDataViewHolder(@NonNull View itemView, final OnItemClickListener listener) {
        super(itemView);

        worldDataTitle = itemView.findViewById(R.id.WorldDataName);
        worldDataDeathCount = itemView.findViewById(R.id.WorldDataDeathCount);
        worldDataCasesCount = itemView.findViewById(R.id.WorldDataCasesCount);
        countryFlags = itemView.findViewById(R.id.covCountryFlags);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (listener!= null ){
                    int position = getAdapterPosition();

                    if(position != RecyclerView.NO_POSITION){
                        listener.onItemClick(position);
                    }
                }
            }
        });
    }
}
</code>```

hers is my mainactivity class

```<code>public class MainActivity extends AppCompatActivity implements WorldDataAdapter.OnItemClickListener {

public static final String COUNTRY_NAME = "countryName";
private static final String TAG = MainActivity.class.getSimpleName();

TextView title, totalDeath, totalDeathNum, totalCases, totalCasesNum, totalRecovered, totalRecoveredData, activePatient, activePatientData;
ProgressBar progressBar;
EditText editText;

ArrayList<CovidCountry> covidCountries;
RecyclerView WorldRecycleView;
WorldDataAdapter worldDataAdapter;
RecyclerView.LayoutManager mlayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    title = findViewById(R.id.Title);
    totalCases = findViewById(R.id.TotalCases);
    totalCasesNum = findViewById(R.id.TotalCasesData);
    totalDeath = findViewById(R.id.TotalDeath);
    totalDeathNum = findViewById(R.id.TotalDeathData);
    progressBar = findViewById(R.id.Progressloader);
    totalRecovered = findViewById(R.id.TotalRecovered);
    totalRecoveredData = findViewById(R.id.TotalRecoveredData);
    activePatient = findViewById(R.id.TotalActive);
    activePatientData = findViewById(R.id.TotalActiveData);
    editText = findViewById(R.id.search_country);

    getData();
    detDataFromServer();
    buildRecycleView();

    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void afterTextChanged(Editable editable) {
            filter(editable.toString());
        }
    });
}

private void buildRecycleView() {
    WorldRecycleView = findViewById(R.id.RecycleView);
    WorldRecycleView.setHasFixedSize(true);
    mlayoutManager = new LinearLayoutManager(this);
    worldDataAdapter = new WorldDataAdapter(this,covidCountries);

    WorldRecycleView.setLayoutManager(mlayoutManager);
    WorldRecycleView.setAdapter(worldDataAdapter);
}

private void filter(String country) {
    ArrayList<CovidCountry> filteredCountries = new ArrayList<>();

    for(CovidCountry item: covidCountries){
        if (item.getmCovidCountry().toLowerCase().contains(country.toLowerCase())) {

            filteredCountries.add(item);
        }
    }

    worldDataAdapter.filteredList(filteredCountries);

}

@Override
public void onItemClick(int position) {
    Intent  detailIntent = new Intent(this, Deploy_Test.class);
    Log.e(TAG, "onclivk: " + ajay );

    CovidCountry covidCountry = filteredCountries.get(position);
    //CovidCountry detailCountry = covidCountries.get(position);

    //detailIntent.putExtra(COUNTRY_NAME,detailCountry.getmCovidCountry());

    detailIntent.putExtra(COUNTRY_NAME,covidCountry.getmCovidCountry());

    Log.e(TAG, "onItemClick: " + covidCountry );

    startActivity(detailIntent);
}
</code>```

How do I get the new Position of filtered List and set OnclickListener to it?

答: you are not using same arraylist, instead creating different arryalist and displaying.</p>

Body:
I've Implemented a search Filter in RecycleView by Edittext. I've set onClickListener to the lists.  Everything is working fine when I search by editext, the data showing perfectly. But when I clicked the Filtered Data. it taking the position from the old list, like 0.

my Adapter class

package com.gujja.ajay.coronovirus;

public class WorldDataAdapter extends RecyclerView.Adapter<WorldDataAdapter.WorldDataViewHolder> {

   private final Context context;
   private ArrayList<CovidCountry> covidCountries;
   private OnItemClickListener covidListener;

public interface OnItemClickListener{
    void onItemClick(int position);
}

public void setOnItemClickListener(OnItemClickListener listener){
    covidListener = listener;
}

public WorldDataAdapter(Context context, ArrayList<CovidCountry> covidCountries) {
    this.covidCountries = covidCountries;
    this.context = context;
}

@NonNull
@Override
public WorldDataViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.activity_world_data_list, parent, false);

    return new WorldDataViewHolder(view,covidListener);
}

@Override
public void onBindViewHolder(@NonNull WorldDataViewHolder holder, int position) {

    CovidCountry covidCountry = covidCountries.get(position);
    String countryFlagUrl = covidCountry.getmCovidCountryImages();

    holder.worldDataTitle.setText(covidCountry.getmCovidCountry());
    holder.worldDataCasesCount.setText(covidCountry.getmCovidCases());
    holder.worldDataDeathCount.setText(covidCountry.getmCovidDeath());

    Picasso.get().load(countryFlagUrl).fit().centerInside().into(holder.countryFlags);

}

@Override
public int getItemCount() {
    return covidCountries.size();
}

public void filteredList(ArrayList<CovidCountry> filteredCountries) {
    covidCountries = new ArrayList<>();
    covidCountries.addAll(filteredCountries);
    notifyDataSetChanged();
}

public static class WorldDataViewHolder extends RecyclerView.ViewHolder {
    TextView worldDataTitle, worldDataDeathCount, worldDataCasesCount, worldNewCasesData;
    ImageView countryFlags;

    public WorldDataViewHolder(@NonNull View itemView, final OnItemClickListener listener) {
        super(itemView);

        worldDataTitle = itemView.findViewById(R.id.WorldDataName);
        worldDataDeathCount = itemView.findViewById(R.id.WorldDataDeathCount);
        worldDataCasesCount = itemView.findViewById(R.id.WorldDataCasesCount);
        countryFlags = itemView.findViewById(R.id.covCountryFlags);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (listener!= null ){
                    int position = getAdapterPosition();

                    if(position != RecyclerView.NO_POSITION){
                        listener.onItemClick(position);
                    }
                }
            }
        });
    }
}

hers is my mainactivity class

public class MainActivity extends AppCompatActivity implements WorldDataAdapter.OnItemClickListener {

public static final String COUNTRY_NAME = "countryName";
private static final String TAG = MainActivity.class.getSimpleName();

TextView title, totalDeath, totalDeathNum, totalCases, totalCasesNum, totalRecovered, totalRecoveredData, activePatient, activePatientData;
ProgressBar progressBar;
EditText editText;

ArrayList<CovidCountry> covidCountries;
RecyclerView WorldRecycleView;
WorldDataAdapter worldDataAdapter;
RecyclerView.LayoutManager mlayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    title = findViewById(R.id.Title);
    totalCases = findViewById(R.id.TotalCases);
    totalCasesNum = findViewById(R.id.TotalCasesData);
    totalDeath = findViewById(R.id.TotalDeath);
    totalDeathNum = findViewById(R.id.TotalDeathData);
    progressBar = findViewById(R.id.Progressloader);
    totalRecovered = findViewById(R.id.TotalRecovered);
    totalRecoveredData = findViewById(R.id.TotalRecoveredData);
    activePatient = findViewById(R.id.TotalActive);
    activePatientData = findViewById(R.id.TotalActiveData);
    editText = findViewById(R.id.search_country);

    getData();
    detDataFromServer();
    buildRecycleView();

    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void afterTextChanged(Editable editable) {
            filter(editable.toString());
        }
    });
}

private void buildRecycleView() {
    WorldRecycleView = findViewById(R.id.RecycleView);
    WorldRecycleView.setHasFixedSize(true);
    mlayoutManager = new LinearLayoutManager(this);
    worldDataAdapter = new WorldDataAdapter(this,covidCountries);

    WorldRecycleView.setLayoutManager(mlayoutManager);
    WorldRecycleView.setAdapter(worldDataAdapter);
}

private void filter(String country) {
    ArrayList<CovidCountry> filteredCountries = new ArrayList<>();

    for(CovidCountry item: covidCountries){
        if (item.getmCovidCountry().toLowerCase().contains(country.toLowerCase())) {

            filteredCountries.add(item);
        }
    }

    worldDataAdapter.filteredList(filteredCountries);

}

@Override
public void onItemClick(int position) {
    Intent  detailIntent = new Intent(this, Deploy_Test.class);
    Log.e(TAG, "onclivk: " + ajay );

    CovidCountry covidCountry = filteredCountries.get(position);
    //CovidCountry detailCountry = covidCountries.get(position);

    //detailIntent.putExtra(COUNTRY_NAME,detailCountry.getmCovidCountry());

    detailIntent.putExtra(COUNTRY_NAME,covidCountry.getmCovidCountry());

    Log.e(TAG, "onItemClick: " + covidCountry );

    startActivity(detailIntent);
}

How do I get the new Position of filtered List and set OnclickListener to it?


来源: stackexchange

问:
Successive ipywidgets buttons
I'm trying to make a successive process of buttons clicks using ipywidgets buttons.

Click on button 1 is supposed to clear button 1 and display button 2 etc...

It looks like the introduction of the wait variable make my purge function unreachable, and I don't understand why.

```<code>from ipywidgets import Button
from IPython.display import display, clear_output

def purge(sender):
    print('purge')
    clear_output()
    wait=False

for i in range(5):
    print(f'Button number :{i}')
    btn = widgets.Button(description=f'Done', disabled=False,
                        button_style='success', icon='check')
    btn.on_click(purge)
    display(btn)
    wait=True
    while wait:
        pass
</code>```

答:
Your while wait: pass loop is an extremely tight loop that will likely spin a CPU core at 100%. This will bog down not just your program but perhaps even your entire computer.

I think what you want to do is to display the next button not in the for loop, but in the on_click callback.

from ipywidgets import Button
from IPython.display import display, clear_output

def purge(i):
    print(f'Button number :{i}')
    clear_output()
    btn = widgets.Button(description=f'Done', disabled=False,
                        button_style='success', icon='check')
    btn.on_click(purge, i + 1)
    display(btn)

purge(1)
```

Then you can put an if i == 5 in your function to do something else when they reach the last button.

ContentLicense: CC BY-SA 4.0

Title: Successive ipywidgets buttons

Body:
I'm trying to make a successive process of buttons clicks using ipywidgets buttons.

Click on button 1 is supposed to clear button 1 and display button 2 etc...

It looks like the introduction of the wait variable make my purge function unreachable, and I don't understand why.

from ipywidgets import Button
from IPython.display import display, clear_output

def purge(sender):
    print('purge')
    clear_output()
    wait=False

for i in range(5):
    print(f'Button number :{i}')
    btn = widgets.Button(description=f'Done', disabled=False,
                        button_style='success', icon='check')
    btn.on_click(purge)
    display(btn)
    wait=True
    while wait:
        pass

Body:
Your while wait: pass loop is an extremely tight loop that will likely spin a CPU core at 100%. This will bog down not just your program but perhaps even your entire computer.

I think what you want to do is to display the next button not in the for loop, but in the on_click callback.

from ipywidgets import Button
from IPython.display import display, clear_output

def purge(i):
    print(f'Button number :{i}')
    clear_output()
    btn = widgets.Button(description=f'Done', disabled=False,
                        button_style='success', icon='check')
    btn.on_click(purge, i + 1)
    display(btn)

purge(1)

Then you can put an if i == 5 in your function to do something else when they reach the last button.


问:
How to add numbers for a string sentence in Java?
I want to add numbers using Java.

For example, the sentence is given String: "My age is 50, and your age is under 30." If I want to add 5 to the sentence, it should be like
"My age is 55, and your age is under 35."

The restriction is the sentence is given, so you need to extract numbers from the sentence and add the numbers to the original sentence.

I was trying to split by space (" ") and try to add numbers after that.
But I don't know how to substitute numbers with the original sentence.

I am confused since it has comma when I am trying to split by " " and even if you can extract all the numbers from the sentence, I am not sure how can I get back to numbers to string.

```<code>public class Main {

public static Pattern pattern = Pattern.compile("\\d+");

public static String addNumber(String str, int n) {

    Matcher matcher = pattern.matcher(str);
    if (matcher.find()) {
        String theAge = matcher.group(0);
        int newAge = Integer.parseInt(theAge) + n;
    }

    String addSentence = str;

    return addSentence;
}

public static void main(String[] args) {
    String testString = "My age is 50, and your age is under 30.";
    String testString2 = "My age is 50, and your age is under 30 and my friend age is 44.";

    String newSent = addNumber(testString, 5);
    // -> should be "My age is 55, and your age is under 35.
    String newSent2 = addNumber(testString2, 10);
    // -> should be "My age is 60, and your age is under 40 and my friend age is 54.";

}
</code>```

}
enter code here

答:
Use regex API as follows:

```<code>import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        String str = "My age is 50, and your age is under 30.";

        // The number to be added
        int n = 5;

        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            str = str.replace(matcher.group(), String.valueOf(Integer.parseInt(matcher.group()) + n));
        }

        // Display
        System.out.println(str);
    }
}
</code>```

Output:

```<code>My age is 55, and your age is under 35.
</code>```

Body:
I want to add numbers using Java.

For example, the sentence is given String: "My age is 50, and your age is under 30." If I want to add 5 to the sentence, it should be like
"My age is 55, and your age is under 35."

The restriction is the sentence is given, so you need to extract numbers from the sentence and add the numbers to the original sentence.

I was trying to split by space (" ") and try to add numbers after that.
But I don't know how to substitute numbers with the original sentence.

I am confused since it has comma when I am trying to split by " " and even if you can extract all the numbers from the sentence, I am not sure how can I get back to numbers to string.

public class Main {

public static Pattern pattern = Pattern.compile("\\d+");

public static String addNumber(String str, int n) {

    Matcher matcher = pattern.matcher(str);
    if (matcher.find()) {
        String theAge = matcher.group(0);
        int newAge = Integer.parseInt(theAge) + n;
    }

    String addSentence = str;

    return addSentence;
}

public static void main(String[] args) {
    String testString = "My age is 50, and your age is under 30.";
    String testString2 = "My age is 50, and your age is under 30 and my friend age is 44.";

    String newSent = addNumber(testString, 5);
    // -> should be "My age is 55, and your age is under 35.
    String newSent2 = addNumber(testString2, 10);
    // -> should be "My age is 60, and your age is under 40 and my friend age is 54.";

}

}
enter code here

Body:
Use regex API as follows:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        String str = "My age is 50, and your age is under 30.";

        // The number to be added
        int n = 5;

        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            str = str.replace(matcher.group(), String.valueOf(Integer.parseInt(matcher.group()) + n));
        }

        // Display
        System.out.println(str);
    }
}

Output:

My age is 55, and your age is under 35.


问:
How to read OS X *.icns file with Java
I want to read *.icns files in OS X into a BufferedImage. Help</p>

答:
You can youse IconManager. It works with following icons formats:

*.ico - Windows Icon

*.icl - Windows Icon Library

*.icns - Macintosh Icon

ContentLicense: CC BY-SA 3.0

Title: How to read OS X *.icns file with Java


问:
Is using a class which sole purpose is to group 2 (very much related) objects together considered a good idea?
I can't find any information on this anywhere and was wondering whether such a use of a class is considered bad practise or not.

Let me explain. I have a class ToDecimalConverter which converts an integer from any base to decimal. However, I now need to add the functionality to also convert fractions. As such, I abstracted the integer conversion into a separate class and created a new class with the purpose of converting fractions. (Code isn't finished so I just added some comments to explain)

```<code>public class ToDecimalConverter {
    private IntegerToDecimalConverter integerConverter;
    private DoubleToDecimalConverter doubleConverter;

    public double convert(String number, int baseNumber) {
        this.integerConverter = new IntegerToDecimalConverter();
        this.doubleConverter = new DoubleToDecimalConverter();

        number = this.removeZerosAtBeginningOfNumber(number);

        // split the number into integer and fraction so they can be used below:

        int decimalInt = this.integerConverter.convert(integerNumber, baseNumber);
        double decimalDouble = this.doubleConverter.convert(fractioNumber, baseNumber);

        // add them together and return them
    }
}

</code>```

Now, except for the methods that remove the zero's from the start of a number and the method that splits the number into integer and fraction (both of which can easily be abstracted into their own class), the ToDecimalConverter class does nothing but group the integer and fraction converters together.

When searching online, I don't see a lot of classes being used like this. Should this be avoided or not? and if so, what are alternatives?

This meant as a more general question, the above is just to explain what I mean.

Edit: Or should I see it as a sort of mini GoF Facade pattern?

答:
There is nothing wrong with it by default, but I would guess that you could achieve the same result with two methods. something like:

```<code>public int convertFromInt(String number, int baseNumber) {
    int theConvertedInt = 0;
    //Really cool convertion
    return theConvertedInt;
}

public double convertFromFraction(String number, int baseNumber) {
    double theConvertedInt = 0;
    //Really cool convertion
    return theConvertedInt;
}
</code>```

Also, keep in mind that a lot of this conversions are already done by Java native classes like BigInteger, BigDecimal, Integer, Decimal, Double, the Math package and so on.

Body:
I can't find any information on this anywhere and was wondering whether such a use of a class is considered bad practise or not.

Let me explain. I have a class ToDecimalConverter which converts an integer from any base to decimal. However, I now need to add the functionality to also convert fractions. As such, I abstracted the integer conversion into a separate class and created a new class with the purpose of converting fractions. (Code isn't finished so I just added some comments to explain)

public class ToDecimalConverter {
    private IntegerToDecimalConverter integerConverter;
    private DoubleToDecimalConverter doubleConverter;

    public double convert(String number, int baseNumber) {
        this.integerConverter = new IntegerToDecimalConverter();
        this.doubleConverter = new DoubleToDecimalConverter();

        number = this.removeZerosAtBeginningOfNumber(number);

        // split the number into integer and fraction so they can be used below:

        int decimalInt = this.integerConverter.convert(integerNumber, baseNumber);
        double decimalDouble = this.doubleConverter.convert(fractioNumber, baseNumber);

        // add them together and return them
    }
}

Now, except for the methods that remove the zero's from the start of a number and the method that splits the number into integer and fraction (both of which can easily be abstracted into their own class), the ToDecimalConverter class does nothing but group the integer and fraction converters together.

When searching online, I don't see a lot of classes being used like this. Should this be avoided or not? and if so, what are alternatives?

This meant as a more general question, the above is just to explain what I mean.

Edit: Or should I see it as a sort of mini GoF Facade pattern?

Body:
There is nothing wrong with it by default, but I would guess that you could achieve the same result with two methods. something like:

public int convertFromInt(String number, int baseNumber) {
    int theConvertedInt = 0;
    //Really cool convertion
    return theConvertedInt;
}

public double convertFromFraction(String number, int baseNumber) {
    double theConvertedInt = 0;
    //Really cool convertion
    return theConvertedInt;
}

Also, keep in mind that a lot of this conversions are already done by Java native classes like BigInteger, BigDecimal, Integer, Decimal, Double, the Math package and so on.


问:
Ping between aws and gcp
I have created a Site to Site VPN connection between VPC of Google cloud Platform and AWS in North Virginia region for both the VPCs. But the problem is I have been getting a very high ping and low bandwidth while communicating between the instances. Can any one tell me the reason for this?
image showing the ping data

The ping is very high considering they are in a very close region. Please help.

答:
Be aware that any VPN will be traversing the internet, so even though they are relatively close to each other there will be multiple hops before the instances are connected together.

Remember that from the instance it will need to route outside of AWS networks, then to any hops on the internet to GCP and finally routed to the instance and back again to return the response

In addition there is some variation in performance as the line will not be dedicated.

If you want dedicated performance, without traversing the internet you would need to look at AWS Direct Connect. However, this might limit your project because of cost.

Title: Ping between aws and gcp


问:
What all should I delete before uploading a laravel project?
My laravel project contains:- 28,408 files and its size is:- 169.4MB

 Apart from default my packages are:-

```<code>"laravel/ui": "^2.0",
        "pusher/pusher-php-server": "3.0",
        "webpatser/laravel-uuid": "^3.0"
</code>```

I can only upload 10000 files, what should I do?

 As this is my first time uploading any website online it would really help if your answer is in simple manner

-ThankYou

答:
When deploying a Laravel package you should leave out vendor, storage and node_modules.

Then run these scripts on the server to build the dependencies. These needs to be installed on your server.

```<code>npm install

composer install --no-dev
</code>```

This should highly decrease the amount of files you upload.

Body:
My laravel project contains:- 28,408 files and its size is:- 169.4MB

 Apart from default my packages are:-

"laravel/ui": "^2.0",
        "pusher/pusher-php-server": "3.0",
        "webpatser/laravel-uuid": "^3.0"

I can only upload 10000 files, what should I do?

 As this is my first time uploading any website online it would really help if your answer is in simple manner

-ThankYou

Body:
When deploying a Laravel package you should leave out vendor, storage and node_modules.

Then run these scripts on the server to build the dependencies. These needs to be installed on your server.

npm install

composer install --no-dev

This should highly decrease the amount of files you upload.


问:
Could not decode JWT payload from base64
I'm going to decode a JWT token from request header, it looks like this:

eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIsImlzcyI6ImxvY2FsaG9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWlAZ21haWwuY29tIn0

```<code>public static string Base64Decode(string base64EncodedData)
{
    var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
    return Encoding.UTF8.GetString(base64EncodedBytes);
}
</code>```

When passing the token above to decode method, it throws an exception that tells:

Invalid length for a Base-64 char array or string

dotnetfiddle referrence: https://dotnetfiddle.net/Z2TUz9

But when using it in javascript (using atob function), it works properly.

Could anyone tell me why, then tell me how can I decode it in C#?

答:
Before I get into detail about the question, I would generally suggest using a JWT library that can do all that needs to be done with a few function calls.

As a Base64 string, it is indeed too short. A valid Base64 encoded string should have a length that is dividable by 4 and should be padded with 1 or 2 padding characters = if necessary. But JWT uses the slightly different Base64url encoding and in this encoding padding is optional.

But the C# Base64 decoder is quite strict in this regard.
Therefore you need to convert from Base64Url to Base64 and add the missing padding. Besides that, there are also two Base64Url specific characters that need to be converted back to Base64, as shown in the following code:

```<code>using System;

public class Program
{
    public static void Main()
    {
        string token = "eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIsImlzcyI6ImxvY2FsaG9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWlAZ21haWwuY29tIn0";
        token = token.Replace('_', '/').Replace('-', '+');
        switch (token.Length % 4)
        {
            case 2: token += "=="; break;
            case 3: token += "="; break;
        }
        var decoded = Convert.FromBase64String(token);
        var decodedToken = System.Text.Encoding.Default.GetString(decoded);
        Console.WriteLine(decodedToken);
    }
}
</code>```

Code in dotnetfiddle

The datatype of decoded is byte[] and the output would be just the name of the type. To convert it to string and print the JSON I added another line.

The next step from here would be to convert the JSON to a C# object or to use a library as mentioned in the beginning.

Body:
I'm going to decode a JWT token from request header, it looks like this:

eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIsImlzcyI6ImxvY2FsaG9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWlAZ21haWwuY29tIn0

public static string Base64Decode(string base64EncodedData)
{
    var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
    return Encoding.UTF8.GetString(base64EncodedBytes);
}

When passing the token above to decode method, it throws an exception that tells:

Invalid length for a Base-64 char array or string

dotnetfiddle referrence: https://dotnetfiddle.net/Z2TUz9

But when using it in javascript (using atob function), it works properly.

Could anyone tell me why, then tell me how can I decode it in C#?

Body:
Before I get into detail about the question, I would generally suggest using a JWT library that can do all that needs to be done with a few function calls.

As a Base64 string, it is indeed too short. A valid Base64 encoded string should have a length that is dividable by 4 and should be padded with 1 or 2 padding characters = if necessary. But JWT uses the slightly different Base64url encoding and in this encoding padding is optional.

But the C# Base64 decoder is quite strict in this regard.
Therefore you need to convert from Base64Url to Base64 and add the missing padding. Besides that, there are also two Base64Url specific characters that need to be converted back to Base64, as shown in the following code:

using System;

public class Program
{
    public static void Main()
    {
        string token = "eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIsImlzcyI6ImxvY2FsaG9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWlAZ21haWwuY29tIn0";
        token = token.Replace('_', '/').Replace('-', '+');
        switch (token.Length % 4)
        {
            case 2: token += "=="; break;
            case 3: token += "="; break;
        }
        var decoded = Convert.FromBase64String(token);
        var decodedToken = System.Text.Encoding.Default.GetString(decoded);
        Console.WriteLine(decodedToken);
    }
}

Code in dotnetfiddle

The datatype of decoded is byte[] and the output would be just the name of the type. To convert it to string and print the JSON I added another line.

The next step from here would be to convert the JSON to a C# object or to use a library as mentioned in the beginning.


问:
Date Pickers and custom display format
I'm a bit stuck here. My application is a non-mobile database front-end, and I need a date field in my form formatted in 'my own way', that is "20-jan-2020", and an accompanying date picker.

I cannot get the <input "date" /> element to format my date value this way (or can I?)

The picker itself is OK, but I cannot find a reliable way to open it from Javascript (or can I?). The idea was to use a hidden date input, and display the formatted value in a normal text input. Then invoke the picker of the hidden input from a button.

I have been looking for some custom pickers around, but those I find are either designed for mobile (way too big), requires jscript/jquery (which I know nothing about), cannot format the date any better than the built-in one (or is there any?), or overrides the rest of the styling of my font end.

Suggestions welcome.

答:
You can use jQuery UI datepicker. It provides well designed datePicker also with lots of options and events.

Try below code.

var currentDate = new Date();
var monthNames = ["January", "February", "March", "April", "May", "June",
     "July", "August", "September", "October", "November", "December"
];

$(document).ready(function() {
    $("#datInput").val(formatDate(currentDate))

    $( "#hiddenDatePicker").datepicker({
      showOn: "button",
      buttonText: "day",
      onSelect: function(dateText, inst) {
         var formattedDate = formatDate(new Date(dateText));
         $("#datInput").val(formattedDate);
      }
    });

 });

function formatDate(dt) {
   var day = dt.getDate();
   var month = monthNames[dt.getMonth()];
   var year = dt.getFullYear();

   return day + '-' + month + '-' + year;

}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#hiddenDatePicker{
    display: none;
}</code>```

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">

<input type="input" id="hiddenDatePicker" class="datepicker" />
<input type="text" id="datInput"/>```

Title: Date Pickers and custom display format

Body:
You can use jQuery UI datepicker. It provides well designed datePicker also with lots of options and events.

Try below code.

var currentDate = new Date();
var monthNames = ["January", "February", "March", "April", "May", "June",
     "July", "August", "September", "October", "November", "December"
];

$(document).ready(function() {
    $("#datInput").val(formatDate(currentDate))

    $( "#hiddenDatePicker").datepicker({
      showOn: "button",
      buttonText: "day",
      onSelect: function(dateText, inst) {
         var formattedDate = formatDate(new Date(dateText));
         $("#datInput").val(formattedDate);
      }
    });

 });

function formatDate(dt) {
   var day = dt.getDate();
   var month = monthNames[dt.getMonth()];
   var year = dt.getFullYear();

   return day + '-' + month + '-' + year;

}

#hiddenDatePicker{
    display: none;
}

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<input type="input" id="hiddenDatePicker" class="datepicker" />
<input type="text" id="datInput"/>


问:
Randomizer picks a number from the vector and delete it
So, program picks this number from the vector, it's actually a sequence {1...n} and I want  to print out and delete random number from it. However, everytime program prints out {n...1} sequence.
Example: Vector(1,2,3,4,5) => program picks random number 4 => Vector(1,2,3,5) => random number 1 => Vector(2,3,5) and until Vector(). So, program will print (4,1,...).
In case of this program, it always prints out (5,4,3,2,1) for Vector(1,2,3,4,5).

```<code>int main()
{
    srand(time(NULL));
    rand();
    int toReturn;
    std::cout << "Enter the number of tickets: ";
    std::cin >> toReturn;
    std::cout << std::endl;
    std::vector<int> nums;

    for (int i = 1; i <= toReturn; ++i)
    {
        nums.push_back(i);
    }

    int choice=0;
    bool checked=0;
    while (nums.size() > 0)
    {
        bool inVector=0;
        choice = rand() % toReturn + 1;

        while(inVector == 0)
        {
            choice = rand() % toReturn + 1;

            for (int i = 0; i < nums.size(); ++i)
            {
                if (choice == nums[i])
                {
                    inVector = 1;
                }
                else
                {
                     inVector = 0;
                }
            }
        }
        std::cout << "Why not check the ticket " << choice << std::endl;
        std::cout << "Did u do it right?" << std::endl;
        std::cin >> checked;
        if (checked)
        {
            nums.erase(std::remove(nums.begin(), nums.end(), choice), nums.end());
        }

        else
        {
             continue;
        }
    }
    if (nums.size() == 0)
    {
        std::cout << "You checked all tickets!!!";
    }
    return 0;
}

</code>```

I would be glad if you leave any suggestion to code refactoring

Thanks everybody for help, completely rewrite my program with std::random_shuffle this way:

```<code>#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
#include <random>
int main()
{

    int toReturn;
    std::cout << "Enter the number of tickets: ";
    std::cin >> toReturn;
    std::cout << std::endl;
    std::vector<int> nums;

    for (int i = 1; i <= toReturn; ++i)
    {
        nums.push_back(i);
    }
    std::random_device rd;
    std::mt19937 g(rd());
    int choice = 0;
    std::shuffle(nums.begin(), nums.end(), g);

    while (nums.size() > 0)
    {
        bool checked = 0;
        choice = 0;
        std::cout << "Why not to check " << nums[choice];
        std::cout << std::endl << "Did you do it right?";
        std::cin >> checked;
        if (checked == 1)
        {
            nums.erase(std::remove(nums.begin(), nums.end(), nums[choice]), nums.end());
        }
        choice++;
    }

    std::cout << "You checked all tickets!!!";
    return 0;
}
</code>```

答:
The problem is in your for loop. Even if it finds that a number eg. 1 is present in [1 2 3 4 5] and sets

```<code>inVector = 1
</code>```

it will carry on and check next numbers in the nums and set eventually

```<code>inVector = 0
</code>```

unless it's the last number.

You have to terminate the loop just when the condition is met eg.

```<code>if (choice == nums[i])
{
    inVector = 1;
    break;
}
</code>```

Body:
So, program picks this number from the vector, it's actually a sequence {1...n} and I want  to print out and delete random number from it. However, everytime program prints out {n...1} sequence.
Example: Vector(1,2,3,4,5) => program picks random number 4 => Vector(1,2,3,5) => random number 1 => Vector(2,3,5) and until Vector(). So, program will print (4,1,...).
In case of this program, it always prints out (5,4,3,2,1) for Vector(1,2,3,4,5).

int main()
{
    srand(time(NULL));
    rand();
    int toReturn;
    std::cout << "Enter the number of tickets: ";
    std::cin >> toReturn;
    std::cout << std::endl;
    std::vector<int> nums;

    for (int i = 1; i <= toReturn; ++i)
    {
        nums.push_back(i);
    }

    int choice=0;
    bool checked=0;
    while (nums.size() > 0)
    {
        bool inVector=0;
        choice = rand() % toReturn + 1;

        while(inVector == 0)
        {
            choice = rand() % toReturn + 1;

            for (int i = 0; i < nums.size(); ++i)
            {
                if (choice == nums[i])
                {
                    inVector = 1;
                }
                else
                {
                     inVector = 0;
                }
            }
        }
        std::cout << "Why not check the ticket " << choice << std::endl;
        std::cout << "Did u do it right?" << std::endl;
        std::cin >> checked;
        if (checked)
        {
            nums.erase(std::remove(nums.begin(), nums.end(), choice), nums.end());
        }

        else
        {
             continue;
        }
    }
    if (nums.size() == 0)
    {
        std::cout << "You checked all tickets!!!";
    }
    return 0;
}

I would be glad if you leave any suggestion to code refactoring

Thanks everybody for help, completely rewrite my program with std::random_shuffle this way:

#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
#include <random>
int main()
{

    int toReturn;
    std::cout << "Enter the number of tickets: ";
    std::cin >> toReturn;
    std::cout << std::endl;
    std::vector<int> nums;

    for (int i = 1; i <= toReturn; ++i)
    {
        nums.push_back(i);
    }
    std::random_device rd;
    std::mt19937 g(rd());
    int choice = 0;
    std::shuffle(nums.begin(), nums.end(), g);

    while (nums.size() > 0)
    {
        bool checked = 0;
        choice = 0;
        std::cout << "Why not to check " << nums[choice];
        std::cout << std::endl << "Did you do it right?";
        std::cin >> checked;
        if (checked == 1)
        {
            nums.erase(std::remove(nums.begin(), nums.end(), nums[choice]), nums.end());
        }
        choice++;
    }

    std::cout << "You checked all tickets!!!";
    return 0;
}

Body:
The problem is in your for loop. Even if it finds that a number eg. 1 is present in [1 2 3 4 5] and sets

inVector = 1

it will carry on and check next numbers in the nums and set eventually

inVector = 0

unless it's the last number.

You have to terminate the loop just when the condition is met eg.

if (choice == nums[i])
{
    inVector = 1;
    break;
}


问:
Why am I getting a compilation error in a C++ factorial function?
I am trying to write a simple factorial function in C++ by using the ternary operator. It gives a compilation error.

```<code>int factorial(int n) {
    (n == 0) ? return 1 : return n * factorial(n-1);
}
</code>```

It says Expected ':' to match this '?'
I am new to C++.

答:
Possible fixes:

```<code>if (n <= 1) return 1; else return n * f(n - 1);
</code>```

or

```<code>return n <= 1 ? 1 : n * f(n - 1);
</code>```

Note that it is a common exercise to implement the factorial as a recursive function. Anyway, due to the fast growth of the function, an int can only accommodate up to 12!, and storing the precomputed values is probably a better idea.

Body:
I am trying to write a simple factorial function in C++ by using the ternary operator. It gives a compilation error.

int factorial(int n) {
    (n == 0) ? return 1 : return n * factorial(n-1);
}

It says Expected ':' to match this '?'
I am new to C++.

Body:
Possible fixes:

if (n <= 1) return 1; else return n * f(n - 1);

or

return n <= 1 ? 1 : n * f(n - 1);

Note that it is a common exercise to implement the factorial as a recursive function. Anyway, due to the fast growth of the function, an int can only accommodate up to 12!, and storing the precomputed values is probably a better idea.


问:
How to extend a variable's map in SCSS?
I am using a package called Buefy which is a Vue.js wrapper for the Bulma CSS framework library. Buefy puts an attribute/property on its template components called type (e.g., type="is-warning"). As per the Buefy documentation, the term "is-warning" is pre-defined according to the $colors variable set within SCSS:

So I followed these instructions from Buefy to be able to customize the the $colors map, but what I would like to do, however, is keep the initial SCSS defined in those instructions within a single base.scss file, and then extend with my own customized SCSS file.

I have included the base.scss file in my Vue project with the following snippet in the vue.config.js file:

```<code>module.exports = {
  css: {
    loaderOptions: {
      sass: {
        prependData: `
          @import "@/assets/scss/base.scss";
        `
      }
    }
  }
}
</code>```

So my question is, how can I extend the $colors map in the base.scss with my own names and values?

This is a snippet from base.scss, where the $colors map is defined:

```<code>```css
$colors: (
  "white": ($white, $black),
  "black": ($black, $white),
  "light": ($light, $light-invert),
  "dark": ($dark, $dark-invert),
  "primary": ($primary, $primary-invert),
  "info": ($info, $info-invert),
  "success": ($success, $success-invert),
  "warning": ($warning, $warning-invert),
  "danger": ($danger, $danger-invert),
  "twitter": ($twitter, $twitter-invert)
);
```
</code>```

So, again, my question is how can I extend the $colors map in a different file outside of base.scss (perhaps in App.vue) to leave the original untouched? I didn't see any solution shown in the scss docs.

答:
Your custom color values would go in a variable (later merged into $colors) called $custom-colors, and it's actually described in the docs on "derived variables".

And to customize it:

```<code>// Import Bulma's core
@import "~bulma/sass/utilities/_all";

// Set your colors
$custom-colors: (
  "facebook": ($blue, $white),
  "linkedin": ($dark-blue, $white)
  // etc.
);

// Setup $colors to use as bulma classes (e.g. 'is-twitter')
$colors: (
  "white": ($white, $black),
  "black": ($black, $white),
  "light": ($light, $light-invert),
  "dark": ($dark, $dark-invert),
  "primary": ($primary, $primary-invert),
  "info": ($info, $info-invert),
  "success": ($success, $success-invert),
  "warning": ($warning, $warning-invert),
  "danger": ($danger, $danger-invert),
  "twitter": ($twitter, $twitter-invert)
);

// Import Bulma and Buefy styles
@import "~bulma";
@import "~buefy/src/scss/buefy";
</code>```

It's internally using a custom function called mergeColorMaps.

Title: How to extend a variable's map in SCSS?

Body:
I am using a package called Buefy which is a Vue.js wrapper for the Bulma CSS framework library. Buefy puts an attribute/property on its template components called type (e.g., type="is-warning"). As per the Buefy documentation, the term "is-warning" is pre-defined according to the $colors variable set within SCSS:

So I followed these instructions from Buefy to be able to customize the the $colors map, but what I would like to do, however, is keep the initial SCSS defined in those instructions within a single base.scss file, and then extend with my own customized SCSS file.

I have included the base.scss file in my Vue project with the following snippet in the vue.config.js file:

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        prependData: `
          @import "@/assets/scss/base.scss";
        `
      }
    }
  }
}

So my question is, how can I extend the $colors map in the base.scss with my own names and values?

This is a snippet from base.scss, where the $colors map is defined:

```css
$colors: (
  "white": ($white, $black),
  "black": ($black, $white),
  "light": ($light, $light-invert),
  "dark": ($dark, $dark-invert),
  "primary": ($primary, $primary-invert),
  "info": ($info, $info-invert),
  "success": ($success, $success-invert),
  "warning": ($warning, $warning-invert),
  "danger": ($danger, $danger-invert),
  "twitter": ($twitter, $twitter-invert)
);
```

So, again, my question is how can I extend the $colors map in a different file outside of base.scss (perhaps in App.vue) to leave the original untouched? I didn't see any solution shown in the scss docs.

Body:
Your custom color values would go in a variable (later merged into $colors) called $custom-colors, and it's actually described in the docs on "derived variables".

And to customize it:

// Import Bulma's core
@import "~bulma/sass/utilities/_all";

// Set your colors
$custom-colors: (
  "facebook": ($blue, $white),
  "linkedin": ($dark-blue, $white)
  // etc.
);

// Setup $colors to use as bulma classes (e.g. 'is-twitter')
$colors: (
  "white": ($white, $black),
  "black": ($black, $white),
  "light": ($light, $light-invert),
  "dark": ($dark, $dark-invert),
  "primary": ($primary, $primary-invert),
  "info": ($info, $info-invert),
  "success": ($success, $success-invert),
  "warning": ($warning, $warning-invert),
  "danger": ($danger, $danger-invert),
  "twitter": ($twitter, $twitter-invert)
);

// Import Bulma and Buefy styles
@import "~bulma";
@import "~buefy/src/scss/buefy";

It's internally using a custom function called mergeColorMaps.


问:
What's the right navigation structure for iOS Swift app with onboarding screens?
I'm creating an app that works as follows

Launch Screen

a. if "Getting Started" screens have been viewed and accepted then open main app

b. if not viewed/accepted then show "Getting started", then show main app once accepted

The "Getting Started" screens are quite self-contained so I've created a Storyboard for them, whereas the main app will be programatically created.

Where should the logic for (2) live? I was thinking about creating some sort of UINavigationController that would sit above both sets of screens and could decided what to show. Alternatively, I was going to just launch the main app VC and let the logic to show the "Getting Started" as a modal live there.

Any suggestions on best practise please?

答:
use code launch in AppDelegate.h/SceneDelegate.h
FYI,I believe you can still mix storyboard ViewController and code ViewController.However I suggest stick to only one style(in this case, code ViewController programmatically)

then use UserDefault to store whether user click "get started"

```<code>        // Set Root VC
    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.windowScene = windowScene

    let navigator = Container.shared.resolve(INavigator.self)!
    let localStorageService = Container.shared.resolve(ILocalStorageService.self)!
    if localStorageService.isKeyExist(key: Configs.KEY_USER) {
        navigator.switchRoot(keyWindow: window!, scene: .main(viewModel: MainTabBarViewModel()))
    } else {
        navigator.switchRoot(keyWindow: window!, scene: .intro(viewModel: IntroViewModel()))
    }
</code>```

Body:
use code launch in AppDelegate.h/SceneDelegate.h
FYI,I believe you can still mix storyboard ViewController and code ViewController.However I suggest stick to only one style(in this case, code ViewController programmatically)

then use UserDefault to store whether user click "get started"

        // Set Root VC
    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.windowScene = windowScene

    let navigator = Container.shared.resolve(INavigator.self)!
    let localStorageService = Container.shared.resolve(ILocalStorageService.self)!
    if localStorageService.isKeyExist(key: Configs.KEY_USER) {
        navigator.switchRoot(keyWindow: window!, scene: .main(viewModel: MainTabBarViewModel()))
    } else {
        navigator.switchRoot(keyWindow: window!, scene: .intro(viewModel: IntroViewModel()))
    }


问:
Playing music with a bot from Youtube without downloading the file
How would i go about playing music using a discord bot from Youtube without downloading the song as a file?

I've already had a look at the included music bot in the discord.py documentation but that one downloads a file to the directory. Is there any way to avoid this? Code from the documentation example:

ytdl_format_options = {
    'format': 'bestaudio/best',
    'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
    'restrictfilenames': True,
    'noplaylist': True,
    'nocheckcertificate': True,
    'ignoreerrors': False,
    'logtostderr': False,
    'quiet': True,
    'no_warnings': True,
    'default_search': 'auto',
    'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}

ffmpeg_options = {
    'options': '-vn'
}

ytdl = youtube_dl.YoutubeDL(ytdl_format_options)

class YTDLSource(discord.PCMVolumeTransformer):
    def __init__(self, source, *, data, volume=0.5):
        super().__init__(source, volume)

        self.data = data

        self.title = data.get('title')
        self.url = data.get('url')

    @classmethod
    async def from_url(cls, url, *, loop=None, stream=False):
        loop = loop or asyncio.get_event_loop()
        data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download= not stream))

        if 'entries' in data:
            # take first item from a playlist
            data = data['entries'][0]

        filename = data['url'] if stream else ytdl.prepare_filename(data)
        return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)

@client.command()
async def play(ctx, url):
    voice = await ctx.author.voice.channel.connect()
    player = await YTDLSource.from_url(url, loop=client.loop)
    ctx.voice_client.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
```

答:
To play music without downloading it, simply use this code into your play function :

ydl_opts = {'format': 'bestaudio'}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    info = ydl.extract_info(video_link, download=False)
    URL = info['formats'][0]['url']
voice = get(self.bot.voice_clients, guild=ctx.guild)
voice.play(discord.FFmpegPCMAudio(URL))
```
<p>Here is what each line is used for :<br></p>
<ul>
<li><code>ydl_opts = {'format': 'bestaudio'}</code> : get the best possible audio<br></li>
<li><code>with youtube_dl.YoutubeDL(ydl_opts) as ydl:</code> : initialize youtube-dl<br></li>
<li><code>info = ydl.extract_info(video_link, download=False)</code> : get a dictionary, named <code>info</code>, containing all the video information (title, duration, uploader, description, ...)<br></li>
<li><code>URL = info['formats'][0]['url']</code> : get the URL which leads to the audio file of the video<br></li>
<li><code>voice = get(self.bot.voice_clients, guild=ctx.guild)</code> : initialize a new audio player<br></li>
<li><code>voice.play(discord.FFmpegPCMAudio(URL))</code> : play the right music</li>
</ul>
<p><br>However, Playing audio from an URL without downloading it causes a known issue explained <strong>here</strong><br>
To fix it, just add a variable, for instance, <code>FFMPEG_OPTIONS</code> which will contain options for FFMPEG:</p>
<pre class="lang-py prettyprint-override"><code>FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
</code>```

Once you've created the variable, you just have to add one argument to the FFmpegPCMAudio method:

voice.play(discord.FFmpegPCMAudio(URL, **FFMPEG_OPTIONS))
```

Body:
To play music without downloading it, simply use this code into your play function :

ydl_opts = {'format': 'bestaudio'}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    info = ydl.extract_info(video_link, download=False)
    URL = info['formats'][0]['url']
voice = get(self.bot.voice_clients, guild=ctx.guild)
voice.play(discord.FFmpegPCMAudio(URL))

Here is what each line is used for :

ydl_opts = {'format': 'bestaudio'} : get the best possible audio

with youtube_dl.YoutubeDL(ydl_opts) as ydl: : initialize youtube-dl

info = ydl.extract_info(video_link, download=False) : get a dictionary, named info, containing all the video information (title, duration, uploader, description, ...)

URL = info['formats'][0]['url'] : get the URL which leads to the audio file of the video

voice = get(self.bot.voice_clients, guild=ctx.guild) : initialize a new audio player

voice.play(discord.FFmpegPCMAudio(URL)) : play the right music

However, Playing audio from an URL without downloading it causes a known issue explained here

To fix it, just add a variable, for instance, FFMPEG_OPTIONS which will contain options for FFMPEG:

FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}

Once you've created the variable, you just have to add one argument to the FFmpegPCMAudio method:

voice.play(discord.FFmpegPCMAudio(URL, **FFMPEG_OPTIONS))


问:
unique "key" / table should have a unique `key` prop, or set `rowKey
Question: How to pass / create and pass unique key to Radio Button , also i have a Table component that takes data(arra) and it also says that [antd: Table] Each record in dataSource of table should have a unique key prop, or set rowKey . Thank you in advance.

```<code>    const userRoles = [
    {
        key: "ROLE_ADMIN",
        name: "Admin"
    },
    {
        key: "ROLE_USER",
        name: "User",
    }
];

class RoleUpdate extends PureComponent {

    constructor(props) {
        super(props);
        this.state = {
            userRole: props.role,
        }
    }

    handleChange = (event) => {
        this.setState({
            userRole: {
                role: event.target.value
            }
        });
        this.props.onRoleChange(event.target.value);
    };

    render() {
        return (
            <Radio.Group value={this.state.userRole.role} onChange={this.handleChange}>
                {userRoles.map(role => {
                    return <Radio.Button value={role.key}>{role.name}</Radio.Button>
                })}
            </Radio.Group>

        )
    };

}

export default RoleUpdate;

<Table size={"middle"}
      columns={columns}
      dataSource={this.state.results}
                   />
</code>```

答:
You need to add key attribute to each element of .map().

The way usually I do is using (role, index) option what you can add as:

```<code><Radio.Group value={this.state.userRole.role} onChange={this.handleChange}>
  {userRoles.map((role, index) => {
     return <Radio.Button key={index} value={role.key}>{role.name}</Radio.Button>
  })}
</Radio.Group>
</code>```

Body:
Question: How to pass / create and pass unique key to Radio Button , also i have a Table component that takes data(arra) and it also says that [antd: Table] Each record in dataSource of table should have a unique key prop, or set rowKey . Thank you in advance.

    const userRoles = [
    {
        key: "ROLE_ADMIN",
        name: "Admin"
    },
    {
        key: "ROLE_USER",
        name: "User",
    }
];

class RoleUpdate extends PureComponent {

    constructor(props) {
        super(props);
        this.state = {
            userRole: props.role,
        }
    }

    handleChange = (event) => {
        this.setState({
            userRole: {
                role: event.target.value
            }
        });
        this.props.onRoleChange(event.target.value);
    };

    render() {
        return (
            <Radio.Group value={this.state.userRole.role} onChange={this.handleChange}>
                {userRoles.map(role => {
                    return <Radio.Button value={role.key}>{role.name}</Radio.Button>
                })}
            </Radio.Group>

        )
    };

}

export default RoleUpdate;

Body:
You need to add key attribute to each element of .map().

The way usually I do is using (role, index) option what you can add as:

<Radio.Group value={this.state.userRole.role} onChange={this.handleChange}>
  {userRoles.map((role, index) => {
     return <Radio.Button key={index} value={role.key}>{role.name}</Radio.Button>
  })}
</Radio.Group>


问:
Import the second tkinter page into the first tkinter page - python3

I have problem/question about tkinter...

I have two tkinter apps - first.py and second.py- I want to import second.py into first.py and run it in first.py window (not in tk and tk#2 but still in tk. (I hope you understand me.)
 So is there a possible way to do it?

Of course, it's much easier to create just one script ... but I'm creating a more complex application, and splitting a script into multiple scripts is essential for me.

Here is a simple script for first.py:

```<code>from tkinter import *
import tkinter as tk
from second import scnd

def frst():

    root = tk.Tk()

    canvas = tk.Canvas(root, bg = "grey", width = 400, height = 400, relief = "groove")
    canvas.pack(expand = YES, fill="both")

    label = tk.Label(root, text = "First page!", bg = "grey",fg = "white")
    canvas.create_window(100, 100, window = label)

    button = tk.Button(root, text = "Open second page", bg = "blue", fg = "white", command = scnd)
    canvas.create_window(200, 200, window = button)

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

And here is a simple script for second.py:

```<code>from tkinter import *
import tkinter as tk

def scnd():
    root = tk.Tk()
    canvas = tk.Canvas(root, bg = "grey", width = 400, height = 400, relief = "groove")
    canvas.pack(expand = YES, fill="both")

    label2 = tk.Label(root, text = "Second page!", bg = "grey",fg = "white")
    canvas.create_window(100, 100, window = label2)

    button2 = tk.Button(root, text = "Open first page", bg = "blue", fg = "white", command = None)
    canvas.create_window(200, 200, window = button2)
    root.mainloop()
</code>```

I will be grateful for any help. Thanks in advance.

答:
First of all if you don't want to create new tk windows, don't call Tk() and mainloop in second script. Put all content from first script into frame, and then call function scnd with button, give parameters root and frame. When you run second script you will want to destroy old frame and put everything from new script into new frame, so in the future you will also destroy it. Hope it helps.

First script:

```<code>def frst():
    root = tk.Tk()
    frame = Frame(root)
    frame.pack()
    canvas = tk.Canvas(frame, bg="grey", width=400, height=400, relief="groove")
    canvas.pack(expand=YES, fill="both")

    label = tk.Label(frame, text="First page!", bg="grey", fg="white")
    canvas.create_window(100, 100, window=label)

    button = tk.Button(frame, text="Open second page", bg="blue", fg="white", command=lambda: scnd(root, frame))
    canvas.create_window(200, 200, window=button)

    root.mainloop()

frst()
</code>```

Second script:

```<code>def scnd(root, frame):
    def clicked():
        print('click!')
    frame.destroy()
    canvas = tk.Canvas(root, bg="grey", width=400, height=400, relief="groove")
    canvas.pack(expand=YES, fill="both")

    label2 = tk.Label(root, text="Second page!", bg="grey", fg="white")
    canvas.create_window(100, 100, window=label2)

    button2 = tk.Button(root, text="Open first page", bg="blue", fg="white", command=clicked)
    canvas.create_window(200, 200, window=button2)
</code>```

Body:
I have problem/question about tkinter...

I have two tkinter apps - first.py and second.py- I want to import second.py into first.py and run it in first.py window (not in tk and tk#2 but still in tk. (I hope you understand me.)
 So is there a possible way to do it?

Of course, it's much easier to create just one script ... but I'm creating a more complex application, and splitting a script into multiple scripts is essential for me.

Here is a simple script for first.py:

from tkinter import *
import tkinter as tk
from second import scnd

def frst():

    root = tk.Tk()

    canvas = tk.Canvas(root, bg = "grey", width = 400, height = 400, relief = "groove")
    canvas.pack(expand = YES, fill="both")

    label = tk.Label(root, text = "First page!", bg = "grey",fg = "white")
    canvas.create_window(100, 100, window = label)

    button = tk.Button(root, text = "Open second page", bg = "blue", fg = "white", command = scnd)
    canvas.create_window(200, 200, window = button)

    root.mainloop()
frst()

And here is a simple script for second.py:

from tkinter import *
import tkinter as tk

def scnd():
    root = tk.Tk()
    canvas = tk.Canvas(root, bg = "grey", width = 400, height = 400, relief = "groove")
    canvas.pack(expand = YES, fill="both")

    label2 = tk.Label(root, text = "Second page!", bg = "grey",fg = "white")
    canvas.create_window(100, 100, window = label2)

    button2 = tk.Button(root, text = "Open first page", bg = "blue", fg = "white", command = None)
    canvas.create_window(200, 200, window = button2)
    root.mainloop()

I will be grateful for any help. Thanks in advance.

Body:
First of all if you don't want to create new tk windows, don't call Tk() and mainloop in second script. Put all content from first script into frame, and then call function scnd with button, give parameters root and frame. When you run second script you will want to destroy old frame and put everything from new script into new frame, so in the future you will also destroy it. Hope it helps.

First script:

def frst():
    root = tk.Tk()
    frame = Frame(root)
    frame.pack()
    canvas = tk.Canvas(frame, bg="grey", width=400, height=400, relief="groove")
    canvas.pack(expand=YES, fill="both")

    label = tk.Label(frame, text="First page!", bg="grey", fg="white")
    canvas.create_window(100, 100, window=label)

    button = tk.Button(frame, text="Open second page", bg="blue", fg="white", command=lambda: scnd(root, frame))
    canvas.create_window(200, 200, window=button)

    root.mainloop()

frst()

Second script:

def scnd(root, frame):
    def clicked():
        print('click!')
    frame.destroy()
    canvas = tk.Canvas(root, bg="grey", width=400, height=400, relief="groove")
    canvas.pack(expand=YES, fill="both")

    label2 = tk.Label(root, text="Second page!", bg="grey", fg="white")
    canvas.create_window(100, 100, window=label2)

    button2 = tk.Button(root, text="Open first page", bg="blue", fg="white", command=clicked)
    canvas.create_window(200, 200, window=button2)


问:
Can't apply styles to VSCode Webview using html file
I am building a VSCode Webview and trying to apply some css.

The only success I have had is with the following method

const webview = this._panel.webview;
const stylePathOnDisk = vscode.Uri.file(path.join(this._extensionPath, '/res/css/styles.css'));
const styleUri = webview.asWebviewUri(stylePathOnDisk);

webview.html = `
  <!doctype html>

      <link rel='stylesheet' type='text/css' href='${styleUri}'>

test

  `
```

<p>But I'd like to have my html in a separate file, used like so</p>

<pre class="lang-js prettyprint-override"><code>const htmlPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, '/res/html/index.html'));
webview.html = fs.readFileSync(htmlPathOnDisk.path).toString();
</code>```

However, I cannot use ${styleUri} within that html file. Nor can I use <link ref='stylesheet' type='text/css' href='{{styleUri}}>, nor EVEN can I use

答:
As told by @Matt Bierner, here is the solution.

const htmlPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, '/res/html/index.html'));
var html = fs.readFileSync(htmlPathOnDisk.path).toString();

const stylePathOnDisk = vscode.Uri.file(path.join(this._extensionPath, '/res/css/styles.css'));
const styleUri = webview.asWebviewUri(stylePathOnDisk);
html = html.replace('${styleUri}', styleUri.toString());

// continue for any other resources, e.g. scripts

webview.html = html
```

Body:
I am building a VSCode Webview and trying to apply some css.

The only success I have had is with the following method

const webview = this._panel.webview;
const stylePathOnDisk = vscode.Uri.file(path.join(this._extensionPath, '/res/css/styles.css'));
const styleUri = webview.asWebviewUri(stylePathOnDisk);

webview.html = `
  <!doctype html>

      <link rel='stylesheet' type='text/css' href='${styleUri}'>

test

  `

But I'd like to have my html in a separate file, used like so

const htmlPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, '/res/html/index.html'));
webview.html = fs.readFileSync(htmlPathOnDisk.path).toString();

However, I cannot use ${styleUri} within that html file. Nor can I use <link ref='stylesheet' type='text/css' href='{{styleUri}}>, nor EVEN can I use


答:
It is quite unclear exactly what you want to achieve, so this might be a long shot.

There seems to be 2 problems included in this question:

Create a sequence with multiple by elements

group a certain column by the sequence generated in 1.

Create a sequence with multiple by elements

Now the for 1. I'm unaware of any inbuild or package function, even though I don't doubt it already exists. We can however simply create our own seqv function with vectorized by elements.

```<code>seqv <- function(from, to, by){
  diff <- to - from
  if((n <- diff / sum(by)) < 1){
    n <- 1
  }else{
    n <- ceiling(n)
  }
  out <- c(from, from + cumsum(rep(by, n)))
  out[out <= to]
}
</code>```

Usage example:

```<code>mi <- trunc(min(pump_packets$PacketTime))
ma <- max(pump_packets$PacketTime)
ra <- 1:60
ra[60] <- ra[60] + 5
cuts <- seqv(mi, ma + 5, ra)
cuts[c(1:6, (length(cuts) - 5):length(cuts))]
[1]     0     1     3     6    10    15 10400 10450 10501 10553 10606 10660
length(cuts)
[1] 355
</code>```

now this output does not include the max value of 10660.46 and the length is not 300, this does however follow the description in the question, as such I am not sure where the misunderstanding has happened. For now I'll add a bit to the last value to include the max value.

```<code>cuts[length(cuts)] <- cuts[length(cuts)] + 1
</code>```

group a certain column by the sequence generated in 1.

Now the main part was really in 1. so here We can just use the cut function to create our groupings

```<code>pump_packets$group <-
  cut(pump_packets$PacketTime, breaks = cuts, right = FALSE, dig.lab = 12)

pump_packets_summary <- pump_packets %>%
  group_by(group) %>%
  summarise(
    PacketTime = max(PacketTime) - min(PacketTime),
    FrameLen = list(FrameLen),
    IPLen = list(IPLen),
    n = n()
  )
head(pump_packets_summary)
# A tibble: 6 x 5
  group   PacketTime FrameLen   IPLen          n
  <fct>        <dbl> <list>     <list>     <int>
1 [0,1)      0.0496  <int [16]> <int [16]>    16
2 [1,3)      0.0396  <int [52]> <int [52]>    52
3 [3,6)      0.00634 <int [6]>  <int [6]>      6
4 [6,10)     0.00672 <int [6]>  <int [6]>      6
5 [10,15)    0.00529 <int [6]>  <int [6]>      6
6 [15,21)    3.01    <int [12]> <int [12]>    12
tail(pump_packets_summary )
# A tibble: 6 x 5
  group         PacketTime FrameLen   IPLen          n
  <fct>              <dbl> <list>     <list>     <int>
1 [10351,10400)       30.0 <int [8]>  <int [8]>      8
2 [10400,10450)       41.0 <int [20]> <int [20]>    20
3 [10450,10501)       42.0 <int [24]> <int [24]>    24
4 [10501,10553)       43.0 <int [20]> <int [20]>    20
5 [10553,10606)       44.0 <int [20]> <int [20]>    20
6 [10606,10661)       50.0 <int [16]> <int [16]>    16
</code>```

Which might be the desired result.

Title: Concatenating rows based on range (variable) column condition

Body:
For subsequent discussion, I will refer to the following dataframe: https://gist.github.com/ryankshah/ab8c2b7c5e178264ccefbae9d72760ee

A shorter capture of this dput() can be found here:

structure(list(PacketTime = c(0.925717, 0.925967, 0.9262, 0.926368,
0.966861, 0.966998, 0.9672, 0.967252, 0.971273, 0.97149, 0.971816,
0.972113, 0.974991, 0.975093, 0.97521, 0.975273, 2.008958, 2.009109,
2.009449, 2.009612, 2.01108, 2.011192, 2.011354, 2.011388, 2.015283,
2.01536, 2.015468, 2.015525, 2.016604, 2.016834, 2.017415, 2.017646,
2.019347, 2.019545, 2.019759, 2.019978, 2.020895, 2.021105, 2.023508,
2.023639, 2.023769, 2.023843, 2.027671, 2.027725, 2.02788, 2.027916,
2.028638, 2.02883, 2.03151, 2.031595, 2.031702, 2.031747, 2.034291,
2.034404, 2.039741, 2.039864, 2.039985, 2.040038, 2.042009, 2.042255,
2.043858, 2.043994, 2.044106, 2.044159, 2.04811, 2.048292, 2.048462,
2.048528, 3.050371, 3.050611, 3.055923, 3.0562, 3.056505, 3.056714,
8.059537, 8.059921, 8.065446, 8.065725, 8.066084, 8.066262, 10.068591,
10.069067, 10.07296, 10.073275, 10.073676, 10.073876, 15.074687,
15.075031, 15.078191, 15.078466, 15.078801, 15.079074, 18.081208,
18.081529, 18.085248, 18.085535, 18.085852, 18.086052, 23.087208,
23.087593, 23.090558, 23.090785, 23.091051, 23.091178, 27.09315,
27.093459, 27.096607, 27.096871, 27.097215, 27.097397, 32.099606,
32.100004, 32.102153, 32.102447, 32.102661, 32.102778, 37.105682,
37.106026, 37.107854, 37.108097, 37.108414, 37.10868, 37.111986,
37.11225, 37.112499, 37.112722, 42.114744, 42.115078, 42.117969,
42.118193, 42.118482, 42.11864, 48.121045, 48.121391, 48.12679,
48.127032, 48.127318, 48.127445, 53.130552, 53.130845, 53.136697,
53.13683, 53.136959, 53.137048, 60.139012, 60.139349, 60.141249,
60.141512, 60.141795, 60.142002, 60.145269, 60.145407, 60.145723,
60.145829, 65.148214, 65.148629, 65.150792, 65.15101, 65.151288,
65.151488, 73.155091, 73.155481, 73.158976, 73.159112, 73.159464,
73.159645, 78.163605, 78.164009, 78.168708, 78.169007, 78.169318,
78.169514, 87.170767, 87.171061, 87.176407, 87.176686, 87.177029,
87.177226, 92.180694, 92.181003, 92.186155, 92.186468, 92.18692,
92.187193, 102.187674, 102.18776, 102.190376, 102.190668, 102.193207,
102.193441, 102.193629, 102.193805, 107.195208, 107.195504, 107.199008,
107.199342, 107.199769, 107.200036, 117.199583, 117.199655, 118.203094,
118.203531, 118.205494, 118.205809, 118.206103, 118.206409, 118.209557,
118.209755, 123.212961, 123.213286, 123.215108, 123.215345, 123.215595,
123.21583, 123.219189, 123.219368, 123.219602, 123.219702, 133.219802,
133.219915, 135.224383, 135.224711, 135.22949, 135.229697, 135.230052,
135.230166, 140.231358, 140.231709, 140.235145, 140.235354, 140.235666,
140.23583, 150.23674, 150.236893, 153.237651, 153.237955, 153.240681,
153.241032, 153.241138, 153.241311, 158.244289, 158.24462, 158.246344,
158.246533, 158.246818, 158.247013, 158.25062, 158.250965, 158.251396,
158.251727, 168.253167, 168.25327, 172.253859, 172.254289, 172.259665,
172.259902, 172.26007, 172.260166, 177.262164, 177.262425, 177.265205,
177.265375, 177.265631, 177.265884, 187.266422, 187.266505, 192.269399,
192.269792, 192.27395, 192.274232, 192.274519, 192.274847, 197.279566,
197.280221, 197.283799, 197.284061, 197.28468, 197.28491, 207.285048,
207.285102, 213.286424, 213.286742, 213.291805, 213.292022, 213.292293,
213.292509, 218.295248, 218.295628, 218.2975, 218.297738, 218.298062,
218.298262, 218.301568, 218.301735, 218.301938, 218.302066, 228.301508,
228.301602, 235.305332, 235.305773, 235.309398, 235.309731, 235.310093,
235.310401, 240.312849, 240.313132, 240.315194, 240.315485, 240.315803,
240.316064, 240.31901, 240.319262, 240.319539, 240.319755, 250.320398,
250.320455, 258.321427, 258.321849, 258.326082, 258.32634, 258.32664,
258.326817, 263.32921, 263.329591, 263.331642, 263.331896, 263.332199,
263.332393, 263.335719, 263.335938, 263.336188, 263.336369, 273.337068,
273.337128, 282.338967, 282.339414, 282.34244, 282.342766, 282.34309,
282.343362, 287.345265, 287.345607, 287.348166, 287.348339, 287.348594,
287.348817, 297.349787, 297.349865, 307.349457, 307.34957, 307.351337,
307.3518, 307.354625, 307.355012, 307.35552, 307.35587, 312.35734,
312.357705, 312.359736, 312.36004, 312.360364, 312.360594, 312.364214,
312.364463, 312.364735, 312.36499, 322.366091, 322.366227, 332.366338,
332.366534, 333.367324, 333.36794, 333.369832, 333.370364, 333.371064,
333.371449, 333.373735, 333.374203, 333.374898, 333.375308, 338.3775,
338.377843, 338.38372, 338.384043, 338.384348, 338.384588, 348.384979,
348.38518, 358.385032, 358.386079, 360.385749, 360.386182, 360.388575,
360.388942, 360.389326, 360.389634, 365.393852, 365.394483, 365.398596,
365.399103, 365.399843, 365.400314, 375.401212, 375.401412, 385.402246,
385.402379, 388.403104, 388.403558, 388.407001, 388.407347, 388.407757,
388.407949, 393.410628, 393.411324, 393.416863, 393.417356, 393.418049,
393.418364, 403.419292, 403.419493, 413.420496, 413.420703, 417.422362,
417.423105, 417.424998, 417.425524, 417.426235, 417.426626, 417.4289,
417.429372, 417.430061, 417.430587, 422.433468, 422.434207, 422.438868,
422.439384, 422.440069, 422.440524, 432.441634, 432.44168, 442.441719,
442.44192, 447.442671, 447.442965, 447.446516, 447.446798, 447.44712,
447.447346, 452.450152, 452.450889, 452.456021, 452.456473, 452.457157,
452.45767, 462.458991, 462.459146, 472.458653, 472.45875, 478.460478,
478.461126, 478.462897, 478.463172, 478.463473, 478.46373, 478.467188,
478.467475, 483.468957, 483.46949, 483.473127, 483.473498, 483.473933,
483.474279, 493.475598, 493.475683, 503.475776, 503.475979, 510.477035,
510.477734, 510.479687, 510.480173, 510.480865, 510.481371, 510.483715,
510.484214, 510.484828, 510.485251, 515.48768, 515.488313, 515.493402,
515.493923, 515.494545, 515.495049, 525.494754, 525.494827, 535.495316,
535.495521, 543.497961, 543.498653, 543.503644, 543.504176),
    FrameLen = c(44L, 276L, 44L, 276L, 44L, 276L, 44L, 276L,
    44L, 276L, 44L, 276L, 44L, 276L, 44L, 276L, 285L, 44L, 285L,
    44L, 44L, 276L, 44L, 276L, 44L, 276L, 44L, 276L, 285L, 44L,
    285L, 44L, 44L, 276L, 44L, 276L, 285L, 44L, 44L, 276L, 44L,
    276L, 44L, 276L, 44L, 276L, 288L, 44L, 44L, 276L, 44L, 276L,
    285L, 44L, 44L, 276L, 44L, 276L, 288L, 44L, 44L, 276L, 44L,
    276L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L,
    289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L,
    276L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L,
    44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L,
    276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L,
    44L, 276L, 44L, 276L, 44L, 276L, 44L, 276L, 289L, 44L, 44L,
    276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L,
    44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 44L,
    276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L,
    44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 289L,
    44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L,
    45L, 56L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L,
    276L, 44L, 276L, 45L, 56L, 289L, 44L, 44L, 276L, 44L, 276L,
    44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 44L, 276L, 44L,
    276L, 45L, 56L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L,
    44L, 276L, 44L, 276L, 45L, 56L, 289L, 44L, 44L, 276L, 44L,
    276L, 289L, 44L, 44L, 276L, 44L, 276L, 44L, 276L, 44L, 276L,
    45L, 56L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L,
    276L, 44L, 276L, 45L, 56L, 289L, 44L, 44L, 276L, 44L, 276L,
    289L, 44L, 44L, 276L, 44L, 276L, 45L, 56L, 289L, 44L, 44L,
    276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 44L, 276L,
    44L, 276L, 45L, 56L, 289L, 44L, 44L, 276L, 44L, 276L, 289L,
    44L, 44L, 276L, 44L, 276L, 44L, 276L, 44L, 276L, 45L, 56L,
    289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L,
    276L, 44L, 276L, 44L, 276L, 45L, 56L, 289L, 44L, 44L, 276L,
    44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 45L, 56L, 45L,
    56L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L,
    44L, 276L, 44L, 276L, 44L, 276L, 45L, 56L, 45L, 56L, 289L,
    44L, 44L, 276L, 44L, 276L, 44L, 276L, 44L, 276L, 289L, 44L,
    44L, 276L, 44L, 276L, 45L, 56L, 45L, 56L, 289L, 44L, 44L,
    276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L, 45L, 56L,
    45L, 56L, 289L, 44L, 44L, 276L, 44L, 276L, 289L, 44L, 44L,
    276L, 44L, 276L, 45L, 56L, 45L, 56L, 289L, 44L, 44L, 276L,
    44L, 276L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L,
    276L, 45L, 56L, 45L, 56L, 289L, 44L, 44L, 276L, 44L, 276L,
    289L, 44L, 44L, 276L, 44L, 276L, 45L, 56L, 45L, 56L, 289L,
    44L, 44L, 276L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L,
    44L, 276L, 45L, 56L, 45L, 56L, 289L, 44L, 44L, 276L, 44L,
    276L, 44L, 276L, 44L, 276L, 289L, 44L, 44L, 276L, 44L, 276L,
    45L, 56L, 45L, 56L, 289L, 44L, 44L, 276L), IPLen = c(40L,
    272L, 40L, 272L, 40L, 272L, 40L, 272L, 40L, 272L, 40L, 272L,
    40L, 272L, 40L, 272L, 281L, 40L, 281L, 40L, 40L, 272L, 40L,
    272L, 40L, 272L, 40L, 272L, 281L, 40L, 281L, 40L, 40L, 272L,
    40L, 272L, 281L, 40L, 40L, 272L, 40L, 272L, 40L, 272L, 40L,
    272L, 284L, 40L, 40L, 272L, 40L, 272L, 281L, 40L, 40L, 272L,
    40L, 272L, 284L, 40L, 40L, 272L, 40L, 272L, 40L, 272L, 40L,
    272L, 285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L,
    40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L,
    272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L,
    40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 285L,
    40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L,
    40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 285L,
    40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L,
    285L, 40L, 40L, 272L, 40L, 272L, 40L, 272L, 40L, 272L, 285L,
    40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L,
    285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L,
    272L, 285L, 40L, 40L, 272L, 40L, 272L, 41L, 52L, 285L, 40L,
    40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 41L,
    52L, 285L, 40L, 40L, 272L, 40L, 272L, 40L, 272L, 285L, 40L,
    40L, 272L, 40L, 272L, 40L, 272L, 40L, 272L, 41L, 52L, 285L,
    40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L,
    41L, 52L, 285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L,
    272L, 40L, 272L, 40L, 272L, 40L, 272L, 41L, 52L, 285L, 40L,
    40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 41L,
    52L, 285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L,
    40L, 272L, 41L, 52L, 285L, 40L, 40L, 272L, 40L, 272L, 285L,
    40L, 40L, 272L, 40L, 272L, 40L, 272L, 40L, 272L, 41L, 52L,
    285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L,
    272L, 40L, 272L, 40L, 272L, 41L, 52L, 285L, 40L, 40L, 272L,
    40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 40L, 272L, 40L,
    272L, 41L, 52L, 285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L,
    40L, 272L, 40L, 272L, 41L, 52L, 41L, 52L, 285L, 40L, 40L,
    272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 40L, 272L,
    40L, 272L, 41L, 52L, 41L, 52L, 285L, 40L, 40L, 272L, 40L,
    272L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L,
    41L, 52L, 41L, 52L, 285L, 40L, 40L, 272L, 40L, 272L, 285L,
    40L, 40L, 272L, 40L, 272L, 41L, 52L, 41L, 52L, 285L, 40L,
    40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 41L,
    52L, 41L, 52L, 285L, 40L, 40L, 272L, 40L, 272L, 40L, 272L,
    40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 41L, 52L, 41L,
    52L, 285L, 40L, 40L, 272L, 40L, 272L, 285L, 40L, 40L, 272L,
    40L, 272L, 41L, 52L, 41L, 52L, 285L, 40L, 40L, 272L, 40L,
    272L, 40L, 272L, 285L, 40L, 40L, 272L, 40L, 272L, 41L, 52L,
    41L, 52L, 285L, 40L, 40L, 272L, 40L, 272L, 40L, 272L, 40L,
    272L, 285L, 40L, 40L, 272L, 40L, 272L, 41L, 52L, 41L, 52L,
    285L, 40L, 40L, 272L), TCPLen = c(0L, 232L, 0L, 232L, 0L,
    232L, 0L, 232L, 0L, 232L, 0L, 232L, 0L, 232L, 0L, 232L, 241L,
    0L, 241L, 0L, 0L, 232L, 0L, 232L, 0L, 232L, 0L, 232L, 241L,
    0L, 241L, 0L, 0L, 232L, 0L, 232L, 241L, 0L, 0L, 232L, 0L,
    232L, 0L, 232L, 0L, 232L, 244L, 0L, 0L, 232L, 0L, 232L, 241L,
    0L, 0L, 232L, 0L, 232L, 244L, 0L, 0L, 232L, 0L, 232L, 0L,
    232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L,
    232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L,
    232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L,
    232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L,
    232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 0L, 232L, 0L,
    232L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L,
    232L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L,
    232L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 245L,
    0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 245L,
    0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 1L,
    0L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L,
    232L, 1L, 0L, 245L, 0L, 0L, 232L, 0L, 232L, 0L, 232L, 245L,
    0L, 0L, 232L, 0L, 232L, 0L, 232L, 0L, 232L, 1L, 0L, 245L,
    0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 1L,
    0L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L,
    232L, 0L, 232L, 0L, 232L, 1L, 0L, 245L, 0L, 0L, 232L, 0L,
    232L, 245L, 0L, 0L, 232L, 0L, 232L, 1L, 0L, 245L, 0L, 0L,
    232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 1L, 0L, 245L,
    0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 0L,
    232L, 0L, 232L, 1L, 0L, 245L, 0L, 0L, 232L, 0L, 232L, 245L,
    0L, 0L, 232L, 0L, 232L, 0L, 232L, 0L, 232L, 1L, 0L, 245L,
    0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 0L,
    232L, 0L, 232L, 1L, 0L, 245L, 0L, 0L, 232L, 0L, 232L, 245L,
    0L, 0L, 232L, 0L, 232L, 1L, 0L, 1L, 0L, 245L, 0L, 0L, 232L,
    0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 0L, 232L, 0L, 232L,
    1L, 0L, 1L, 0L, 245L, 0L, 0L, 232L, 0L, 232L, 0L, 232L, 0L,
    232L, 245L, 0L, 0L, 232L, 0L, 232L, 1L, 0L, 1L, 0L, 245L,
    0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 1L,
    0L, 1L, 0L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L,
    0L, 232L, 1L, 0L, 1L, 0L, 245L, 0L, 0L, 232L, 0L, 232L, 0L,
    232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L, 232L, 1L, 0L, 1L,
    0L, 245L, 0L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L,
    232L, 1L, 0L, 1L, 0L, 245L, 0L, 0L, 232L, 0L, 232L, 0L, 232L,
    245L, 0L, 0L, 232L, 0L, 232L, 1L, 0L, 1L, 0L, 245L, 0L, 0L,
    232L, 0L, 232L, 0L, 232L, 0L, 232L, 245L, 0L, 0L, 232L, 0L,
    232L, 1L, 0L, 1L, 0L, 245L, 0L, 0L, 232L), Movement = c(3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3)), row.names = c(NA, 500L), class = "data.frame")

The aim here is to group all the packets where the PacketTime is similar. This can be done using the following:

brks <- seq(trunc(min(pump_packets$PacketTime)), max(pump_packets$PacketTime) + 5, 5)
pump_packets$Interval <- cut(pump_packets$PacketTime, breaks = brks, labels = brks[-length(brks)], right = FALSE)

However, this is for a fixed interval. In this case, the grouping is for packet times in the range of a 1s to 60s gap, which repeats (i.e. when it reaches the 60s gap, the next grouping will be starting at 1s). As you can see the current solution for a fixed interval does not take the range interval into account. As well as this, some of these crossover (i.e. 1480s also includes part of 1481s). What makes this somewhat simpler is that each of the groups are separated by an n second timing window (via Python time.sleep(n)), where n is in range(1, 61) (1s to 60s).

Furthermore, after each interval between packets - there is a 5s sleep (break). An example of what I mean by the interval in a more visual way can be seen below.

How can this be achieved? (This is a variable version of this post Concatenating data frame rows based on column condition)

EDIT: I will eventually use the grouped data to group by the interval the packets are in, such as follows:

pump_packets <- pump_packets %>%
  group_by(Interval) %>%
  summarise(
    PTime=max(PacketTime)-min(PacketTime),
    FLen=list(FrameLen),
    ILen=list(IPLen),
    Movement=3
  ) %>%
  rename(PacketTime=PTime) %>%
  rename(FrameLen=FLen) %>%
  rename(IPLen=ILen)

Ultimately, there should be a total of 300 samples/groups.

Body:
It is quite unclear exactly what you want to achieve, so this might be a long shot.

There seems to be 2 problems included in this question:

Create a sequence with multiple by elements

group a certain column by the sequence generated in 1.

Create a sequence with multiple by elements

Now the for 1. I'm unaware of any inbuild or package function, even though I don't doubt it already exists. We can however simply create our own seqv function with vectorized by elements.

seqv <- function(from, to, by){
  diff <- to - from
  if((n <- diff / sum(by)) < 1){
    n <- 1
  }else{
    n <- ceiling(n)
  }
  out <- c(from, from + cumsum(rep(by, n)))
  out[out <= to]
}

Usage example:

mi <- trunc(min(pump_packets$PacketTime))
ma <- max(pump_packets$PacketTime)
ra <- 1:60
ra[60] <- ra[60] + 5
cuts <- seqv(mi, ma + 5, ra)
cuts[c(1:6, (length(cuts) - 5):length(cuts))]
[1]     0     1     3     6    10    15 10400 10450 10501 10553 10606 10660
length(cuts)
[1] 355

now this output does not include the max value of 10660.46 and the length is not 300, this does however follow the description in the question, as such I am not sure where the misunderstanding has happened. For now I'll add a bit to the last value to include the max value.

cuts[length(cuts)] <- cuts[length(cuts)] + 1

group a certain column by the sequence generated in 1.

Now the main part was really in 1. so here We can just use the cut function to create our groupings

pump_packets$group <-
  cut(pump_packets$PacketTime, breaks = cuts, right = FALSE, dig.lab = 12)

pump_packets_summary <- pump_packets %>%
  group_by(group) %>%
  summarise(
    PacketTime = max(PacketTime) - min(PacketTime),
    FrameLen = list(FrameLen),
    IPLen = list(IPLen),
    n = n()
  )
head(pump_packets_summary)
# A tibble: 6 x 5
  group   PacketTime FrameLen   IPLen          n
  <fct>        <dbl> <list>     <list>     <int>
1 [0,1)      0.0496  <int [16]> <int [16]>    16
2 [1,3)      0.0396  <int [52]> <int [52]>    52
3 [3,6)      0.00634 <int [6]>  <int [6]>      6
4 [6,10)     0.00672 <int [6]>  <int [6]>      6
5 [10,15)    0.00529 <int [6]>  <int [6]>      6
6 [15,21)    3.01    <int [12]> <int [12]>    12
tail(pump_packets_summary )
# A tibble: 6 x 5
  group         PacketTime FrameLen   IPLen          n
  <fct>              <dbl> <list>     <list>     <int>
1 [10351,10400)       30.0 <int [8]>  <int [8]>      8
2 [10400,10450)       41.0 <int [20]> <int [20]>    20
3 [10450,10501)       42.0 <int [24]> <int [24]>    24
4 [10501,10553)       43.0 <int [20]> <int [20]>    20
5 [10553,10606)       44.0 <int [20]> <int [20]>    20
6 [10606,10661)       50.0 <int [16]> <int [16]>    16

Which might be the desired result.


问:
How to reduce number of map calls in Angular Web App (agm-core)?
We have a simple application made with Angular that has 5 pages, each with Google map. The reason we moved to Angular was so we could reduce the number of Map calls per user session to just 1 (in javascript based application, it was going upto 20 per session!).

However, our implementation still costs as many map calls as number of visits to each of these pages, and we would like to know what we are doing wrong.

Here's our setup:

We are using agm-core library (and not JS script directly) We divided
our app into 5 sub-components (each page with its own component) with
a master component : /home. The map is imported in a separate
component at the same level as Home component

We also allow users to hide the map. For this, we tried two things: 1.) Set map height/width to zero. 2.) Push the map out of the boundaries of the screen, and bring it back when user wants to see it.

Our component structure:

```<code>- map-div
- home
  - page1
  - page2
  - page3
  - page4
  - page5
</code>```

Clicking on each of the pages should not initialize map-div again, however, after testing and looking at the API calls in GCP, we realize that each page click is still counting towards Map calls.

Note: To test the number of API calls, we created a separate environment with a new key, and performed limited, traceable steps to identify the correct number of calls. Each click on Pages 1..5 was counted as a separate API call.

Below is the usage shown on GCP API/Services -> Credentials -> Key  after clicking pages 1...5, total of 12 times.

```<code>Total usage (last 30 days)
12
</code>```

We also looked at Transactions under Billing, and the number seems to be correct (charges for Dynamic Map calls).

We haven't gone through the code inside agm-core, and are trying to avoid overhead of implementing a custom class using Javascript in the hope that there must be a better way to do this. Please raise a comment if we can include more information / code.

How approach should we take so that each session only costs us 1 map load?

Thank you

答:
You can't build it so that an user session costs you only 1 map load. There are no session-based nor caching options for JavaScript API, which is what the agm-core library uses underneath.

A map load means every time a map is created with the google.maps.Map() class. Even if you "hide" the map, if you still create it, then that counts. Each web page refresh that loads a map counts. So if each of those pages loads a map then it's expected that the number of map loads increases for every visit to said page (regardless of whether it's the same user session or not).

If you want to lower costs, besides removing the map creation from web pages where you do not need to display a map, I recommend you look into setting daily quota limits and budget alerts as per this FAQ.

Body:
We have a simple application made with Angular that has 5 pages, each with Google map. The reason we moved to Angular was so we could reduce the number of Map calls per user session to just 1 (in javascript based application, it was going upto 20 per session!).

However, our implementation still costs as many map calls as number of visits to each of these pages, and we would like to know what we are doing wrong.

Here's our setup:

We are using agm-core library (and not JS script directly) We divided
our app into 5 sub-components (each page with its own component) with
a master component : /home. The map is imported in a separate
component at the same level as Home component

We also allow users to hide the map. For this, we tried two things: 1.) Set map height/width to zero. 2.) Push the map out of the boundaries of the screen, and bring it back when user wants to see it.

Our component structure:

- map-div
- home
  - page1
  - page2
  - page3
  - page4
  - page5

Clicking on each of the pages should not initialize map-div again, however, after testing and looking at the API calls in GCP, we realize that each page click is still counting towards Map calls.

Note: To test the number of API calls, we created a separate environment with a new key, and performed limited, traceable steps to identify the correct number of calls. Each click on Pages 1..5 was counted as a separate API call.

Below is the usage shown on GCP API/Services -> Credentials -> Key  after clicking pages 1...5, total of 12 times.

Total usage (last 30 days)
12

We also looked at Transactions under Billing, and the number seems to be correct (charges for Dynamic Map calls).

We haven't gone through the code inside agm-core, and are trying to avoid overhead of implementing a custom class using Javascript in the hope that there must be a better way to do this. Please raise a comment if we can include more information / code.

How approach should we take so that each session only costs us 1 map load?

Thank you


问:
How to get the day of the week from the day number in JavaScript?
Given dayNumber is from 0 - 6 representing Monday - Sunday respectively.

Can the Date / String objects be used to get the day of the week from dayNumber?

答:
```<code>let today= new Date()

//Function To Convert Day Integer to String

function daysToSrting() {
  const daysOfWeek = ['Sunday', 'Monday','Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  return daysOfWeek[today.getDay()]
}

console.log(daysToSrting())
</code>```