问:
Pandas - loop through dataframe, check column values if empty, if empty then add entire row to new list or df
Currently my database looks like this:

```<code>import pandas as pd

output =  [['Owner', 'Database', 'Schema', 'Table', 'Column', 'Comment', 'Status'], ['', 'VICE_DEV', 'AIRFLOW', 'TASK_INSTANCE', '_LOAD_DATETIME', 'Load datetime'], ['', 'VICE_DEV', 'AIRFLOW', 'TEST', '_LOAD_FILENAME', 'load file name', 'ADDED']]

df = pd.DataFrame(output[1:], columns=output[0])
</code>```

It looks like this:

```<code>  Owner  Database   Schema  ...          Column         Comment Status
0        VICE_DEV  AIRFLOW  ...  _LOAD_DATETIME   Load datetime   None
1        VICE_DEV  AIRFLOW  ...  _LOAD_FILENAME  load file name  ADDED
</code>```

I'm now trying to loop through the Status col, and if Status is None or empty I want to create a list of SQL string queries, and go to the next row and check, etc.

I've tried this:

```<code>query_list = []

for column in df['Status']:
    if column is None:
        sql = f"ALTER TABLE {df['Table']} ALTER {df['Column']} COMMENT {df['Comment']}; "
        # print(sql)
        query_list.append(sql)
</code>```

But its not correct, its getting both rows, instead I want to only get the rows with the column df['Status'] None (or empty). Also, the formatting is off. I've tried by creating an empty list and an empty df.

答:
If I understand it correctly you want to create one query if Status is None. This query uses the values from the particular row that is None. The problem then is that you insert whole columns into your query and not the values from the particular row with Status==None. I think what you want is to iterate over all columns in your dataframe and then check if the status is None. If so, create the query based on that row. This can be done with the following code for example:

```<code>import pandas as pd

output =  [['Owner', 'Database', 'Schema', 'Table', 'Column', 'Comment', 'Status'], ['', 'VICE_DEV', 'AIRFLOW', 'TASK_INSTANCE', '_LOAD_DATETIME', 'Load datetime'], ['', 'VICE_DEV', 'AIRFLOW', 'TEST', '_LOAD_FILENAME', 'load file name', 'ADDED']]

df = pd.DataFrame(output[1:], columns=output[0])

query_list = []

for index, row in df.iterrows():
    if row['Status'] is None:
        sql = f"ALTER TABLE {row['Table']} ALTER {row['Column']} COMMENT {row['Comment']}; "

        # print(sql)
        query_list.append(sql)
query_list
</code>```

Output:

```<code>['ALTER TABLE TASK_INSTANCE ALTER _LOAD_DATETIME COMMENT Load datetime; ']
</code>```

Body:
Currently my database looks like this:

import pandas as pd

output =  [['Owner', 'Database', 'Schema', 'Table', 'Column', 'Comment', 'Status'], ['', 'VICE_DEV', 'AIRFLOW', 'TASK_INSTANCE', '_LOAD_DATETIME', 'Load datetime'], ['', 'VICE_DEV', 'AIRFLOW', 'TEST', '_LOAD_FILENAME', 'load file name', 'ADDED']]

df = pd.DataFrame(output[1:], columns=output[0])

It looks like this:

  Owner  Database   Schema  ...          Column         Comment Status
0        VICE_DEV  AIRFLOW  ...  _LOAD_DATETIME   Load datetime   None
1        VICE_DEV  AIRFLOW  ...  _LOAD_FILENAME  load file name  ADDED

I'm now trying to loop through the Status col, and if Status is None or empty I want to create a list of SQL string queries, and go to the next row and check, etc.

I've tried this:

query_list = []

for column in df['Status']:
    if column is None:
        sql = f"ALTER TABLE {df['Table']} ALTER {df['Column']} COMMENT {df['Comment']}; "
        # print(sql)
        query_list.append(sql)

But its not correct, its getting both rows, instead I want to only get the rows with the column df['Status'] None (or empty). Also, the formatting is off. I've tried by creating an empty list and an empty df.

Body:
If I understand it correctly you want to create one query if Status is None. This query uses the values from the particular row that is None. The problem then is that you insert whole columns into your query and not the values from the particular row with Status==None. I think what you want is to iterate over all columns in your dataframe and then check if the status is None. If so, create the query based on that row. This can be done with the following code for example:

import pandas as pd

output =  [['Owner', 'Database', 'Schema', 'Table', 'Column', 'Comment', 'Status'], ['', 'VICE_DEV', 'AIRFLOW', 'TASK_INSTANCE', '_LOAD_DATETIME', 'Load datetime'], ['', 'VICE_DEV', 'AIRFLOW', 'TEST', '_LOAD_FILENAME', 'load file name', 'ADDED']]

df = pd.DataFrame(output[1:], columns=output[0])

query_list = []

for index, row in df.iterrows():
    if row['Status'] is None:
        sql = f"ALTER TABLE {row['Table']} ALTER {row['Column']} COMMENT {row['Comment']}; "

        # print(sql)
        query_list.append(sql)
query_list

Output:

['ALTER TABLE TASK_INSTANCE ALTER _LOAD_DATETIME COMMENT Load datetime; ']


来源: stackexchange

问:
Testing Windowing in Apache Beam Python SDK
I am trying to write tests for late and out-of-order data in an Apache Beam 2.35.0 pipeline written using the Python SDK. I'm following the Testing Unbounded Pipelines in Apache Beam blog post and trying to map the Java examples into Python by reading the Python code.

Here is my first attempt. The pipeline is extracting the time from the message and rewriting the times on the messages. The comments explain my understanding of what's going on:

```<code>import apache_beam as beam
import pandas as pd
from apache_beam.testing import test_stream
from apache_beam.testing.test_pipeline import TestPipeline
from apache_beam.testing.util import assert_that, equal_to

def test_out_of_order_data():
    stream = test_stream.TestStream()

    # First element arrives 15 after its "data" time.
    stream.advance_watermark_to(ts("12:00:45"))
    stream.add_elements([{"time": ts("12:00:30"), "value": 1}])

    # Next element 5 seconds after its data time and advances output watermark past the previous window.
    stream.advance_watermark_to(ts("13:01:05"))
    stream.add_elements([{"time": ts("13:01:01"), "value": 2}])

    # Late element from the first window arrives.
    stream.advance_watermark_to(ts("13:01:06"))
    stream.add_elements([{"time": ts("12:00:31"), "value": 3}])

    stream.advance_watermark_to_infinity()

    with TestPipeline() as p:
        output = (
            p
            | "stream" >> stream
            | "rewrite timestamps" >> beam.Map(lambda e: beam.window.TimestampedValue(e, e["time"]))
            | "window" >> beam.WindowInto(beam.window.FixedWindows(60))
            | "add dummy key" >> beam.Map(lambda elem: (None, elem))
            | "group" >> beam.GroupByKey()
            | "remove dummy key" >> beam.Map(lambda elem: elem[1])
            | "sum" >> beam.Map(lambda elems: sum([e["value"] for e in elems]))
        )

        # I expected the output watermark to be advanced by the data, the late element to be discarded,
        # and `output` to be [1, 2]. It is not. This test passes.
        assert_that(output, equal_to([4, 2]))

def ts(time_str):
    return pd.Timestamp(f"2000-01-01 {time_str}").timestamp()
</code>```

That did not behave as I expected. The late message at 13:01:06 watermark time still contributes to the 12:00 window.

The Java example has some assertions that reference windows directly. I thought that might be what I'm missing above, so I tried to write a minimal test using that:

```<code>def test_window_simple_with_global_false():
    stream = test_stream.TestStream()
    stream.advance_watermark_to(ts("12:00:30"))
    stream.add_elements([1])
    stream.advance_watermark_to_infinity()

    with TestPipeline() as p:
        output = (
            p
            | "stream" >> stream
            | "window" >> beam.WindowInto(beam.window.FixedWindows(60))
            | "add dummy key" >> beam.Map(lambda elem: (None, elem))
            | "group" >> beam.GroupByKey()
            | "remove dummy key" >> beam.Map(lambda elem: elem[1])
        )
        assert_that(
            output,
            equal_to({beam.window.IntervalWindow(ts("12:00"), ts("12:01")): [1]}),
            use_global_window=False,
        )
</code>```

I tried some variations of this (removing the "add dummy key/group/remove dummy key" steps, adding reify_windows=True), but it looks like the matcher is expecting a window and receiving a list:

```<code>ERROR    apache_beam.runners.direct.executor:executor.py:379 Exception at bundle <apache_beam.runners.direct.bundle_factory._Bundle object at 0x7f44cd345400>, due to an exception.
 Traceback (most recent call last):
  File "apache_beam/runners/common.py", line 1198, in apache_beam.runners.common.DoFnRunner.process
  File "apache_beam/runners/common.py", line 718, in apache_beam.runners.common.PerWindowInvoker.invoke_process
  File "apache_beam/runners/common.py", line 843, in apache_beam.runners.common.PerWindowInvoker._invoke_process_per_window
  File "/home/aschmied/code/cme-injestion/cme-real-time/.tox/unit/lib/python3.8/site-packages/apache_beam/transforms/core.py", line 1636, in <lambda>
    wrapper = lambda x, *args, **kwargs: [fn(x, *args, **kwargs)]
  File "/home/aschmied/code/cme-injestion/cme-real-time/.tox/unit/lib/python3.8/site-packages/apache_beam/testing/util.py", line 164, in _equal
    sorted_actual = sorted(actual)
  File "/home/aschmied/code/cme-injestion/cme-real-time/.tox/unit/lib/python3.8/site-packages/apache_beam/transforms/window.py", line 232, in __lt__
    if self.end != other.end:
AttributeError: 'list' object has no attribute 'end'
</code>```

Any help greatly appreciated.

答:
For your first question, there's no guarantee that "late" data will be dropped, rather the runner is allowed to drop data later than this. (In practice, in a distributed runner, whether data is late and by how much is often a matter of non-deterministic timing.) I agree that it'd be nicer if the local runner enforced this though.

As for testing with reify_windows=True, I've found it much easier to do something like

```<code>assert_that(
  actual | beam.Map(lambda x, w=beam.DoFn.WindowParam: (x, w))
  equal_to([(some_value, some_window)])
)
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am trying to write tests for late and out-of-order data in an Apache Beam 2.35.0 pipeline written using the Python SDK. I'm following the Testing Unbounded Pipelines in Apache Beam blog post and trying to map the Java examples into Python by reading the Python code.

Here is my first attempt. The pipeline is extracting the time from the message and rewriting the times on the messages. The comments explain my understanding of what's going on:

import apache_beam as beam
import pandas as pd
from apache_beam.testing import test_stream
from apache_beam.testing.test_pipeline import TestPipeline
from apache_beam.testing.util import assert_that, equal_to

def test_out_of_order_data():
    stream = test_stream.TestStream()

    # First element arrives 15 after its "data" time.
    stream.advance_watermark_to(ts("12:00:45"))
    stream.add_elements([{"time": ts("12:00:30"), "value": 1}])

    # Next element 5 seconds after its data time and advances output watermark past the previous window.
    stream.advance_watermark_to(ts("13:01:05"))
    stream.add_elements([{"time": ts("13:01:01"), "value": 2}])

    # Late element from the first window arrives.
    stream.advance_watermark_to(ts("13:01:06"))
    stream.add_elements([{"time": ts("12:00:31"), "value": 3}])

    stream.advance_watermark_to_infinity()

    with TestPipeline() as p:
        output = (
            p
            | "stream" >> stream
            | "rewrite timestamps" >> beam.Map(lambda e: beam.window.TimestampedValue(e, e["time"]))
            | "window" >> beam.WindowInto(beam.window.FixedWindows(60))
            | "add dummy key" >> beam.Map(lambda elem: (None, elem))
            | "group" >> beam.GroupByKey()
            | "remove dummy key" >> beam.Map(lambda elem: elem[1])
            | "sum" >> beam.Map(lambda elems: sum([e["value"] for e in elems]))
        )

        # I expected the output watermark to be advanced by the data, the late element to be discarded,
        # and `output` to be [1, 2]. It is not. This test passes.
        assert_that(output, equal_to([4, 2]))

def ts(time_str):
    return pd.Timestamp(f"2000-01-01 {time_str}").timestamp()

That did not behave as I expected. The late message at 13:01:06 watermark time still contributes to the 12:00 window.

The Java example has some assertions that reference windows directly. I thought that might be what I'm missing above, so I tried to write a minimal test using that:

def test_window_simple_with_global_false():
    stream = test_stream.TestStream()
    stream.advance_watermark_to(ts("12:00:30"))
    stream.add_elements([1])
    stream.advance_watermark_to_infinity()

    with TestPipeline() as p:
        output = (
            p
            | "stream" >> stream
            | "window" >> beam.WindowInto(beam.window.FixedWindows(60))
            | "add dummy key" >> beam.Map(lambda elem: (None, elem))
            | "group" >> beam.GroupByKey()
            | "remove dummy key" >> beam.Map(lambda elem: elem[1])
        )
        assert_that(
            output,
            equal_to({beam.window.IntervalWindow(ts("12:00"), ts("12:01")): [1]}),
            use_global_window=False,
        )

I tried some variations of this (removing the "add dummy key/group/remove dummy key" steps, adding reify_windows=True), but it looks like the matcher is expecting a window and receiving a list:

ERROR    apache_beam.runners.direct.executor:executor.py:379 Exception at bundle <apache_beam.runners.direct.bundle_factory._Bundle object at 0x7f44cd345400>, due to an exception.
 Traceback (most recent call last):
  File "apache_beam/runners/common.py", line 1198, in apache_beam.runners.common.DoFnRunner.process
  File "apache_beam/runners/common.py", line 718, in apache_beam.runners.common.PerWindowInvoker.invoke_process
  File "apache_beam/runners/common.py", line 843, in apache_beam.runners.common.PerWindowInvoker._invoke_process_per_window
  File "/home/aschmied/code/cme-injestion/cme-real-time/.tox/unit/lib/python3.8/site-packages/apache_beam/transforms/core.py", line 1636, in <lambda>
    wrapper = lambda x, *args, **kwargs: [fn(x, *args, **kwargs)]
  File "/home/aschmied/code/cme-injestion/cme-real-time/.tox/unit/lib/python3.8/site-packages/apache_beam/testing/util.py", line 164, in _equal
    sorted_actual = sorted(actual)
  File "/home/aschmied/code/cme-injestion/cme-real-time/.tox/unit/lib/python3.8/site-packages/apache_beam/transforms/window.py", line 232, in __lt__
    if self.end != other.end:
AttributeError: 'list' object has no attribute 'end'

Any help greatly appreciated.

Body:
For your first question, there's no guarantee that "late" data will be dropped, rather the runner is allowed to drop data later than this. (In practice, in a distributed runner, whether data is late and by how much is often a matter of non-deterministic timing.) I agree that it'd be nicer if the local runner enforced this though.

As for testing with reify_windows=True, I've found it much easier to do something like

assert_that(
  actual | beam.Map(lambda x, w=beam.DoFn.WindowParam: (x, w))
  equal_to([(some_value, some_window)])
)


问:
Trying to add my animation to my idle state, but it just keeps saying "None(Motion)"
I have pulled the animation to the Motion tab both by dragging and trough the select motion search function but neither makes the animation stick to my idle state. Can someone give me a pointer to what im doing wrong?</p>

答: Use the Animator, not the animation controller. I made this mistake when I was following a tutorial. This is only relevant if you are animating .anim files within unity itself. Animation controller is the way to go if you import animations for your specific model.</p>

ContentLicense: CC BY-SA 3.0


问:
List of available/registered twilio voice clients
I'm looking through documention but didn't find anything that can help me find registered clients to twilio voice incoming calls.

For example. I have 10 registered clients to javascript sdk, that can handle incoming calls by their identities. But on my backend I need to find out who is registered and who is not busy making another call.

Is there any endpoint or someting that can return list of users(identites, clients, devices) with their status?

Because with TwiML I can redirect incoming call up to 10 clients. But when I don't know who is ready to answer and not busy I can't redirect responsible.

Thanks for any leads.

答:
Twilio developer evangelist here.

I'm afraid that there isn't a way to list your currently registered clients. But you have a couple of options with how to deal with this.

You could keep a list of your registered clients manually. Adding a client to the list as they log in and removing them when they disconnect.

Alternatively, you could consider using TaskRouter to keep track of this and control the passing out of incoming call tasks to available agents. Then the agents would log on and enter an idle status in TaskRouter, when they accept a call they would be busy, once the call is over they go through a wrapping up stage before you return them to idle and ready for another call.


问:
What is the easiest way to generate a String of n repeated characters?
Given a character c and a number n, how can I create a String that consists of n repetitions of c? Doing it manually is too cumbersome:

```<code>StringBuilder sb = new StringBuilder(n);
for (int i = 0; i < n; ++i)
{
    sb.append(c);
}
String result = sb.toString();
</code>```

Surely there is some static library function that already does this for me?

答:
```<code>int n = 10;
char[] chars = new char[n];
Arrays.fill(chars, 'c');
String result = new String(chars);
</code>```

EDIT:

It's been 9 years since this answer was submitted but it still attracts some attention now and then. In the meantime Java 8 has been introduced with functional programming features. Given a char c and the desired number of repetitions count the following one-liner can do the same as above.

```<code>String result = IntStream.range(1, count).mapToObj(index -> "" + c).collect(Collectors.joining());
</code>```

Do note however that it is slower than the array approach. It should hardly matter in any but the most demanding circumstances. Unless it's in some piece of code that will be executed thousands of times per second it won't make much difference. This can also be used with a String instead of a char to repeat it a number of times so it's a bit more flexible. No third-party libraries needed.

Body:
Given a character c and a number n, how can I create a String that consists of n repetitions of c? Doing it manually is too cumbersome:

StringBuilder sb = new StringBuilder(n);
for (int i = 0; i < n; ++i)
{
    sb.append(c);
}
String result = sb.toString();

Surely there is some static library function that already does this for me?

Body:
int n = 10;
char[] chars = new char[n];
Arrays.fill(chars, 'c');
String result = new String(chars);

EDIT:

It's been 9 years since this answer was submitted but it still attracts some attention now and then. In the meantime Java 8 has been introduced with functional programming features. Given a char c and the desired number of repetitions count the following one-liner can do the same as above.

String result = IntStream.range(1, count).mapToObj(index -> "" + c).collect(Collectors.joining());

Do note however that it is slower than the array approach. It should hardly matter in any but the most demanding circumstances. Unless it's in some piece of code that will be executed thousands of times per second it won't make much difference. This can also be used with a String instead of a char to repeat it a number of times so it's a bit more flexible. No third-party libraries needed.


问:
Notifications are being sent out on the wrong time (Java, Android Studio)
In my app the user can choose a time and a date when a notification will be sent out on.
However, the notifcations are not being sent out on the right time. If I choose a notification to be sent out on the same day, it will be sent out on a random time during the next day. and If I choose a notification to be sent out on a day in the future, it will be sent out on a random time during that day. So in summary, it seems to be ignoring the time and sending out notifications based on the date but it can't even get the date right when I choose a notification for the current day.

The code worked fine when the the user only had the ability to choose the time. It broke after I added the ability to choose a date for the notification.

MeeldetuletusActivity.java

```<code>public class MeeldetuletusActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener, DatePickerDialog.OnDateSetListener {
    String timeText;
    TextView textTime;
    Button nupp_vali, nupp_katkesta, nupp_kuupaev, nupp_alarm;
    Calendar c;

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

        nupp_vali = findViewById(R.id.button2);
        nupp_katkesta = findViewById(R.id.nupp_katkesta);
        nupp_kuupaev = findViewById(R.id.button);
        nupp_alarm = findViewById(R.id.button3);

        nupp_alarm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startAlarm(c);

            }
        });

        nupp_vali.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment timePicker = new TimePickerFragment();
                timePicker.show(getSupportFragmentManager(), "time picker");

            }
        });

        nupp_kuupaev.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment kuupaevaValija = new KuupaevaFragment();
                kuupaevaValija.show(getSupportFragmentManager(), "date picker");
            }
        });

        nupp_katkesta.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                katkestaAlarm();
                Toast.makeText(MeeldetuletusActivity.this, "Meeldetuletus unustatud", Toast.LENGTH_SHORT).show();

            }
        });

    }

    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, hourOfDay);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, 0);
    }

    public void onDateSet (DatePicker view, int aasta, int kuu, int paev) {
        c = Calendar.getInstance();
        c.set(Calendar.YEAR, aasta);
        c.set(Calendar.MONTH, kuu);
        c.set(Calendar.DAY_OF_MONTH, paev);
    }

    private void startAlarm(Calendar c) {
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, NotificationPublisher.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
        if (c.before(Calendar.getInstance())) {
            c.add(Calendar.DATE, 1);
        }
        Objects.requireNonNull(alarmManager).setExact(AlarmManager.RTC_WAKEUP,
                c.getTimeInMillis(), pendingIntent);
    }

    private void katkestaAlarm() {
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent myIntent = new Intent(getApplicationContext(), NotificationPublisher.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                getApplicationContext(), 1, myIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        alarmManager.cancel(pendingIntent);
    }
}
</code>```

KuupaevaFragment.java

```<code>public class KuupaevaFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        int aasta = c.get(Calendar.YEAR);
        int kuu = c.get(Calendar.MONTH);
        int paev = c.get(Calendar.DAY_OF_MONTH);
        return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener) getActivity(),
                aasta, kuu, paev);

    }

}
</code>```

TimePickerFragment.java

```<code>public class TimePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);
        return new TimePickerDialog(getActivity(), (TimePickerDialog.OnTimeSetListener) getActivity(),
                hour, minute, DateFormat.is24HourFormat(getActivity()));

    }

}
</code>```

NotificationPublisher.java

```<code>public class NotificationPublisher extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationHelper notificationHelper = new NotificationHelper(context);
        NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
        notificationHelper.getManager().notify(1, nb.build());
        Notification notification = nb.build();
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        notification.defaults |= Notification.DEFAULT_SOUND;
    }
}
</code>```

NotificationHelper.java

```<code>class NotificationHelper extends ContextWrapper {
    public static final String channelID = "channelID";
    public static final String channelName = "Channel Name";
    private NotificationManager notificationManager;
    public NotificationHelper(Context base) {
        super(base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel();
        }
    }
    @TargetApi(Build.VERSION_CODES.O)
    private void createChannel() {
        NotificationChannel channel = new NotificationChannel(channelID, channelName,
                NotificationManager.IMPORTANCE_HIGH);
        getManager().createNotificationChannel(channel);
    }
    public NotificationManager getManager() {
        if (notificationManager == null) {
            notificationManager = (NotificationManager)
                    getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return notificationManager;
    }
    public NotificationCompat.Builder getChannelNotification() {
        return new NotificationCompat.Builder(getApplicationContext(), channelID)
                .setContentTitle("Meeldetuletus")
                .setContentText("Teie valitud aeg on käes")
                .setSmallIcon(R.drawable.ic_baseline_notifications_active_24);
    }
}
</code>```

答:
The Answer by sweak seems correct about you needlessly instantiating new Calendar objects.

In addition, the Calendar class is terrible, and should be avoided. Sun, Oracle, and the JCP gave up on the legacy date-time classes when they appointed JSR 310 defining the modern java.time classes.

I’ve not studied all your code in detail, but at a glance it looks like you need to end up with simply a count of milliseconds from the epoch reference of the first moment of 1970 in UTC (an offset from UTC of zero hours-minutes-seconds). We can easily do that using only java.time classes.

Your code seems to be ignoring the crucial issue of time zone. If omitted from your code, the JVM’s current default time zone is implicitly applied. I suggest it is better to be explicit. Furthermore, the JVM’s current default time zone can be changed at any moment by any code in any app within the same JVM.

```<code>ZoneId z = ZoneId.systemDefault() ;  // Or ZoneId.of( "Europe/Paris" )
LocalDate ld = LocalDate.of( 2022 , 1 , 23 ) ;
LocalTime lt = LocalTime.of( 15 , 30 ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Instant instant = zdt.toInstant() ;
long millis = instant.toEpochMilli() ;
</code>```

Body:
In my app the user can choose a time and a date when a notification will be sent out on.
However, the notifcations are not being sent out on the right time. If I choose a notification to be sent out on the same day, it will be sent out on a random time during the next day. and If I choose a notification to be sent out on a day in the future, it will be sent out on a random time during that day. So in summary, it seems to be ignoring the time and sending out notifications based on the date but it can't even get the date right when I choose a notification for the current day.

The code worked fine when the the user only had the ability to choose the time. It broke after I added the ability to choose a date for the notification.

MeeldetuletusActivity.java

public class MeeldetuletusActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener, DatePickerDialog.OnDateSetListener {
    String timeText;
    TextView textTime;
    Button nupp_vali, nupp_katkesta, nupp_kuupaev, nupp_alarm;
    Calendar c;

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

        nupp_vali = findViewById(R.id.button2);
        nupp_katkesta = findViewById(R.id.nupp_katkesta);
        nupp_kuupaev = findViewById(R.id.button);
        nupp_alarm = findViewById(R.id.button3);

        nupp_alarm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startAlarm(c);

            }
        });

        nupp_vali.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment timePicker = new TimePickerFragment();
                timePicker.show(getSupportFragmentManager(), "time picker");

            }
        });

        nupp_kuupaev.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment kuupaevaValija = new KuupaevaFragment();
                kuupaevaValija.show(getSupportFragmentManager(), "date picker");
            }
        });

        nupp_katkesta.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                katkestaAlarm();
                Toast.makeText(MeeldetuletusActivity.this, "Meeldetuletus unustatud", Toast.LENGTH_SHORT).show();

            }
        });

    }

    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, hourOfDay);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, 0);
    }

    public void onDateSet (DatePicker view, int aasta, int kuu, int paev) {
        c = Calendar.getInstance();
        c.set(Calendar.YEAR, aasta);
        c.set(Calendar.MONTH, kuu);
        c.set(Calendar.DAY_OF_MONTH, paev);
    }

    private void startAlarm(Calendar c) {
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, NotificationPublisher.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
        if (c.before(Calendar.getInstance())) {
            c.add(Calendar.DATE, 1);
        }
        Objects.requireNonNull(alarmManager).setExact(AlarmManager.RTC_WAKEUP,
                c.getTimeInMillis(), pendingIntent);
    }

    private void katkestaAlarm() {
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent myIntent = new Intent(getApplicationContext(), NotificationPublisher.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                getApplicationContext(), 1, myIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        alarmManager.cancel(pendingIntent);
    }
}

KuupaevaFragment.java

public class KuupaevaFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        int aasta = c.get(Calendar.YEAR);
        int kuu = c.get(Calendar.MONTH);
        int paev = c.get(Calendar.DAY_OF_MONTH);
        return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener) getActivity(),
                aasta, kuu, paev);

    }

}

TimePickerFragment.java

public class TimePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);
        return new TimePickerDialog(getActivity(), (TimePickerDialog.OnTimeSetListener) getActivity(),
                hour, minute, DateFormat.is24HourFormat(getActivity()));

    }

}

NotificationPublisher.java

public class NotificationPublisher extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationHelper notificationHelper = new NotificationHelper(context);
        NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
        notificationHelper.getManager().notify(1, nb.build());
        Notification notification = nb.build();
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        notification.defaults |= Notification.DEFAULT_SOUND;
    }
}

NotificationHelper.java

class NotificationHelper extends ContextWrapper {
    public static final String channelID = "channelID";
    public static final String channelName = "Channel Name";
    private NotificationManager notificationManager;
    public NotificationHelper(Context base) {
        super(base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel();
        }
    }
    @TargetApi(Build.VERSION_CODES.O)
    private void createChannel() {
        NotificationChannel channel = new NotificationChannel(channelID, channelName,
                NotificationManager.IMPORTANCE_HIGH);
        getManager().createNotificationChannel(channel);
    }
    public NotificationManager getManager() {
        if (notificationManager == null) {
            notificationManager = (NotificationManager)
                    getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return notificationManager;
    }
    public NotificationCompat.Builder getChannelNotification() {
        return new NotificationCompat.Builder(getApplicationContext(), channelID)
                .setContentTitle("Meeldetuletus")
                .setContentText("Teie valitud aeg on käes")
                .setSmallIcon(R.drawable.ic_baseline_notifications_active_24);
    }
}

Body:
The Answer by sweak seems correct about you needlessly instantiating new Calendar objects.

In addition, the Calendar class is terrible, and should be avoided. Sun, Oracle, and the JCP gave up on the legacy date-time classes when they appointed JSR 310 defining the modern java.time classes.

I’ve not studied all your code in detail, but at a glance it looks like you need to end up with simply a count of milliseconds from the epoch reference of the first moment of 1970 in UTC (an offset from UTC of zero hours-minutes-seconds). We can easily do that using only java.time classes.

Your code seems to be ignoring the crucial issue of time zone. If omitted from your code, the JVM’s current default time zone is implicitly applied. I suggest it is better to be explicit. Furthermore, the JVM’s current default time zone can be changed at any moment by any code in any app within the same JVM.

ZoneId z = ZoneId.systemDefault() ;  // Or ZoneId.of( "Europe/Paris" )
LocalDate ld = LocalDate.of( 2022 , 1 , 23 ) ;
LocalTime lt = LocalTime.of( 15 , 30 ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Instant instant = zdt.toInstant() ;
long millis = instant.toEpochMilli() ;


问:
Google Sheets Extracting Digits with Regex
I've been stuck on this for a while now. I want to extract only digits (numeric values) from the cell, but for some reason, it does not extract if it contains a single digit. See below for more details:

String
End Result

$8 - added to cart
8

Formula used: =REGEXEXTRACT(J92,"\d+.?\d+")

The formula would also grab digits that contain decimals. For some reason, this formula works if the string was "$81 - added to cart". Can someone help me fix this so it would work on strings with a single digit?

Body:
Use

=REGEXEXTRACT(J92,"\d+(?:\.\d+)?")

EXPLANATION

--------------------------------------------------------------------------------
  \d+                      digits (0-9) (1 or more times (matching
                           the most amount possible))
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (optional
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    \.                       '.'
--------------------------------------------------------------------------------
    \d+                      digits (0-9) (1 or more times (matching
                             the most amount possible))
--------------------------------------------------------------------------------
  )?                       end of grouping

Your regex does not work because it means:

--------------------------------------------------------------------------------
  \d+                      digits (0-9) (1 or more times (matching
                           the most amount possible))
--------------------------------------------------------------------------------
  .?                       any character except \n (optional
                           (matching the most amount possible))
--------------------------------------------------------------------------------
  \d+                      digits (0-9) (1 or more times (matching
                           the most amount possible))


问:
Reference current drive path in a Foreach loop through drives
I'm trying to find and log any local PST files on multiple machines, accross all local drives on each machine. I have the code below so far, but I can't get it to run in the context of the root of the current drive in the foreach loop, it just runs in the context of where the script was run from.

```<code>If (-not (Test-Path -Path "\\BETH-FS01\F$\PSTBackups")){
    Exit 1
} # check if PC is connected to domain, some laptops aren't always on the VPN
Else{
    #defines the path where to store the log CSV
    $LogPath = "\\BETH-FS01\F$\PSTBackups"
    $Log = @() #object array to store "PST objects"

    # defining string variable to combine with another string variable later on
    $Ext = ".pst"

    # creates array of local drives on PC
    $Drives = Get-PSDrive -PSProvider 'FileSystem'

    foreach ($Drive in $Drives) {

        # searches drive for PST files, creates an array of those files,
        # then passes each through to create PST objects
        $Log = ForEach ($PST in ($PSTS = Get-ChildItem -LiteralPath $Drive.Name -Include *.pst -Recurse -Force -erroraction silentlycontinue)){
            New-Object PSObject -Property @{
                ComputerName = $env:COMPUTERNAME
                Path = $PST.DirectoryName
                FileName = $PST.BaseName+$Ext
                Size = "{0:N2} MB" -f ($PST.Length / 1mb)
                Date = $PST.LastWriteTime.ToString("yyyy-MM-dd HH:mm")
            } #creates PST object
        }
    }
}
$Name = $env:COMPUTERNAME #define string to use in log path below
$Log | Export-Csv $LogPath\$Name.csv -NoTypeInformation #exports the Log object array to a CSV
</code>```

To clarify, I'm trying to find out how to reference the fact that if the foreach loop is currently doing the C: drive, it would use the "C:" path as the -path for Get-ChildItem, i.e.:

```<code>$PSTS = Get-ChildItem -path "*somehow reference C: drive path*" -Include *.pst -Recurse -Force -erroraction silentlycontinue
</code>```

Sorry if the code is sloppy, I'm not the best at keeping clean code...

答:
In this line...

```<code>$Log = ForEach ($PST in ($PSTS = Get-ChildItem -LiteralPath $Drive.Name -Include *.pst -Recurse -Force -erroraction silentlycontinue)){
</code>```

... you are just passing the drive letter for -LiteralPath, which is not a path.

You need to pass the root path, e. g. "C:\", not just "C" or "C:". The latter only means the current directory on drive C.

This should do the trick:

```<code>$Log = ForEach ($PST in ($PSTS = Get-ChildItem -LiteralPath $Drive.Root -Include *.pst -Recurse -Force -erroraction silentlycontinue)){
</code>```

Body:
I'm trying to find and log any local PST files on multiple machines, accross all local drives on each machine. I have the code below so far, but I can't get it to run in the context of the root of the current drive in the foreach loop, it just runs in the context of where the script was run from.

If (-not (Test-Path -Path "\\BETH-FS01\F$\PSTBackups")){
    Exit 1
} # check if PC is connected to domain, some laptops aren't always on the VPN
Else{
    #defines the path where to store the log CSV
    $LogPath = "\\BETH-FS01\F$\PSTBackups"
    $Log = @() #object array to store "PST objects"

    # defining string variable to combine with another string variable later on
    $Ext = ".pst"

    # creates array of local drives on PC
    $Drives = Get-PSDrive -PSProvider 'FileSystem'

    foreach ($Drive in $Drives) {

        # searches drive for PST files, creates an array of those files,
        # then passes each through to create PST objects
        $Log = ForEach ($PST in ($PSTS = Get-ChildItem -LiteralPath $Drive.Name -Include *.pst -Recurse -Force -erroraction silentlycontinue)){
            New-Object PSObject -Property @{
                ComputerName = $env:COMPUTERNAME
                Path = $PST.DirectoryName
                FileName = $PST.BaseName+$Ext
                Size = "{0:N2} MB" -f ($PST.Length / 1mb)
                Date = $PST.LastWriteTime.ToString("yyyy-MM-dd HH:mm")
            } #creates PST object
        }
    }
}
$Name = $env:COMPUTERNAME #define string to use in log path below
$Log | Export-Csv $LogPath\$Name.csv -NoTypeInformation #exports the Log object array to a CSV

To clarify, I'm trying to find out how to reference the fact that if the foreach loop is currently doing the C: drive, it would use the "C:" path as the -path for Get-ChildItem, i.e.:

$PSTS = Get-ChildItem -path "*somehow reference C: drive path*" -Include *.pst -Recurse -Force -erroraction silentlycontinue

Sorry if the code is sloppy, I'm not the best at keeping clean code...

Body:
In this line...

$Log = ForEach ($PST in ($PSTS = Get-ChildItem -LiteralPath $Drive.Name -Include *.pst -Recurse -Force -erroraction silentlycontinue)){

... you are just passing the drive letter for -LiteralPath, which is not a path.

You need to pass the root path, e. g. "C:\", not just "C" or "C:". The latter only means the current directory on drive C.

This should do the trick:

$Log = ForEach ($PST in ($PSTS = Get-ChildItem -LiteralPath $Drive.Root -Include *.pst -Recurse -Force -erroraction silentlycontinue)){


问:
Is it possible to get dataset file infromation at the time of test a model?
My dataset code is like the below one; Here, X_test is a list[list] and y_test is list[Path]

The first.py file

```<code>self.test_dataset = LongDataset(
                X_path=X_test,
                y_path=y_test,
                transform=val_transforms,
            )
</code>```

The rest of the part is as usual (dataloader)

```<code>def test_dataloader(self):
        return DataLoader(self.test_dataset, batch_size=1, num_workers=8)
</code>```

In the second.py file

The DataModule

```<code>data_module = DataModuleLong(batch_size=3,)
</code>```

The Trainer

```<code>trainer = Trainer(gpus=1)
    trainer.test(
        model=model,
        ckpt_path=ckpt_path,
        datamodule=data_module,
    )
</code>```

The  train_step() in the third.py file

```<code>def test_step(self, batch, batch_idx: int):
        inputs, targets = batch
        logits = self(inputs)
        ...
        ...
        ...
</code>```

Now, is it possible to print (in the train_step()) the (inputs, targets) filename (or the full path) I am sending from test_dataset as (X_path, y_path)?

答:
Essentially, what you want to do is get the index of each batch element in the batch returned by the dataloader object (from there it is trivial to index the dataset to get the desired data elements (in this case file paths).

Now the short answer is that there is no directly implemented way to return this data using the dataloader. However, there are a few workarounds:

Pass your own BatchSampler or Sampler object to the DataLoader constructor. Unfortunately there's not a simple way to query the Sampler for the current batch because it relies on generators (where yielding the next sample clears it and loades the next one. This is the same reason why you can't directly access the batch indices of the Dataloader. So to use this method, you'd have to pass a sampler wherein you know a priori which indices will be returned on the i-th query to the sampler. Not an ideal solution.

Create a custom dataset object - this is actually extremely easy to do, simply inherit from the torch.data object and implement the __init__, __len__ and __getitem__ methods. The __getitem__ method takes an index (let's say idx) as input and returns that index of the dataset. You can essentially copy the code for the existing LongDataset line for line, but simply append idx to the returned values from the __getitem__ method. I would demonstrate but you don't indicate where the LongDataset code comes from.

```<code>def __getitem__(self,idx):
    ... #load files, preprocess, etc.
    return data, idx
</code>```

Now dataloader will automatically zip the idx values for each, so you can simply replace the existing line with:

```<code>inputs, targets, indices = batch
data_paths = [self.test_dataset.file_paths[idx] for idx in indices]
</code>```

The second solution is by far preferable as it is more transparently easy to understand.

Body:
My dataset code is like the below one; Here, X_test is a list[list] and y_test is list[Path]

The first.py file

self.test_dataset = LongDataset(
                X_path=X_test,
                y_path=y_test,
                transform=val_transforms,
            )

The rest of the part is as usual (dataloader)

def test_dataloader(self):
        return DataLoader(self.test_dataset, batch_size=1, num_workers=8)

In the second.py file

The DataModule

data_module = DataModuleLong(batch_size=3,)

The Trainer

trainer = Trainer(gpus=1)
    trainer.test(
        model=model,
        ckpt_path=ckpt_path,
        datamodule=data_module,
    )

The  train_step() in the third.py file

def test_step(self, batch, batch_idx: int):
        inputs, targets = batch
        logits = self(inputs)
        ...
        ...
        ...

Now, is it possible to print (in the train_step()) the (inputs, targets) filename (or the full path) I am sending from test_dataset as (X_path, y_path)?

Body:
Essentially, what you want to do is get the index of each batch element in the batch returned by the dataloader object (from there it is trivial to index the dataset to get the desired data elements (in this case file paths).

Now the short answer is that there is no directly implemented way to return this data using the dataloader. However, there are a few workarounds:

Pass your own BatchSampler or Sampler object to the DataLoader constructor. Unfortunately there's not a simple way to query the Sampler for the current batch because it relies on generators (where yielding the next sample clears it and loades the next one. This is the same reason why you can't directly access the batch indices of the Dataloader. So to use this method, you'd have to pass a sampler wherein you know a priori which indices will be returned on the i-th query to the sampler. Not an ideal solution.

Create a custom dataset object - this is actually extremely easy to do, simply inherit from the torch.data object and implement the __init__, __len__ and __getitem__ methods. The __getitem__ method takes an index (let's say idx) as input and returns that index of the dataset. You can essentially copy the code for the existing LongDataset line for line, but simply append idx to the returned values from the __getitem__ method. I would demonstrate but you don't indicate where the LongDataset code comes from.

def __getitem__(self,idx):
    ... #load files, preprocess, etc.
    return data, idx

Now dataloader will automatically zip the idx values for each, so you can simply replace the existing line with:

inputs, targets, indices = batch
data_paths = [self.test_dataset.file_paths[idx] for idx in indices]

The second solution is by far preferable as it is more transparently easy to understand.


问:
Potential downtime during MSI upgrade
I'm considering deploying websites to an Win2k3/IIS6 machine using a MSI built with WiX.

The website in question has a collection of .html, .jpg, .js, .swf & .asp files (no ASP.NET)

I'm doing a "Major Upgrade" when installing the MSI (i.e, it first uninstalls the old MSI, then installs the new MSI).  This is the only way I can figure to get the MSI to remove redundant files.

My question is; will there be any downtime for visitors to the site during the uninstall / reinstall process?

Or does IIS cache the files being used by currently open connections?

答: No, you'll definitely be in an outage.  It does not cache that info.</p>

ContentLicense: CC BY-SA 2.5

Title: Potential downtime during MSI upgrade

OwnerDisplayName: Joe


问:
docker create context ecs fails in github actions
I'm trying to deploy my docker containers to ECS using docker compose. Everything works as expected locally, but when I try to do the same in a github actions workflow, I get the following error when trying to run docker create context ecs ecscontext:

"docker context create" requires exactly 1 argument.

I first assumed the error was because the docker and docker-compose version on the github runner were different my local ones, so I uninstalled them and reinstalled them. Here is the the modified workflow file:

```<code>name: deploy

on:
  workflow_dispatch:
  repository_dispatch:
    types: [update_stack]

jobs:
  deploy:
    name: "Deploy stack"
    runs-on: ubuntu-latest
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
      AWS_DEFAULT_REGION: us-east-1
    steps:
      -
        name: Update docker version
        run: |
          sudo apt-get remove docker docker-engine docker.io containerd runc
          sudo apt-get update -y
          sudo apt-get install -y ca-certificates curl gnupg lsb-release
          curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
          echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
          sudo apt-get update -y
          sudo apt-get install -y docker-ce docker-ce-cli containerd.io
      -
        name: Update docker-compose version
        run: |
          sudo rm /usr/local/bin/docker-compose
          sudo mkdir -p /usr/local/lib/docker/cli-plugins
          sudo curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose
          sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
      -
        name: check docker new version
        run: docker -v
      -
        name: check docker compose new version
        run: docker compose version
      -
        name: Create ECS docker context
        run: sudo docker context create ecs ecscontext --from-env
</code>```

The docker -v output is the same the one I have locally: Docker version 20.10.12, build e91ed57

The docker compose version output is the same as the one I have locally: Docker Compose version v2.2.3

Yet it still fails at the create context step. Any help is appreciated.

答:
Turns out that the docker and docker-compose binaries were irrelevant, I had to update the docker CLI by running sudo curl -L https://raw.githubusercontent.com/docker/compose-cli/main/scripts/install/install_linux.sh | sudo sh. The new workflow looks like this:

```<code>name: deploy

on:
  workflow_dispatch:
  repository_dispatch:
    types: [update_stack]

jobs:
  deploy:
    name: "Deploy stack"
    runs-on: ubuntu-latest
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
      AWS_DEFAULT_REGION: us-east-1
    steps:
      -
        name: Update docker-compose version
        run: |
          sudo curl -L https://raw.githubusercontent.com/docker/compose-cli/main/scripts/install/install_linux.sh | sudo sh
      -
        name: check docker new version
        run: docker -v
      -
        name: check docker compose new version
        run: docker compose version
      -
        name: Create ECS docker context
        run: sudo docker context create ecs ecscontext --from-env
</code>```

Body:
I'm trying to deploy my docker containers to ECS using docker compose. Everything works as expected locally, but when I try to do the same in a github actions workflow, I get the following error when trying to run docker create context ecs ecscontext:

"docker context create" requires exactly 1 argument.

I first assumed the error was because the docker and docker-compose version on the github runner were different my local ones, so I uninstalled them and reinstalled them. Here is the the modified workflow file:

name: deploy

on:
  workflow_dispatch:
  repository_dispatch:
    types: [update_stack]

jobs:
  deploy:
    name: "Deploy stack"
    runs-on: ubuntu-latest
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
      AWS_DEFAULT_REGION: us-east-1
    steps:
      -
        name: Update docker version
        run: |
          sudo apt-get remove docker docker-engine docker.io containerd runc
          sudo apt-get update -y
          sudo apt-get install -y ca-certificates curl gnupg lsb-release
          curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
          echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
          sudo apt-get update -y
          sudo apt-get install -y docker-ce docker-ce-cli containerd.io
      -
        name: Update docker-compose version
        run: |
          sudo rm /usr/local/bin/docker-compose
          sudo mkdir -p /usr/local/lib/docker/cli-plugins
          sudo curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose
          sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
      -
        name: check docker new version
        run: docker -v
      -
        name: check docker compose new version
        run: docker compose version
      -
        name: Create ECS docker context
        run: sudo docker context create ecs ecscontext --from-env

The docker -v output is the same the one I have locally: Docker version 20.10.12, build e91ed57

The docker compose version output is the same as the one I have locally: Docker Compose version v2.2.3

Yet it still fails at the create context step. Any help is appreciated.

Body:
Turns out that the docker and docker-compose binaries were irrelevant, I had to update the docker CLI by running sudo curl -L https://raw.githubusercontent.com/docker/compose-cli/main/scripts/install/install_linux.sh | sudo sh. The new workflow looks like this:

name: deploy

on:
  workflow_dispatch:
  repository_dispatch:
    types: [update_stack]

jobs:
  deploy:
    name: "Deploy stack"
    runs-on: ubuntu-latest
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
      AWS_DEFAULT_REGION: us-east-1
    steps:
      -
        name: Update docker-compose version
        run: |
          sudo curl -L https://raw.githubusercontent.com/docker/compose-cli/main/scripts/install/install_linux.sh | sudo sh
      -
        name: check docker new version
        run: docker -v
      -
        name: check docker compose new version
        run: docker compose version
      -
        name: Create ECS docker context
        run: sudo docker context create ecs ecscontext --from-env


问:
Ifelse with conditional on grouped data
This has got to be simple, but I'm stuck. I want to mutate some grouped data using a where statement within an ifelse statement. Here's an example that works:

```<code>example <- tibble::tribble(
  ~Group, ~Code, ~Value,
  "1", "A", 1,
  "1", "B", 1,
  "1", "C", 5,
  "2", "A", 1,
  "2", "B", 5,
  "2", "C", 2
)

example %>% group_by(Group) %>%
  mutate(GroupStatus=ifelse(Value[Code=="C"]==5, 1, 0))
</code>```

This gives the desired result:

```<code>  Group Code  Value GroupStatus
  <chr> <chr> <dbl>       <dbl>
1 1     A         1           1
2 1     B         1           1
3 1     C         5           1
4 2     A         1           0
5 2     B         5           0
6 2     C         2           0
</code>```

The problem is when one of the groups is missing Code C, as below:

```<code>example2 <- tibble::tribble(
  ~Group, ~Code, ~Value,
  "1", "A", 1,
  "1", "B", 1,
  "1", "C", 5,
  "2", "A", 1,
  "2", "B", 5
)

example2 %>% group_by(Group) %>%
  mutate(GroupStatus=ifelse(Value[Code=="C"]==5, 1, 0))
</code>```

This gives me an error: Error: Problem with mutate() column GroupStatus.
i GroupStatus = ifelse(Value[Code == "C"] == 5, 1, 0).
i GroupStatus must be size 2 or 1, not 0.
i The error occurred in group 2: Group = "2".

What I'd like is for "GroupStatus" in any group that is missing Code C to just be set to zero. Is that possible?

答:
Another possible solution, based on a nested ifelse:

library(dplyr)

example2 <- tibble::tribble(
  ~Group, ~Code, ~Value,
  "1", "A", 1,
  "1", "B", 1,
  "1", "C", 5,
  "2", "A", 1,
  "2", "B", 5
)

example2 %>%
  group_by(Group) %>%
  mutate(GroupStatus = ifelse("C" %in% Code,
     ifelse(Value[Code == "C"] == 5, 1, 0), 0)) %>%
  ungroup

#> # A tibble: 5 × 4
#>   Group Code  Value GroupStatus
#>   <chr> <chr> <dbl>       <dbl>
#> 1 1     A         1           1
#> 2 1     B         1           1
#> 3 1     C         5           1
#> 4 2     A         1           0
#> 5 2     B         5           0
```

Title: Ifelse with conditional on grouped data

Body:
This has got to be simple, but I'm stuck. I want to mutate some grouped data using a where statement within an ifelse statement. Here's an example that works:

example <- tibble::tribble(
  ~Group, ~Code, ~Value,
  "1", "A", 1,
  "1", "B", 1,
  "1", "C", 5,
  "2", "A", 1,
  "2", "B", 5,
  "2", "C", 2
)

example %>% group_by(Group) %>%
  mutate(GroupStatus=ifelse(Value[Code=="C"]==5, 1, 0))

This gives the desired result:

  Group Code  Value GroupStatus
  <chr> <chr> <dbl>       <dbl>
1 1     A         1           1
2 1     B         1           1
3 1     C         5           1
4 2     A         1           0
5 2     B         5           0
6 2     C         2           0

The problem is when one of the groups is missing Code C, as below:

example2 <- tibble::tribble(
  ~Group, ~Code, ~Value,
  "1", "A", 1,
  "1", "B", 1,
  "1", "C", 5,
  "2", "A", 1,
  "2", "B", 5
)

example2 %>% group_by(Group) %>%
  mutate(GroupStatus=ifelse(Value[Code=="C"]==5, 1, 0))

This gives me an error: Error: Problem with mutate() column GroupStatus.
i GroupStatus = ifelse(Value[Code == "C"] == 5, 1, 0).
i GroupStatus must be size 2 or 1, not 0.
i The error occurred in group 2: Group = "2".

What I'd like is for "GroupStatus" in any group that is missing Code C to just be set to zero. Is that possible?


问:
Android: Accessing a function within a thread and getting the result?
In my android service, I'm starting a new thread like this

```<code>    thread = new Thread(new Runnable() {
        public void run() {
            new myClassName(getApplicationContext());
        }
    });
    thread.start();
</code>```

The class is ran in a separate thread because it would otherwise block the service thread (causes timeout). That code is in the "onCreate" method, and is alive the whole time whilst the service is alive (unless it crashes, of course).

Now, I need to have a function in "myClassName" which returns a String. I've not actually created that function yet, but I'm trying to test it with a function which simply returns "hello", so let's call that function "helloFn".

```<code>    public String helloFn(String name) {
        return "hello "+name;
    }
</code>```

How can I call "helloFn" which is inside the thread I just created, from my service? Thanks!

答: Create a new class which implements Runnable, and call helloFn(name) on the instance of that class.

Body:
In my android service, I'm starting a new thread like this

    thread = new Thread(new Runnable() {
        public void run() {
            new myClassName(getApplicationContext());
        }
    });
    thread.start();

The class is ran in a separate thread because it would otherwise block the service thread (causes timeout). That code is in the "onCreate" method, and is alive the whole time whilst the service is alive (unless it crashes, of course).

Now, I need to have a function in "myClassName" which returns a String. I've not actually created that function yet, but I'm trying to test it with a function which simply returns "hello", so let's call that function "helloFn".

    public String helloFn(String name) {
        return "hello "+name;
    }

How can I call "helloFn" which is inside the thread I just created, from my service? Thanks!


问:
how to return bmp format for get Request?
@GetMapping(value = "/{id}", produces = MediaType.IMAGE_PNG_VALUE)
This have only 3 types: GIF, PNG, JPEG. For bmp returns just black pixels.
How to deal with it?</p>

答:
You need to specify media type for BMP images.
According to RFC standart, the media type for bmp images is "image/bmp"

RFC standart:

https://www.rfc-editor.org/rfc/rfc7903.html

https://www.iana.org/assignments/media-types/media-types.xhtml#image

MediaType class contain just a few string constants. You can extend it according to RFC. Also you can define any custom media type string in produces tag.

```<code>@GetMapping(
        value = "/{id}",
        produces = "image/bmp"
)
public @ResponseBody
byte[] getImage(@PathVariable("id") String id) throws IOException {

}
</code>```

Body:
You need to specify media type for BMP images.
According to RFC standart, the media type for bmp images is "image/bmp"

RFC standart:

https://www.rfc-editor.org/rfc/rfc7903.html

https://www.iana.org/assignments/media-types/media-types.xhtml#image

MediaType class contain just a few string constants. You can extend it according to RFC. Also you can define any custom media type string in produces tag.

@GetMapping(
        value = "/{id}",
        produces = "image/bmp"
)
public @ResponseBody
byte[] getImage(@PathVariable("id") String id) throws IOException {

}


问:
Update React component injected to DOM in Chrome Extension based on user navigation
I have a simple React component injected to the DOM as content script in my Chrome Extension, running on a website which is not mine.

I want to update (re-render) the component on every navigation (url change) made by the user on the website which my React app is injected to.

I figured React Router should be the best tool for this job.

However, it doesn't seem to work.
I found some related questions: this, this, this but none of the solutions work for me.

I tried to add a unique key to the Route, (like using useLocation or simply using location.href or even a Math.random() for the test) - but none of those make the component update.

The weird thing is that if I attach an onclick that changes a state to the div in my component, it does successfully makes the component re-render and update.

My content script looks like this:

```<code>import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const myDiv = document.createElement('div');
myDiv.id = 'my-id';
document.body.appendChild(myDiv);

ReactDOM.render(<App />, myDiv);
</code>```

My Routes (react-router v6):

```<code>import {
    BrowserRouter,
    Routes,
    Route,
    useParams,
    useLocation
} from "react-router-dom";

function App() {
    return (
        <BrowserRouter>
            <Routes>
                <Route path="/user/:id/" element={<MyComponent />} />
            </Routes>
        </BrowserRouter>
    );
}
</code>```

My component:

```<code>function MyComponent(props) {
    const { id } = useParams();

    React.useEffect(() => {
       // Some stuff
    }, [id])

    return <div> User {id}</div>
</code>```

My manifest.json scripts look like:

```<code>  "background": {
    "scripts": [
      "build/background.js"
    ]
  },
  "content_scripts": [
    {
      "matches": [
        "https://example-website.com/*"
      ],
      "js": [
        "build/content.js"
      ],
      "css": [
        "build/css/content.css"
      ]
    },
    {
      "matches": [
        "https://example-website.com/*"
      ],
      "js": [
        "build/reactApp.js"
      ],
      "css": [
        "build/css/content.css"
      ]
    }
  ],
</code>```

答:
I want to update (re-render) the component on every navigation (url change) made by the user on the website which my React app is injected to.

The answer to your question depends entirely on the precise definition of what "every navigation (url change)" means in terms of code. It sounds like you're not quite sure about this (but if you are, please update the question with this information).

When there is a page reload event to a matching URL, your app is already being injected again, so that's covered.

If the site is a single-page-application, and is modifying its content without a page reload (e.g. React), then it depends on what happens when the view data (and URL) changes.

There are some window events that you can listen for and re-render in response to: hashchange and popstate. The least performant solution is simply to poll: if no other option works, this is your last resort.

Here's how to change your content script:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const myDiv = document.createElement('div');
myDiv.id = 'my-id';
document.body.appendChild(myDiv);

const render = () => ReactDOM.render(<App />, myDiv);

render();

const handleLocationUpdates = () => {
  window.addEventListener("hashchange", render);
  window.addEventListener("popstate", render);

  // or, if neither of those work, you might have to poll:

  // const aDelayValueThatWorksForYou = 500;
  // setInterval(render, aDelayValueThatWorksForYou);
};

handleLocationUpdates();

```
<blockquote>
<p>Note: To get the ID, you're parsing a part of the URL pathname using the <code>useParams</code> hook from React Router. I've never tested re-rendering an app using React Router above the Router component itself. My guess is that it'll subscribe to changes on such a re-render, but I don't know about this behavior. If not, you'll need to manually parse the ID from <code>window.location.pathname</code> in your app rather than using the <code>useParams</code> hook.</p>
</blockquote>
<hr />
<h2>Edit</h2>
<p>Because you haven't shared the URL of the site that you are injecting your extension into (in order to reproduce the issue), I have created a self-contained example which you can run on a local web server to see working:</p>
<blockquote>
<p>Ref: MDN: <code>Proxy/handler.apply()</code></p>
</blockquote>
<p><code>example.html</code>:</p>
<pre class="lang-html prettyprint-override"><code><!doctype html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Example</title>

  <script type="module">
    // Imagine that this is the JS in the example website (that you don't control)
    const delay = (ms) => new Promise(res => setTimeout(res, ms));
    const updateUrl = (relativePath) => window.history.pushState({}, '', new URL(relativePath, window.location.href));

    await delay(1500);
    updateUrl('/user/2');

    await delay(1500);
    updateUrl('/about');

    await delay(1500);
    updateUrl('/user/3');

  </script>

  <!-- This examples uses UMD modules instead of ESM or bundling -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script><script src="https://unpkg.com/@babel/standalone@7.17.2/babel.min.js"></script>
  <script type="text/babel" data-type="module" data-presets="env,react">
    // This is your entire React app

    const {useEffect, useState} = React;

    function parseId () {
      const idRegex = /^\/user\/(?<id>[^?/#]+)/;
      const id = window.location.pathname.match(idRegex)?.groups?.id;
      return id;
    }

    function useId () {
      const [id, setId] = useState();

      useEffect(() => {
        const parsed = parseId();
        if (parsed !== id) setId(parsed);
      });

      return id;
    }

    function IDComponent () {
      const id = useId();

      useEffect(() => {
        if (!id) return; // No ID in current location
        console.log('New ID:', id);
      }, [id]);

      return id ?
        (<div>User ID: {id}</div>)
        : (<div>User ID not found</div>);
    }

    function App () {
      return (
        <div>
          <h1>Detecting ID changes...</h1>
          <IDComponent />
        </div>
      );
    }

    // The logic of the body of this function would be in your content script
    function main () {
      const reactRoot = document.body.appendChild(document.createElement('div'));
      const render = () => ReactDOM.render(<App />, reactRoot);

      const applyCallback = (object, method, callback) => {
        object[method] = new Proxy(object[method], {
          apply: (target, thisArg, args) => {
            callback();
            return target.apply(thisArg, args);
          },
        });
      };

      const handleLocationUpdates = (usePolling) => {
        if (usePolling) {
          const aDelayValueThatWorksForYou = 500;
          setInterval(render, aDelayValueThatWorksForYou);
          return;
        }
        window.addEventListener('hashchange', render);
        window.addEventListener('popstate', render);
        applyCallback(window.history, 'pushState', render);
        applyCallback(window.history, 'replaceState', render);
      };

      render();

      // If the event listeners and proxy interceptor don't handle the
      // "navigation" events created by the page you're injecting into,
      // then you'll need to set the polling option to `true`
      handleLocationUpdates(false);
    }

    main();
  </script>
</head>

<body></body>
</html>

</code>```

Body:
I have a simple React component injected to the DOM as content script in my Chrome Extension, running on a website which is not mine.

I want to update (re-render) the component on every navigation (url change) made by the user on the website which my React app is injected to.

I figured React Router should be the best tool for this job.

However, it doesn't seem to work.
I found some related questions: this, this, this but none of the solutions work for me.

I tried to add a unique key to the Route, (like using useLocation or simply using location.href or even a Math.random() for the test) - but none of those make the component update.

The weird thing is that if I attach an onclick that changes a state to the div in my component, it does successfully makes the component re-render and update.

My content script looks like this:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const myDiv = document.createElement('div');
myDiv.id = 'my-id';
document.body.appendChild(myDiv);

ReactDOM.render(<App />, myDiv);

My Routes (react-router v6):

import {
    BrowserRouter,
    Routes,
    Route,
    useParams,
    useLocation
} from "react-router-dom";

function App() {
    return (
        <BrowserRouter>
            <Routes>
                <Route path="/user/:id/" element={<MyComponent />} />
            </Routes>
        </BrowserRouter>
    );
}

My component:

function MyComponent(props) {
    const { id } = useParams();

    React.useEffect(() => {
       // Some stuff
    }, [id])

    return
 User {id}

My manifest.json scripts look like:

  "background": {
    "scripts": [
      "build/background.js"
    ]
  },
  "content_scripts": [
    {
      "matches": [
        "https://example-website.com/*"
      ],
      "js": [
        "build/content.js"
      ],
      "css": [
        "build/css/content.css"
      ]
    },
    {
      "matches": [
        "https://example-website.com/*"
      ],
      "js": [
        "build/reactApp.js"
      ],
      "css": [
        "build/css/content.css"
      ]
    }
  ],

Body:
I want to update (re-render) the component on every navigation (url change) made by the user on the website which my React app is injected to.

The answer to your question depends entirely on the precise definition of what "every navigation (url change)" means in terms of code. It sounds like you're not quite sure about this (but if you are, please update the question with this information).

When there is a page reload event to a matching URL, your app is already being injected again, so that's covered.

If the site is a single-page-application, and is modifying its content without a page reload (e.g. React), then it depends on what happens when the view data (and URL) changes.

There are some window events that you can listen for and re-render in response to: hashchange and popstate. The least performant solution is simply to poll: if no other option works, this is your last resort.

Here's how to change your content script:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const myDiv = document.createElement('div');
myDiv.id = 'my-id';
document.body.appendChild(myDiv);

const render = () => ReactDOM.render(<App />, myDiv);

render();

const handleLocationUpdates = () => {
  window.addEventListener("hashchange", render);
  window.addEventListener("popstate", render);

  // or, if neither of those work, you might have to poll:

  // const aDelayValueThatWorksForYou = 500;
  // setInterval(render, aDelayValueThatWorksForYou);
};

handleLocationUpdates();

Note: To get the ID, you're parsing a part of the URL pathname using the useParams hook from React Router. I've never tested re-rendering an app using React Router above the Router component itself. My guess is that it'll subscribe to changes on such a re-render, but I don't know about this behavior. If not, you'll need to manually parse the ID from window.location.pathname in your app rather than using the useParams hook.

Edit

Because you haven't shared the URL of the site that you are injecting your extension into (in order to reproduce the issue), I have created a self-contained example which you can run on a local web server to see working:

Ref: MDN: Proxy/handler.apply()

example.html:

<!doctype html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Example</title>

  <script type="module">
    // Imagine that this is the JS in the example website (that you don't control)
    const delay = (ms) => new Promise(res => setTimeout(res, ms));
    const updateUrl = (relativePath) => window.history.pushState({}, '', new URL(relativePath, window.location.href));

    await delay(1500);
    updateUrl('/user/2');

    await delay(1500);
    updateUrl('/about');

    await delay(1500);
    updateUrl('/user/3');

  </script>

  <!-- This examples uses UMD modules instead of ESM or bundling -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script><script src="https://unpkg.com/@babel/standalone@7.17.2/babel.min.js"></script>
  <script type="text/babel" data-type="module" data-presets="env,react">
    // This is your entire React app

    const {useEffect, useState} = React;

    function parseId () {
      const idRegex = /^\/user\/(?<id>[^?/#]+)/;
      const id = window.location.pathname.match(idRegex)?.groups?.id;
      return id;
    }

    function useId () {
      const [id, setId] = useState();

      useEffect(() => {
        const parsed = parseId();
        if (parsed !== id) setId(parsed);
      });

      return id;
    }

    function IDComponent () {
      const id = useId();

      useEffect(() => {
        if (!id) return; // No ID in current location
        console.log('New ID:', id);
      }, [id]);

      return id ?
        (<div>User ID: {id}</div>)
        : (<div>User ID not found</div>);
    }

    function App () {
      return (
        <div>
          <h1>Detecting ID changes...</h1>
          <IDComponent />
        </div>
      );
    }

    // The logic of the body of this function would be in your content script
    function main () {
      const reactRoot = document.body.appendChild(document.createElement('div'));
      const render = () => ReactDOM.render(<App />, reactRoot);

      const applyCallback = (object, method, callback) => {
        object[method] = new Proxy(object[method], {
          apply: (target, thisArg, args) => {
            callback();
            return target.apply(thisArg, args);
          },
        });
      };

      const handleLocationUpdates = (usePolling) => {
        if (usePolling) {
          const aDelayValueThatWorksForYou = 500;
          setInterval(render, aDelayValueThatWorksForYou);
          return;
        }
        window.addEventListener('hashchange', render);
        window.addEventListener('popstate', render);
        applyCallback(window.history, 'pushState', render);
        applyCallback(window.history, 'replaceState', render);
      };

      render();

      // If the event listeners and proxy interceptor don't handle the
      // "navigation" events created by the page you're injecting into,
      // then you'll need to set the polling option to `true`
      handleLocationUpdates(false);
    }

    main();
  </script>
</head>

<body></body>
</html>


问:
How to make tailwind rows equal height?
I've got a table pretty much laid out as I want, but one row in the table will have text of different lengths.

There's one row beneath that, that I'd like to push to the bottom of the parent container, making the variable row above the same height.

https://codepen.io/chris__sev/pen/mdyoGar

Any pointers?

Basic

15 accounts

1 product

Cannot change plans

                <button class="bg-indigo-600 text-xl text-white py-2 px-6 rounded hover:bg-indigo-700 transition-colors duration-300">Get Started</button>

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam libero nulla, egestas vel vehicula ut, pretium vel erat. Quisque quam elit, fermentum lacinia aliquam sit amet, lobortis et ex. Pellentesque mauris sapien, posuere et nisl
                a, aliquam pharetra nulla. Morbi nec ex fermentum, euismod dolor in, aliquam ipsum. Morbi ligula libero, tincidunt nec lacus eu, interdum semper tellus. Duis leo eros, facilisis id rhoncus et, tempor eu nisl. Proin ullamcorper ipsum vel
                lorem luctus viverra. Phasellus sit amet arcu nec nunc sollicitudin aliquet et in nulla. Nulla mollis ullamcorper mauris, sed suscipit urna commodo mattis. Cras tortor ex, porta quis varius sed, porta condimentum dolor. Vestibulum sed
                nibh sed ex maximus posuere. Vivamus a erat eget neque laoreet imperdiet id ut purus. Curabitur id arcu nisi. Aliquam dui orci, porta nec blandit eget, semper eget leo.

$20 /month

Pro

5 accounts

25 products

Customer can change plan

                <button class="bg-indigo-600 text-xl text-white py-2 px-6 rounded hover:bg-indigo-700 transition-colors duration-300">Get Started</button>

Lorem ipsum dolor sit amet, consectetur adipiscing elit. .

$50 /month

```

答:
Got it eventually:

    @foreach ($plans as $plan)

{{ $plan->name }}

            @foreach($plan->featureSpecs as $featureSpec)

                    {{ $featureSpec->spec }}

            @endforeach

{{ $plan->description }}

                    {{$plan->price_amount}} /{{$plan->price_frequency}}

                    <button class="bg-indigo-600 text-xl text-white py-2 px-6 rounded hover:bg-indigo-700 transition-colors duration-300">Get Started</button>

        @endforeach

```

Title: How to make tailwind rows equal height?

Body:
Got it eventually:

<div class="w-full bg-blue pt-8">
    <div class="flex flex-col sm:flex-row justify-center mx-4 md:mx-0 lg:-mx-2 flex-wrap">
    @foreach ($plans as $plan)
        <div class="flex-1 lg:flex-initial lg:w-1/3 rounded-lg bg-white mt-4 flex flex-col sm:mx-2 md:mx-1 lg:mx-2">
            <div class="p-8 text-3xl font-bold text-center">{{ $plan->name }}</div>
            <div class="border-0 border-grey-light border-t border-solid text-sm">
            @foreach($plan->featureSpecs as $featureSpec)
                <div class="text-center border-0 border-grey-light border-b border-solid py-4">
                    {{ $featureSpec->spec }}
                </div>
            @endforeach
                <div class="p-6 md:py-8">
                    <p class="text-gray-600">{{ $plan->description }}</p>
                </div>
            </div>
            <div class="text-center pt-8 mb-8 mt-auto">
                <div class="pricing-amount bg-indigo-100 p-6 transition-colors duration-300 text-center mt-auto">
                    <span class="text-4xl font-semibold">{{$plan->price_amount}}</span> /{{$plan->price_frequency}}
                </div>
                <div class="mt-6 py-4 flex-1">
                    <button class="bg-indigo-600 text-xl text-white py-2 px-6 rounded hover:bg-indigo-700 transition-colors duration-300">Get Started</button>
                </div>
            </div>
        </div>
        @endforeach
    </div>
</div>


问:
How to get a list of every video from a channel using the YouTube API?
I have created a program where the user enters a YouTube channel name and it does a search and returns and displays YouTube channels with similar names based on their relevancy. Then the user picks what channel that they want and the program saves the ChannelID. Then I want to get a list of all of the channels videos so i can display a random video to the user from that channel. The issue is that the old method of using a channels "Uploads" playlist no longer works as I believe that channels don't have this playlist anymore by default. The code I am currently using to get the channels videos has its own issues.

```<code>   SearchListResponse response;
                var search = service.Search.List(repeatable);
                search.Type = "video";
                search.ChannelId = Session["ChannelID"].ToString();
                search.MaxResults = 500;

                do
                {
                    response = search.ExecuteAsync().Result;

                    foreach (SearchResult sr in response.Items)
                    {
                        videoIds.Add(sr.Id.VideoId);
                    }

                    search.PageToken = response.NextPageToken;

                } while (response.NextPageToken != "");
</code>```

The issue with this method is that it uses 100 quota per search but only returns 50 videos at a time. And if a user has 1000 videos it would take 20 searches aka 2000 quota (20% of daily quota) just to get the channels VideoID's.

I believe there are two ways to fix this:

From a single request, get a random video from the channel

OR

Get all VideoIDs from the channel and then pick a random one.

答:
Channel has a property ChannelContentDetails which you can access RelatedPlaylists from. Inside related playlists, you can pull the Playlist "ID" for the Channels Uploads. then you can grab the PlaylistItems thus videoID's and you could randomly go through that with a much lower quota cost. looking through the documentation it doesn't appear to be depreciated so this could be a workaround.

I apologize for not being able to format a script for you, but I have never used Youtube's API and it probably wouldn't compile anyway.

Body:
I have created a program where the user enters a YouTube channel name and it does a search and returns and displays YouTube channels with similar names based on their relevancy. Then the user picks what channel that they want and the program saves the ChannelID. Then I want to get a list of all of the channels videos so i can display a random video to the user from that channel. The issue is that the old method of using a channels "Uploads" playlist no longer works as I believe that channels don't have this playlist anymore by default. The code I am currently using to get the channels videos has its own issues.

   SearchListResponse response;
                var search = service.Search.List(repeatable);
                search.Type = "video";
                search.ChannelId = Session["ChannelID"].ToString();
                search.MaxResults = 500;

                do
                {
                    response = search.ExecuteAsync().Result;

                    foreach (SearchResult sr in response.Items)
                    {
                        videoIds.Add(sr.Id.VideoId);
                    }

                    search.PageToken = response.NextPageToken;

                } while (response.NextPageToken != "");

The issue with this method is that it uses 100 quota per search but only returns 50 videos at a time. And if a user has 1000 videos it would take 20 searches aka 2000 quota (20% of daily quota) just to get the channels VideoID's.

I believe there are two ways to fix this:

From a single request, get a random video from the channel

OR

Get all VideoIDs from the channel and then pick a random one.


问:
How to access last modified date/time for file on exFAT with 10 ms resolution?
From my research, exFAT has a 2-second resolution for the last modified date/time of files. Also, there is another field for the file storing the offset to the last modified date/time with a 10-millisecond resolution. Am I correct about this?

When I display file properties in Windows Explorer, or use QFileInfo::lastModified() (from the Qt framework) to analyze the file, both methods only display the last modified date/time down to a 2-second resolution.

If I am correct about the above, how do I access the more precise timestamp using Qt, or the Win32 API, or Windows Explorer?

答:
According to FAT32 and exFAT, which file timestamps are supported?:

Timestamp granularity of 10 ms for Create and Modified times (down from 2 s of FAT, but not as fine as NTFS's 100 ns)

Timestamp granularity for Last Access time to double seconds (FAT had date only).

Do you HAVE to use lastModified? Does Qt expose two other fields?

Note: that "double seconds" granularity matches your observed "divisible by 2000 msecs"