问:
Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton Instrumentation Test
The app works fine if I normally run the app but when I try to test it shows error here is the full log of the error.

java.lang.RuntimeException: android.view.InflateException: Binary XML file line #14: Binary XML file line #14: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton
  at androidx.test.runner.MonitoringInstrumentation.runOnMainSync(MonitoringInstrumentation.java:441)
  at androidx.test.core.app.ActivityScenario.onActivity(ActivityScenario.java:564)
  at androidx.fragment.app.testing.FragmentScenario.internalLaunch(FragmentScenario.java:300)
  at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:282)
  at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:262)
  at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:244)
  at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:228)
  at com.medium.todoapp.HomeFragmentInstrumentedTest.testRecyclerView(HomeFragmentInstrumentedTest.kt:14)
  at java.lang.reflect.Method.invoke(Native Method)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
  at org.junit.runners.Suite.runChild(Suite.java:128)
  at org.junit.runners.Suite.runChild(Suite.java:27)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
  at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
  at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
  at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
  Caused by: android.view.InflateException: Binary XML file line #14: Binary XML file line #14: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton
  Caused by: android.view.InflateException: Binary XML file line #14: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton
  Caused by: java.lang.reflect.InvocationTargetException
  at java.lang.reflect.Constructor.newInstance0(Native Method)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
  at android.view.LayoutInflater.createView(LayoutInflater.java:645)
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787)
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
  at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
  at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
  at com.medium.todoapp.HomeFragment.onCreateView(HomeFragment.kt:16)
  at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
  at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
  at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
  at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
  at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
  at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
  at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
  at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
  at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
  at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
  at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
  at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:297)
  at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:317)
  at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:301)
  at androidx.test.core.app.ActivityScenario.lambda$onActivity$2$ActivityScenario(ActivityScenario.java:551)
  at androidx.test.core.app.ActivityScenario$$Lambda$4.run(Unknown Source)
  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
  at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1950)
  at android.os.Handler.handleCallback(Handler.java:751)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:154)
  at android.app.ActivityThread.main(ActivityThread.java:6119)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
  Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).
  at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:243)
  at com.google.android.material.internal.ThemeEnforcement.checkAppCompatTheme(ThemeEnforcement.java:213)
  at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:148)
  at com.google.android.material.internal.ThemeEnforcement.obtainStyledAttributes(ThemeEnforcement.java:76)
  at com.google.android.material.floatingactionbutton.FloatingActionButton.(FloatingActionButton.java:211)
  at com.google.android.material.floatingactionbutton.FloatingActionButton.(FloatingActionButton.java:200)
  ... 36 more
  Test running failed: Instrumentation run failed due to 'Process crashed.'

Here is my XML file

```<code><?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="adapter"
            type="com.medium.todoapp.adapters.ToDoListAdapter" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".HomeFragment">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:adapter="@{adapter}"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            tools:listitem="@layout/item_todo" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
</code>```

Here is my TestFile

```<code>@RunWith(AndroidJUnit4::class)
class HomeFragmentInstrumentedTest {

    @Test
    fun testRecyclerView() {
        val homeScenario = launchInContainer(HomeFragment::class.java)
        homeScenario.onFragment {
            Assert.assertNotEquals(it.view?.findViewById(R.id.recyclerView), null)
        }
    }

    @Test
    fun testAddTodoButton() {
        val homeScenario = launchInContainer(HomeFragment::class.java)
        homeScenario.onFragment {
            Assert.assertNotEquals(it.view?.findViewById(R.id.addToDo), null)
        }
    }
}
</code>```

```<code>override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        bindings = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
        bindings?.apply {
            this.adapter = ToDoListAdapter()
        }
        return bindings?.root
    }
</code>```

Build.gradle

```<code>apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"

    defaultConfig {
        applicationId "com.medium.todoapp"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    dataBinding {
        enabled = true
    }

    kapt {
        generateStubs = true
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

    // AndroidX
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'

    // Test
    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    // Tests
    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    androidTestImplementation 'androidx.test:rules:1.2.0'

    // Mockito
    androidTestImplementation "org.mockito:mockito-core:2.24.5"
    androidTestImplementation "org.mockito:mockito-android:2.24.5"

    // FragmentScenario
    debugImplementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.72"
    debugImplementation ("androidx.fragment:fragment-testing:1.2.4") {
        // required, while there is no version 1.2.0 yet.
        exclude group: "androidx.test", module: "core"
    }

    // Navigation Architecture Component
    implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
    implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
}

</code>```

答:
Try to replace launchInContainer(HomeFragment::class.java) with:

```<code>launchInContainer(HomeFragment::class.java, null, R.style.AppTheme, null)
</code>```

R.style.AppTheme has to inherit from Theme.AppCompat

Body:
The app works fine if I normally run the app but when I try to test it shows error here is the full log of the error.

java.lang.RuntimeException: android.view.InflateException: Binary XML file line #14: Binary XML file line #14: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton
  at androidx.test.runner.MonitoringInstrumentation.runOnMainSync(MonitoringInstrumentation.java:441)
  at androidx.test.core.app.ActivityScenario.onActivity(ActivityScenario.java:564)
  at androidx.fragment.app.testing.FragmentScenario.internalLaunch(FragmentScenario.java:300)
  at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:282)
  at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:262)
  at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:244)
  at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:228)
  at com.medium.todoapp.HomeFragmentInstrumentedTest.testRecyclerView(HomeFragmentInstrumentedTest.kt:14)
  at java.lang.reflect.Method.invoke(Native Method)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
  at org.junit.runners.Suite.runChild(Suite.java:128)
  at org.junit.runners.Suite.runChild(Suite.java:27)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
  at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
  at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
  at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
  Caused by: android.view.InflateException: Binary XML file line #14: Binary XML file line #14: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton
  Caused by: android.view.InflateException: Binary XML file line #14: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton
  Caused by: java.lang.reflect.InvocationTargetException
  at java.lang.reflect.Constructor.newInstance0(Native Method)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
  at android.view.LayoutInflater.createView(LayoutInflater.java:645)
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787)
  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
  at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
  at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
  at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
  at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
  at com.medium.todoapp.HomeFragment.onCreateView(HomeFragment.kt:16)
  at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
  at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
  at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
  at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
  at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
  at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
  at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
  at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
  at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
  at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
  at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
  at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:297)
  at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:317)
  at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:301)
  at androidx.test.core.app.ActivityScenario.lambda$onActivity$2$ActivityScenario(ActivityScenario.java:551)
  at androidx.test.core.app.ActivityScenario$$Lambda$4.run(Unknown Source)
  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
  at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1950)
  at android.os.Handler.handleCallback(Handler.java:751)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:154)
  at android.app.ActivityThread.main(ActivityThread.java:6119)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
  Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).
  at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:243)
  at com.google.android.material.internal.ThemeEnforcement.checkAppCompatTheme(ThemeEnforcement.java:213)
  at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:148)
  at com.google.android.material.internal.ThemeEnforcement.obtainStyledAttributes(ThemeEnforcement.java:76)
  at com.google.android.material.floatingactionbutton.FloatingActionButton.(FloatingActionButton.java:211)
  at com.google.android.material.floatingactionbutton.FloatingActionButton.(FloatingActionButton.java:200)
  ... 36 more
  Test running failed: Instrumentation run failed due to 'Process crashed.'

Here is my XML file

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="adapter"
            type="com.medium.todoapp.adapters.ToDoListAdapter" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".HomeFragment">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:adapter="@{adapter}"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            tools:listitem="@layout/item_todo" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Here is my TestFile

@RunWith(AndroidJUnit4::class)
class HomeFragmentInstrumentedTest {

    @Test
    fun testRecyclerView() {
        val homeScenario = launchInContainer(HomeFragment::class.java)
        homeScenario.onFragment {
            Assert.assertNotEquals(it.view?.findViewById(R.id.recyclerView), null)
        }
    }

    @Test
    fun testAddTodoButton() {
        val homeScenario = launchInContainer(HomeFragment::class.java)
        homeScenario.onFragment {
            Assert.assertNotEquals(it.view?.findViewById(R.id.addToDo), null)
        }
    }
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        bindings = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
        bindings?.apply {
            this.adapter = ToDoListAdapter()
        }
        return bindings?.root
    }

Build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"

    defaultConfig {
        applicationId "com.medium.todoapp"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    dataBinding {
        enabled = true
    }

    kapt {
        generateStubs = true
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

    // AndroidX
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'

    // Test
    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    // Tests
    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    androidTestImplementation 'androidx.test:rules:1.2.0'

    // Mockito
    androidTestImplementation "org.mockito:mockito-core:2.24.5"
    androidTestImplementation "org.mockito:mockito-android:2.24.5"

    // FragmentScenario
    debugImplementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.72"
    debugImplementation ("androidx.fragment:fragment-testing:1.2.4") {
        // required, while there is no version 1.2.0 yet.
        exclude group: "androidx.test", module: "core"
    }

    // Navigation Architecture Component
    implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
    implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
}

Body:
Try to replace launchInContainer(HomeFragment::class.java) with:

launchInContainer(HomeFragment::class.java, null, R.style.AppTheme, null)

R.style.AppTheme has to inherit from Theme.AppCompat


来源: stackexchange

问:
Convert timestamp to datetime changing format
I have a timestamp 2020-01-08T16:06:00+00:00 format value, I want to convert it to datetime format as 2020-01-08 16:06:00.

I have tried to convert to datetime, but getting error says:

failed when converting date and/or time from character string.

I would like to convert timestamp to datetime.

答:
If you're simply interested in dropping the the offset, and not converting the timestamp to local time (as the offset sets the timestamp at UTC), try this:

DECLARE @timestamp AS DATETIMEOFFSET = '2020-01-08T16:06:00+00:00' ;
SELECT  CAST ( @timestamp AS DATETIME2(0) ) AS formatted_timestamp ;
```

(I've assumed the data type for your timestamp is DATETIMEOFFSET. But this could also work if the data type is DATETIME or DATETIME2.)

ContentLicense: CC BY-SA 4.0

Body:
If you're simply interested in dropping the the offset, and not converting the timestamp to local time (as the offset sets the timestamp at UTC), try this:

DECLARE @timestamp AS DATETIMEOFFSET = '2020-01-08T16:06:00+00:00' ;
SELECT  CAST ( @timestamp AS DATETIME2(0) ) AS formatted_timestamp ;

(I've assumed the data type for your timestamp is DATETIMEOFFSET. But this could also work if the data type is DATETIME or DATETIME2.)


问:
gradient property in img tag
I am trying to gradient my image but it never shows

.asdf img  {
 background: rgb(2,0,36);
background: linear-gradient(0deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%);
            }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="asdf text-center tx-white">

  <img style="height: 200px;" class="w-100 shadow-sm bd" src="{{url($xd->banner)}}"alt="">

</div></code>```

what is the correct way to show the gradient on the image?

答: You have to set width and height property on img's parent (div), to extend image size and cover it with background. Or do it with image.</p>

Title: gradient property in img tag

Body:
I am trying to gradient my image but it never shows

.asdf img  {
 background: rgb(2,0,36);
background: linear-gradient(0deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%);
            }

  banner)}}"alt="">

what is the correct way to show the gradient on the image?


问:
Best way to group filename based on filename in Bash?
I have a folder with the following files:

```<code>DA-001-car.jpg
DA-001-dog.jpg
DA-001-coffee.jpg
DA-002-house.jpg
DA-003-coffee.jpg
DA-003-cat.jpg
...
</code>```

I want to generate this (CSV) output:

```<code>SKU, IMAGE
DA-001, "DA-001-car.jpg, DA-001-dog.jpg, DA-001-coffee.jpg"
DA-002, "DA-001-house.jpg"
DA-003, "DA-001-coffee.jpg, DA-001-cat.jpg"
</code>```

I tried to program this in Bash:

```<code>#!/bin/bash
echo "SKU, FILE" >> tmp.csv
for file in /home/calvin/test/*.jpg
do
    SKU_NAME="${file##*/}"
    echo ${SKU_NAME:0:6}, \"inner for-loop?, ?, ?\" >> tmp.csv
done
uniq tmp.csv output.csv
</code>```

As you can see I'm a noob as for programming :)
Please help me out, thanks in advance!

答:
This will do the trick. This requires GNU awk to output in ascending order. If you don't care about the order, you can use any old awk and remove the PROCINFO line

```<code>#!/bin/bash

awk -F- '
  BEGIN{
    print "SKU, IMAGE"
  }
  {
    sep=!a[$2]?"":", "
    a[$2]=a[$2] sep $0
  }
  END{
    PROCINFO["sorted_in"] = "@ind_str_asc" # GNU only feature
    for(i in a){print "DA-" i ", " "\"" a[i] "\""}
  }' <(find /home/calvin/test -type f -name "*.jpg" -printf "%f\n") > ./tmp.csv
</code>```

Example Output

```<code>$ cat ./tmp.csv
SKU, IMAGE
DA-001, "DA-001-coffee.jpg, DA-001-car.jpg, DA-001-dog.jpg"
DA-002, "DA-002-house.jpg"
DA-003, "DA-003-coffee.jpg, DA-003-cat.jpg"
</code>```

Body:
I have a folder with the following files:

DA-001-car.jpg
DA-001-dog.jpg
DA-001-coffee.jpg
DA-002-house.jpg
DA-003-coffee.jpg
DA-003-cat.jpg
...

I want to generate this (CSV) output:

SKU, IMAGE
DA-001, "DA-001-car.jpg, DA-001-dog.jpg, DA-001-coffee.jpg"
DA-002, "DA-001-house.jpg"
DA-003, "DA-001-coffee.jpg, DA-001-cat.jpg"

I tried to program this in Bash:

#!/bin/bash
echo "SKU, FILE" >> tmp.csv
for file in /home/calvin/test/*.jpg
do
    SKU_NAME="${file##*/}"
    echo ${SKU_NAME:0:6}, \"inner for-loop?, ?, ?\" >> tmp.csv
done
uniq tmp.csv output.csv

As you can see I'm a noob as for programming :)
Please help me out, thanks in advance!

Body:
This will do the trick. This requires GNU awk to output in ascending order. If you don't care about the order, you can use any old awk and remove the PROCINFO line

#!/bin/bash

awk -F- '
  BEGIN{
    print "SKU, IMAGE"
  }
  {
    sep=!a[$2]?"":", "
    a[$2]=a[$2] sep $0
  }
  END{
    PROCINFO["sorted_in"] = "@ind_str_asc" # GNU only feature
    for(i in a){print "DA-" i ", " "\"" a[i] "\""}
  }' <(find /home/calvin/test -type f -name "*.jpg" -printf "%f\n") > ./tmp.csv

Example Output

$ cat ./tmp.csv
SKU, IMAGE
DA-001, "DA-001-coffee.jpg, DA-001-car.jpg, DA-001-dog.jpg"
DA-002, "DA-002-house.jpg"
DA-003, "DA-003-coffee.jpg, DA-003-cat.jpg"


问:
what's wrong with my VHDL sine function gen?
```<code>library IEEE;
use IEEE.MATH_REAL.ALL;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;

entity SineGen is
    Port (clock             : in  std_logic;
          dac_ab_vpp        : in  integer range 0 to 4095;
          dac_cd_vpp        : in  integer range 0 to 4095;
          sine_dac_ab       : out std_logic_vector(11 downto 0);
          sine_dac_cd       : out std_logic_vector(11 downto 0));
end SineGen;

architecture Behavioral of SineGen is

subtype slv is std_logic_vector(11 downto 0);

begin

        process(clock)
            variable count       : integer range 0 to 255  := 0;
            variable temp_dac_ab : integer range 0 to 4095 := 0;
            variable temp_dac_cd : integer range 0 to 4095 := 0;

        begin
            if rising_edge(clock) then
</code>```

I tried everything and it comes down to that the next two lines makes the output always zero, and I don't understand why. It should've been an output with a sine function. (count is the 256 samples per period. n is the number of bits.) Are the following in valid format?

```<code>                -- A*sin (2PI/2^n * count)
                temp_dac_ab := dac_ab_vpp * integer(round(sin(real(count * integer(math_2_pi/real(256))))));
                temp_dac_cd := dac_cd_vpp * integer(round(sin(real(count * integer(math_2_pi/real(256))))));

                if count < 256 then
                    count := count + 1;
                else
                    count := 0;
                end if;

                sine_dac_ab <= conv_std_logic_vector(temp_dac_ab, slv'length);
                sine_dac_cd <= conv_std_logic_vector(temp_dac_cd, slv'length);

            end if;

        end process;
end Behavioral;
</code>```

答:
In addition to what has been pointed out by @brianreavis, you don't want to convert the fraction math_2_pi/real(256) to an integer, since that will always be 0. So:

```<code>temp_dac_ab := integer(round(dac_ab_vpp * sin(real(count) * math_2_pi/real(256))));
temp_dac_cd := integer(round(dac_cd_vpp * sin(real(count) * math_2_pi/real(256))));
</code>```

ContentLicense: CC BY-SA 3.0

Body:
library IEEE;
use IEEE.MATH_REAL.ALL;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;

entity SineGen is
    Port (clock             : in  std_logic;
          dac_ab_vpp        : in  integer range 0 to 4095;
          dac_cd_vpp        : in  integer range 0 to 4095;
          sine_dac_ab       : out std_logic_vector(11 downto 0);
          sine_dac_cd       : out std_logic_vector(11 downto 0));
end SineGen;

architecture Behavioral of SineGen is

subtype slv is std_logic_vector(11 downto 0);

begin

        process(clock)
            variable count       : integer range 0 to 255  := 0;
            variable temp_dac_ab : integer range 0 to 4095 := 0;
            variable temp_dac_cd : integer range 0 to 4095 := 0;

        begin
            if rising_edge(clock) then

I tried everything and it comes down to that the next two lines makes the output always zero, and I don't understand why. It should've been an output with a sine function. (count is the 256 samples per period. n is the number of bits.) Are the following in valid format?

                -- A*sin (2PI/2^n * count)
                temp_dac_ab := dac_ab_vpp * integer(round(sin(real(count * integer(math_2_pi/real(256))))));
                temp_dac_cd := dac_cd_vpp * integer(round(sin(real(count * integer(math_2_pi/real(256))))));

                if count < 256 then
                    count := count + 1;
                else
                    count := 0;
                end if;

                sine_dac_ab <= conv_std_logic_vector(temp_dac_ab, slv'length);
                sine_dac_cd <= conv_std_logic_vector(temp_dac_cd, slv'length);

            end if;

        end process;
end Behavioral;

Body:
In addition to what has been pointed out by @brianreavis, you don't want to convert the fraction math_2_pi/real(256) to an integer, since that will always be 0. So:

temp_dac_ab := integer(round(dac_ab_vpp * sin(real(count) * math_2_pi/real(256))));
temp_dac_cd := integer(round(dac_cd_vpp * sin(real(count) * math_2_pi/real(256))));


问:
Android: no start destination defined via app:startDestination for x.x.x:id/nav_graph
In the nav_graph even though I have used, I get warning

project level gradle:

```<code>// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.3.72'
    repositories {
        google()
        jcenter()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        def nav_version = "2.3.0-beta01"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

allprojects {
    repositories {
        google()
        jcenter()

    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
</code>```

app level gradle:

```<code>apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "androidx.navigation.safeargs.kotlin"

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.demo.sample"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    viewBinding {
        enabled = true
    }

}

dependencies {
    def nav_version = "2.3.0-beta01"
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    // JetPack Navigation
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
    implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

}
</code>```

MainActivity.kt

```<code>class MainActivity : AppCompatActivity() {

    //Binding reference
    private lateinit var binding : ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initOnCreate()
    }

    /** Init OnCreate **/
    private fun initOnCreate() {
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

    }
}
</code>```

nav_graph.xml

```<code><?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph">
    <fragment
        android:id="@+id/frgChooseRecipient2"
        android:name="com.demo.sample.fragments.FrgChooseRecipient"
        android:label="fragment_choose_recipient"
        tools:layout="@layout/fragment_choose_recipient" >
        <action
            android:id="@+id/action_frgChooseRecipient2_to_frgConfirmation"
            app:destination="@id/frgConfirmation" />
    </fragment>
    <fragment
        android:id="@+id/frgViewTransaction2"
        android:name="com.demo.sample.fragments.FrgViewTransaction"
        android:label="fragment_view_transaction"
        tools:layout="@layout/fragment_view_transaction" />
    <fragment
        android:id="@+id/frgConfirmation"
        android:name="com.demo.sample.fragments.FrgConfirmation"
        android:label="fragment_confirmation"
        tools:layout="@layout/fragment_confirmation" />
    <fragment
        android:id="@+id/frgMain2"
        android:name="com.demo.sample.fragments.FrgMain"
        android:label="fragment_main"
        tools:layout="@layout/fragment_main" >
        <action
            android:id="@+id/action_frgMain2_to_frgSpecifyAmount"
            app:destination="@id/frgSpecifyAmount" />
        <action
            android:id="@+id/action_frgMain2_to_frgViewTransaction2"
            app:destination="@id/frgViewTransaction2" />
        <action
            android:id="@+id/action_frgMain2_to_frgBalance2"
            app:destination="@id/frgBalance2" />
    </fragment>
    <fragment
        android:id="@+id/frgSpecifyAmount"
        android:name="com.demo.sample.fragments.FrgSpecifyAmount"
        android:label="fragment_specify_amount"
        tools:layout="@layout/fragment_specify_amount" >
        <action
            android:id="@+id/action_frgSpecifyAmount_to_frgChooseRecipient2"
            app:destination="@id/frgChooseRecipient2" />
    </fragment>
    <fragment
        android:id="@+id/frgBalance2"
        android:name="com.demo.sample.fragments.FrgBalance"
        android:label="fragment_balance"
        tools:layout="@layout/fragment_balance" />
</navigation>
</code>```

activity_main.xml

```<code><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.MainActivity">
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayo
</code>```

Error I am facing:

```<code>2020-05-30 23:19:57.486 17192-17192/com.demo.sample E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.demo.sample, PID: 17192
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.demo.sample/com.demo.sample.activities.MainActivity}: android.view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class androidx.fragment.app.FragmentContainerView
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: android.view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class androidx.fragment.app.FragmentContainerView
     Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class androidx.fragment.app.FragmentContainerView
     Caused by: java.lang.IllegalStateException: no start destination defined via app:startDestination for com.demo.sample:id/nav_graph
        at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:61)
        at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:28)
        at androidx.navigation.NavController.navigate(NavController.java:1036)
        at androidx.navigation.NavController.onGraphCreated(NavController.java:629)
        at androidx.navigation.NavController.setGraph(NavController.java:586)
        at androidx.navigation.NavController.setGraph(NavController.java:551)
        at androidx.navigation.NavController.setGraph(NavController.java:533)
        at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:238)
        at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684)
        at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175)
        at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
        at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
        at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:303)
        at androidx.fragment.app.FragmentContainerView.<init>(FragmentContainerView.java:166)
        at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:51)
        at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
        at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
        at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:335)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at com.demo.sample.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:44)
        at com.demo.sample.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:38)
2020-05-30 23:19:57.488 17192-17192/com.demo.sample E/AndroidRuntime:     at com.demo.sample.activities.MainActivity.initOnCreate(MainActivity.kt:21)
        at com.demo.sample.activities.MainActivity.onCreate(MainActivity.kt:16)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
</code>```

答:
The actual problem is

```<code>Caused by: java.lang.IllegalStateException: no start destination defined via app:startDestination for com.demo.sample:id/nav_graph
</code>```

meaning no app:startDestination attribute was set for the navigation tag in nav_graph.xml as mentioned in Designate a screen as the start destination and Connect destinations.

Body:
In the nav_graph even though I have used, I get warning

project level gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.3.72'
    repositories {
        google()
        jcenter()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        def nav_version = "2.3.0-beta01"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

allprojects {
    repositories {
        google()
        jcenter()

    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

app level gradle:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "androidx.navigation.safeargs.kotlin"

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.demo.sample"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    viewBinding {
        enabled = true
    }

}

dependencies {
    def nav_version = "2.3.0-beta01"
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    // JetPack Navigation
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
    implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    //Binding reference
    private lateinit var binding : ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initOnCreate()
    }

    /** Init OnCreate **/
    private fun initOnCreate() {
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

    }
}

nav_graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph">
    <fragment
        android:id="@+id/frgChooseRecipient2"
        android:name="com.demo.sample.fragments.FrgChooseRecipient"
        android:label="fragment_choose_recipient"
        tools:layout="@layout/fragment_choose_recipient" >
        <action
            android:id="@+id/action_frgChooseRecipient2_to_frgConfirmation"
            app:destination="@id/frgConfirmation" />
    </fragment>
    <fragment
        android:id="@+id/frgViewTransaction2"
        android:name="com.demo.sample.fragments.FrgViewTransaction"
        android:label="fragment_view_transaction"
        tools:layout="@layout/fragment_view_transaction" />
    <fragment
        android:id="@+id/frgConfirmation"
        android:name="com.demo.sample.fragments.FrgConfirmation"
        android:label="fragment_confirmation"
        tools:layout="@layout/fragment_confirmation" />
    <fragment
        android:id="@+id/frgMain2"
        android:name="com.demo.sample.fragments.FrgMain"
        android:label="fragment_main"
        tools:layout="@layout/fragment_main" >
        <action
            android:id="@+id/action_frgMain2_to_frgSpecifyAmount"
            app:destination="@id/frgSpecifyAmount" />
        <action
            android:id="@+id/action_frgMain2_to_frgViewTransaction2"
            app:destination="@id/frgViewTransaction2" />
        <action
            android:id="@+id/action_frgMain2_to_frgBalance2"
            app:destination="@id/frgBalance2" />
    </fragment>
    <fragment
        android:id="@+id/frgSpecifyAmount"
        android:name="com.demo.sample.fragments.FrgSpecifyAmount"
        android:label="fragment_specify_amount"
        tools:layout="@layout/fragment_specify_amount" >
        <action
            android:id="@+id/action_frgSpecifyAmount_to_frgChooseRecipient2"
            app:destination="@id/frgChooseRecipient2" />
    </fragment>
    <fragment
        android:id="@+id/frgBalance2"
        android:name="com.demo.sample.fragments.FrgBalance"
        android:label="fragment_balance"
        tools:layout="@layout/fragment_balance" />
</navigation>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.MainActivity">
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayo

Error I am facing:

2020-05-30 23:19:57.486 17192-17192/com.demo.sample E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.demo.sample, PID: 17192
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.demo.sample/com.demo.sample.activities.MainActivity}: android.view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class androidx.fragment.app.FragmentContainerView
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: android.view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class androidx.fragment.app.FragmentContainerView
     Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class androidx.fragment.app.FragmentContainerView
     Caused by: java.lang.IllegalStateException: no start destination defined via app:startDestination for com.demo.sample:id/nav_graph
        at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:61)
        at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:28)
        at androidx.navigation.NavController.navigate(NavController.java:1036)
        at androidx.navigation.NavController.onGraphCreated(NavController.java:629)
        at androidx.navigation.NavController.setGraph(NavController.java:586)
        at androidx.navigation.NavController.setGraph(NavController.java:551)
        at androidx.navigation.NavController.setGraph(NavController.java:533)
        at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:238)
        at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684)
        at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175)
        at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
        at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
        at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:303)
        at androidx.fragment.app.FragmentContainerView.<init>(FragmentContainerView.java:166)
        at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:51)
        at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
        at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
        at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:335)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at com.demo.sample.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:44)
        at com.demo.sample.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:38)
2020-05-30 23:19:57.488 17192-17192/com.demo.sample E/AndroidRuntime:     at com.demo.sample.activities.MainActivity.initOnCreate(MainActivity.kt:21)
        at com.demo.sample.activities.MainActivity.onCreate(MainActivity.kt:16)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Body:
The actual problem is

Caused by: java.lang.IllegalStateException: no start destination defined via app:startDestination for com.demo.sample:id/nav_graph

meaning no app:startDestination attribute was set for the navigation tag in nav_graph.xml as mentioned in Designate a screen as the start destination and Connect destinations.


问:
How do I SORT only the fields ($project) returned from Mongodb aggregation, while also using $match, $lookup AND $filter
I am VERY close to getting what I want out of this query... but now I want to sort on a notification field

NOTE: This is a refinement : I am now asking how to return SORT on notification fields, while my similar question asks how to return the data between a start and end date and my other similar question asks how to return only certain fields.

Register Schema

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const RegisterSchema = new Schema({
    userId: {type: Schema.Types.ObjectId, required: true},
    accessToken: {type:String, required: true, default: null},
})
module.exports = Register = mongoose.model( 'register', RegisterSchema)
```

<p>Here is some register data</p>

<pre class="lang-js prettyprint-override"><code>[
  {
    "_id": "Reg_1",
    "userId": "User_1",
    "accessToken": "a_1"
  },
  {
    "_id": "Reg_2",
    "userId": "User_2",
    "accessToken": "a_2"
  }
]
</code>```

The next document contains data that is related to the Register schema via the accessToken

Notifications

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const NotificationSchema = new Schema({
    accessToken: {type:String, required: true},
    summaryId: {type:Number, required: true},
    dateCreated: {type: Date, default: Date.now},

    // I don't want these returned in the final results
    dontWantThis1: {type:Number, required: true},
    dontWantThis2: {type:Number, required: true},
})
module.exports = Notification = mongoose.model( 'notification', NotificationSchema)
```

<p>Here is some notification data</p>

<pre class="lang-js prettyprint-override"><code>[{
    "_id": "N1_1",
    "accessToken": "a_1",
    "summaryId": 1111,
    "dontWantThis1": 61,
    "dontWantThis2": 62,
    "dateCreated": "2020-04-17T00:00:00.000+00:00" },
  {
    "_id": "N2_1",
    "accessToken": "a_2",
    "summaryId": 2221,
    "dontWantThis1": 71,
    "dontWantThis2": 72,
    "dateCreated": "2020-04-18T00:00:00.000+00:00" },
  {
    "_id": "N1_2",
    "accessToken": "a_1",
    "summaryId": 1112,
    "dontWantThis1": 611,
    "dontWantThis2": 622,
    "dateCreated": "2020-05-25T00:00:00.000+00:00" },
  {
    "_id": "N2_2",
    "accessToken": "a_2",
    "summaryId": 2222,
    "dontWantThis1": 711,
    "dontWantThis2": 722,
    "dateCreated": "2020-05-26T00:00:00.000+00:00" }
]
</code>```

Starting with this

This code returns everything I want... but doesn't sort the notifications by dateCreated showing the newest dates first.

        // make sure the input dates are REALLY date objects
        // I only want to see notifications for the month of May (in this example)
        var dateStart = new Date('2020-01-01T00:00:00.000+00:00');
        var dateEnd = new Date('2020-05-30T00:00:00.000+00:00');

        var match = {$match: { userId: mongoose.Types.ObjectId(userId) } };

        var lookup ={
            $lookup:
            {
                from: "my_Notifications",
                localField: "accessToken",
                foreignField: "accessToken",
                as: "notifications"
            }
        };

        var dateCondition = { $and: [
            { $gte: [ "$$item.dateCreated", dateStart ] },
            { $lte: [ "$$item.dateCreated", dateEnd ] }
          ]}

        var project = {
            $project: {
                notifications: {
                    $filter: {
                    input: "$notifications",
                    as: "item",
                    cond: dateCondition
                    } } }
        };

        var project2 = {
            $project: {
                "_id": 1,
                "userId": 1,
                "accessToken":1,
                "count":{$size:"$notifications"},
                "notifications._id":1,
                "notifications.summaryId": 1,
                "notifications.dateCreated":1,
                "notifications.dateProcessed":1,
            }
        };

        var agg = [
            match,
            lookup,
            project,
            project2,
        ];

        Register.aggregate(agg)
        .then( ..... )
```

<h2>Expected Results</h2>

<p>I would like to have the notifications sorted by latest date to earliest date</p>

<p><strong>NOTE</strong>: It doesn't matter which "accessToken" is the first record... just that the dates of the notifications <em>in EACH accessToken record</em> are latest to earliest AND all of the data is present :</p>

<pre class="lang-js prettyprint-override"><code>[
  {
    "_id": "Reg_1",
    "accessToken": "a_1",
    "userId": "User_1",
    "count": 2,
    "notifications": [
      {
        "_id": "N1_2",
        "dateCreated": ISODate("2020-05-25T00:00:00Z"),
        "summaryId": 1112
      },
      {
        "_id": "N1_1",
        "dateCreated": ISODate("2020-04-17T00:00:00Z"),
        "summaryId": 1111
      }
    ]
  },
  {
    "_id": "Reg_2",
    "accessToken": "a_2",
    "userId": "User_2",
    "count": 2,
    "notifications": [
      {
        "_id": "N2_2",
        "dateCreated": ISODate("2020-05-26T00:00:00Z"),
        "summaryId": 2222
      },
      {
        "_id": "N2_1",
        "dateCreated": ISODate("2020-04-18T00:00:00Z"),
        "summaryId": 2221
      }
    ]
  }
]
</code>```

previous tries removed for brevity

Try 6

I am getting closer with this playground attempt, but

Try 6 close... but no cigar

I am getting this... instead of the expected results

[
  {
    "_id": {
      "accessToken": "a_2",
      "userId": "User_2"
    },
    "notifications": [
      {
        "_id": "N2_2",
        "dateCreated": "2020-05-26T00:00:00.000+00:00",
        "summaryId": 2222
      },
      {
        "_id": "N2_1",
        "dateCreated": "2020-04-18T00:00:00.000+00:00",
        "summaryId": 2221
      }
    ],
    "notifications_count": 2
  },
  {
    "_id": {
      "accessToken": "a_1",
      "userId": "User_1"
    },
    "notifications": [
      {
        "_id": "N1_2",
        "dateCreated": "2020-05-25T00:00:00.000+00:00",
        "summaryId": 1112
      },
      {
        "_id": "N1_1",
        "dateCreated": "2020-04-17T00:00:00.000+00:00",
        "summaryId": 1111
      }
    ],
    "notifications_count": 2
  }
]
```

Thanks!!

答:
You can use [$lookup , $unwind , $sort , $group] aggregation pipeline stages to sort the content of notification array. Example</p>

```<code>    db.Register.aggregate([
      {
        $lookup: {
          from: "my_Notifications",
          localField: "accessToken",
          foreignField: "accessToken",
          as: "notifications"
        }
      },
      {
       // cartesian product of array lengths
        $unwind: "$notifications"
      },
      {
        $sort: {
         // Sort the records by created date
          "notifications.dateCreated": -1
        }
      },
      {
        $group: {
          "_id": {
            "accessToken": "$accessToken",
            "userId": "$userId"
          },
          "notifications": {
            $push: "$notifications"
          },
          "notifications_count": {
            $sum: 1
          }
        }
      }
    ])
</code>```

Body:
I am VERY close to getting what I want out of this query... but now I want to sort on a notification field

NOTE: This is a refinement : I am now asking how to return SORT on notification fields, while my similar question asks how to return the data between a start and end date and my other similar question asks how to return only certain fields.

Register Schema

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const RegisterSchema = new Schema({
    userId: {type: Schema.Types.ObjectId, required: true},
    accessToken: {type:String, required: true, default: null},
})
module.exports = Register = mongoose.model( 'register', RegisterSchema)

Here is some register data

[
  {
    "_id": "Reg_1",
    "userId": "User_1",
    "accessToken": "a_1"
  },
  {
    "_id": "Reg_2",
    "userId": "User_2",
    "accessToken": "a_2"
  }
]

The next document contains data that is related to the Register schema via the accessToken

Notifications

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const NotificationSchema = new Schema({
    accessToken: {type:String, required: true},
    summaryId: {type:Number, required: true},
    dateCreated: {type: Date, default: Date.now},

    // I don't want these returned in the final results
    dontWantThis1: {type:Number, required: true},
    dontWantThis2: {type:Number, required: true},
})
module.exports = Notification = mongoose.model( 'notification', NotificationSchema)

Here is some notification data

[{
    "_id": "N1_1",
    "accessToken": "a_1",
    "summaryId": 1111,
    "dontWantThis1": 61,
    "dontWantThis2": 62,
    "dateCreated": "2020-04-17T00:00:00.000+00:00" },
  {
    "_id": "N2_1",
    "accessToken": "a_2",
    "summaryId": 2221,
    "dontWantThis1": 71,
    "dontWantThis2": 72,
    "dateCreated": "2020-04-18T00:00:00.000+00:00" },
  {
    "_id": "N1_2",
    "accessToken": "a_1",
    "summaryId": 1112,
    "dontWantThis1": 611,
    "dontWantThis2": 622,
    "dateCreated": "2020-05-25T00:00:00.000+00:00" },
  {
    "_id": "N2_2",
    "accessToken": "a_2",
    "summaryId": 2222,
    "dontWantThis1": 711,
    "dontWantThis2": 722,
    "dateCreated": "2020-05-26T00:00:00.000+00:00" }
]

Starting with this

This code returns everything I want... but doesn't sort the notifications by dateCreated showing the newest dates first.

        // make sure the input dates are REALLY date objects
        // I only want to see notifications for the month of May (in this example)
        var dateStart = new Date('2020-01-01T00:00:00.000+00:00');
        var dateEnd = new Date('2020-05-30T00:00:00.000+00:00');

        var match = {$match: { userId: mongoose.Types.ObjectId(userId) } };

        var lookup ={
            $lookup:
            {
                from: "my_Notifications",
                localField: "accessToken",
                foreignField: "accessToken",
                as: "notifications"
            }
        };

        var dateCondition = { $and: [
            { $gte: [ "$$item.dateCreated", dateStart ] },
            { $lte: [ "$$item.dateCreated", dateEnd ] }
          ]}

        var project = {
            $project: {
                notifications: {
                    $filter: {
                    input: "$notifications",
                    as: "item",
                    cond: dateCondition
                    } } }
        };

        var project2 = {
            $project: {
                "_id": 1,
                "userId": 1,
                "accessToken":1,
                "count":{$size:"$notifications"},
                "notifications._id":1,
                "notifications.summaryId": 1,
                "notifications.dateCreated":1,
                "notifications.dateProcessed":1,
            }
        };

        var agg = [
            match,
            lookup,
            project,
            project2,
        ];

        Register.aggregate(agg)
        .then( ..... )

Expected Results

I would like to have the notifications sorted by latest date to earliest date

NOTE: It doesn't matter which "accessToken" is the first record... just that the dates of the notifications in EACH accessToken record are latest to earliest AND all of the data is present :

[
  {
    "_id": "Reg_1",
    "accessToken": "a_1",
    "userId": "User_1",
    "count": 2,
    "notifications": [
      {
        "_id": "N1_2",
        "dateCreated": ISODate("2020-05-25T00:00:00Z"),
        "summaryId": 1112
      },
      {
        "_id": "N1_1",
        "dateCreated": ISODate("2020-04-17T00:00:00Z"),
        "summaryId": 1111
      }
    ]
  },
  {
    "_id": "Reg_2",
    "accessToken": "a_2",
    "userId": "User_2",
    "count": 2,
    "notifications": [
      {
        "_id": "N2_2",
        "dateCreated": ISODate("2020-05-26T00:00:00Z"),
        "summaryId": 2222
      },
      {
        "_id": "N2_1",
        "dateCreated": ISODate("2020-04-18T00:00:00Z"),
        "summaryId": 2221
      }
    ]
  }
]

previous tries removed for brevity

Try 6

I am getting closer with this playground attempt, but

Try 6 close... but no cigar

I am getting this... instead of the expected results

[
  {
    "_id": {
      "accessToken": "a_2",
      "userId": "User_2"
    },
    "notifications": [
      {
        "_id": "N2_2",
        "dateCreated": "2020-05-26T00:00:00.000+00:00",
        "summaryId": 2222
      },
      {
        "_id": "N2_1",
        "dateCreated": "2020-04-18T00:00:00.000+00:00",
        "summaryId": 2221
      }
    ],
    "notifications_count": 2
  },
  {
    "_id": {
      "accessToken": "a_1",
      "userId": "User_1"
    },
    "notifications": [
      {
        "_id": "N1_2",
        "dateCreated": "2020-05-25T00:00:00.000+00:00",
        "summaryId": 1112
      },
      {
        "_id": "N1_1",
        "dateCreated": "2020-04-17T00:00:00.000+00:00",
        "summaryId": 1111
      }
    ],
    "notifications_count": 2
  }
]

Thanks!!

Body:
You can use [$lookup , $unwind , $sort , $group] aggregation pipeline stages to sort the content of notification array. Example

    db.Register.aggregate([
      {
        $lookup: {
          from: "my_Notifications",
          localField: "accessToken",
          foreignField: "accessToken",
          as: "notifications"
        }
      },
      {
       // cartesian product of array lengths
        $unwind: "$notifications"
      },
      {
        $sort: {
         // Sort the records by created date
          "notifications.dateCreated": -1
        }
      },
      {
        $group: {
          "_id": {
            "accessToken": "$accessToken",
            "userId": "$userId"
          },
          "notifications": {
            $push: "$notifications"
          },
          "notifications_count": {
            $sum: 1
          }
        }
      }
    ])


问:
How to configure S3 bucket policies for my app
I have a bucket called prod, with a directory tree that looks like this:

```<code>prod
 logs
 uploads
  user
   doc
    1
     a.jpg
     b.jpg
    2
     a.jpg
     b.jpg
  thing
   photos
    1
     a.jpg
     b.jpg
    2
     a.jpg
     b.jpg
</code>```

Everything in thing/photos should be public. GET requests should be allowed for everyone, but PUT and POST requests should only be allowed when users upload a file through my app.

The user/doc directory on the other hand, I want to be completely private. POST requests should be allowed for users who upload a file through my app, but the only person who should be able to GET those resources is an admin. That data is encrypted before it is stored, but I want to make sure that the folder is not accessible to the public or to other users of my app.

After reading A deep dive into AWS S3 access controls – taking full control over your assets and ACLs - What Permissions Can I Grant? I remain confused about how to accomplish what I want. The overlapping access controls leave me feeling bewildered, and I cannot find a tutorial that explains any of this in an action-oriented approach. Given the number of data leaks caused by improperly set S3 bucket policies, it seems likely that I'm not the only person who misunderstands this.

How are your policies set? Do you have a link to a better tutorial than the ones I've found? Thank you!

答:
Amazon S3 buckets are private by default. Therefore, access is only available if you specifically configure access.

Everything in thing/photos should be public

If you wish to make an entire bucket, or part of a bucket public, use a Bucket Policy.

Copying from @avlazarov's answer:

```<code>{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"Example",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::examplebucket/things/photos/*"]
      }
  ]
}
</code>```

This means:

Allow anyone

To GetObject, meaning read an object

As long as it is in the bucket named examplebucket, in the things/photos/ path

Please note that they will not be able List the contents of the path, so they will need to know the exact name of the object they are retrieving.

Before adding a Bucket Policy, you will need to deactivate the setting in Amazon S3 block public access that prevents Bucket Policies being added.

General rule: When granting public access, use a Bucket Policy.

The user/doc directory should be completely private

Amazon S3 buckets are private by default. Therefore, nothing needs to be done.

However, you then mention that the mobile app should have access. Such permissions should be granted via Identity and Access Management (IAM) settings.

Since you mention 'users', there is probably some authentication method being used by your app, presumably to a back-end service. Therefore, rather than putting IAM credentials directly in the app, the flow should be:

User logs into the app

The app sends the authentication information to a back-end service that authenticates the user (could be Cognito, login with Google or even just your own database)

If the user is verified, then the back-end service would generate temporary credentials using the AWS Security Token Service (STS). A policy can be attached to these credentials, granting sufficient permissions for the user and app for this particular session. For example, it could grant access to a path (sub-directory) so that the user can only access objects in their own sub-directory.

It is preferable to only grant the app (and therefore the user) the minimal amount of permissions required to use the service. This avoids intentional or accidental problems that might be caused by providing too much access.

General rule: Only provide mobile apps the minimum permissions they require. Assume that accidents or intentional hacking will happen.

The only person who should be able to GET those resources is an Admin

When granting access to your own staff, use policies attached to an IAM User or IAM Group.

I would recommend:

Create an IAM Group for Admins

Attach an IAM policy to the Group that grants desired access

Create an IAM User for each of your staff admins

Put their IAM User in the IAM Group

This way, all admins (including future ones) will obtain appropriate access, and you can track what each IAM User did independently. Never have multiple staff use the same logins. It would also be advisable to associate a Multi-factor Authentication device to each admin account since the permissions could be dangerous if access was compromised. MFA can be as simple as running an authentication app on a phone that provides a number that changes every 30 seconds.

In fact, some companies only give the Admins 'normal' accounts (without superpowers). Then, if they need to do something extraordinary, they have the Admins temporarily switch to an IAM Role that gives 'admin' capabilities. This minimizes the chance of accidentally doing something that might have an impact on the system.

General rule: Use IAM to grant access to staff within your organization.

If you wish to learn more about IAM, I would highly recommend IAM videos from the annual AWS re:Invent conference. For a complete list of sessions, see: AWS re:Invent 2019 Sessions & Podcast Feed

Body:
I have a bucket called prod, with a directory tree that looks like this:

prod
 logs
 uploads
  user
   doc
    1
     a.jpg
     b.jpg
    2
     a.jpg
     b.jpg
  thing
   photos
    1
     a.jpg
     b.jpg
    2
     a.jpg
     b.jpg

Everything in thing/photos should be public. GET requests should be allowed for everyone, but PUT and POST requests should only be allowed when users upload a file through my app.

The user/doc directory on the other hand, I want to be completely private. POST requests should be allowed for users who upload a file through my app, but the only person who should be able to GET those resources is an admin. That data is encrypted before it is stored, but I want to make sure that the folder is not accessible to the public or to other users of my app.

After reading A deep dive into AWS S3 access controls – taking full control over your assets and ACLs - What Permissions Can I Grant? I remain confused about how to accomplish what I want. The overlapping access controls leave me feeling bewildered, and I cannot find a tutorial that explains any of this in an action-oriented approach. Given the number of data leaks caused by improperly set S3 bucket policies, it seems likely that I'm not the only person who misunderstands this.

How are your policies set? Do you have a link to a better tutorial than the ones I've found? Thank you!

Body:
Amazon S3 buckets are private by default. Therefore, access is only available if you specifically configure access.

Everything in thing/photos should be public

If you wish to make an entire bucket, or part of a bucket public, use a Bucket Policy.

Copying from @avlazarov's answer:

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"Example",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::examplebucket/things/photos/*"]
      }
  ]
}

This means:

Allow anyone

To GetObject, meaning read an object

As long as it is in the bucket named examplebucket, in the things/photos/ path

Please note that they will not be able List the contents of the path, so they will need to know the exact name of the object they are retrieving.

Before adding a Bucket Policy, you will need to deactivate the setting in Amazon S3 block public access that prevents Bucket Policies being added.

General rule: When granting public access, use a Bucket Policy.

The user/doc directory should be completely private

Amazon S3 buckets are private by default. Therefore, nothing needs to be done.

However, you then mention that the mobile app should have access. Such permissions should be granted via Identity and Access Management (IAM) settings.

Since you mention 'users', there is probably some authentication method being used by your app, presumably to a back-end service. Therefore, rather than putting IAM credentials directly in the app, the flow should be:

User logs into the app

The app sends the authentication information to a back-end service that authenticates the user (could be Cognito, login with Google or even just your own database)

If the user is verified, then the back-end service would generate temporary credentials using the AWS Security Token Service (STS). A policy can be attached to these credentials, granting sufficient permissions for the user and app for this particular session. For example, it could grant access to a path (sub-directory) so that the user can only access objects in their own sub-directory.

It is preferable to only grant the app (and therefore the user) the minimal amount of permissions required to use the service. This avoids intentional or accidental problems that might be caused by providing too much access.

General rule: Only provide mobile apps the minimum permissions they require. Assume that accidents or intentional hacking will happen.

The only person who should be able to GET those resources is an Admin

When granting access to your own staff, use policies attached to an IAM User or IAM Group.

I would recommend:

Create an IAM Group for Admins

Attach an IAM policy to the Group that grants desired access

Create an IAM User for each of your staff admins

Put their IAM User in the IAM Group

This way, all admins (including future ones) will obtain appropriate access, and you can track what each IAM User did independently. Never have multiple staff use the same logins. It would also be advisable to associate a Multi-factor Authentication device to each admin account since the permissions could be dangerous if access was compromised. MFA can be as simple as running an authentication app on a phone that provides a number that changes every 30 seconds.

In fact, some companies only give the Admins 'normal' accounts (without superpowers). Then, if they need to do something extraordinary, they have the Admins temporarily switch to an IAM Role that gives 'admin' capabilities. This minimizes the chance of accidentally doing something that might have an impact on the system.

General rule: Use IAM to grant access to staff within your organization.

If you wish to learn more about IAM, I would highly recommend IAM videos from the annual AWS re:Invent conference. For a complete list of sessions, see: AWS re:Invent 2019 Sessions & Podcast Feed


问:
Python - not enough values to unpack from tensorflow dataset
Following the Tensorflow example.

```<code>TRAIN_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/train.csv"
LABEL_COLUMN_TRAIN = 'Survived'
train_file_path = tf.keras.utils.get_file("train.csv", TRAIN_DATA_URL)
SELECT_COLUMNS = ['Survived', 'Age', 'SibSp', 'Fare']
DEFAULTS = [0, 0.0, 0.0, 0.0]
temp_dataset = get_dataset(
    train_file_path,
    label_column_name=LABEL_COLUMN_TRAIN,
    select_columns=SELECT_COLUMNS,
    column_defaults=DEFAULTS
)

def pack(features, label):
  return tf.stack(list(features.values()), axis=-1), label

packed_dataset = temp_dataset.map(pack)
for features, labels in packed_dataset.take(1):
  print(features.numpy())
  print(labels.numpy())
</code>```

This shows below.

```<code>[[ 0.     1.    15.5  ]
 [30.     3.    21.   ]
 [ 0.     0.     7.896]
 [21.     0.     8.663]
 [39.     0.     7.925]]
[0 1 0 0 0]
</code>```

Question

Please help understand the cause of the error.

I believe packed_dataset.take(1) returns a tuple of two element.

```<code>packed_dataset.take(1)
<TakeDataset shapes: ((None, 3), (None,)), types: (tf.float32, tf.int32)>
</code>```

However, below causes the error.

```<code>(features, labels) = packed_dataset.take(1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-125-dceb31d47f78> in <module>
----> 1 features, labels = packed_dataset.take(1)

ValueError: not enough values to unpack (expected 2, got 1)
</code>```

答:
the function
pack(feature, labels)
require 2 arguments, while function call
for features, labels in packed_dataset.take(1)
passes only one argument with the value 1, it should expect
for features, labels in packed_dataset.take(1, ?)

Body:
Following the Tensorflow example.

TRAIN_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/train.csv"
LABEL_COLUMN_TRAIN = 'Survived'
train_file_path = tf.keras.utils.get_file("train.csv", TRAIN_DATA_URL)
SELECT_COLUMNS = ['Survived', 'Age', 'SibSp', 'Fare']
DEFAULTS = [0, 0.0, 0.0, 0.0]
temp_dataset = get_dataset(
    train_file_path,
    label_column_name=LABEL_COLUMN_TRAIN,
    select_columns=SELECT_COLUMNS,
    column_defaults=DEFAULTS
)

def pack(features, label):
  return tf.stack(list(features.values()), axis=-1), label

packed_dataset = temp_dataset.map(pack)
for features, labels in packed_dataset.take(1):
  print(features.numpy())
  print(labels.numpy())

This shows below.

[[ 0.     1.    15.5  ]
 [30.     3.    21.   ]
 [ 0.     0.     7.896]
 [21.     0.     8.663]
 [39.     0.     7.925]]
[0 1 0 0 0]

Question

Please help understand the cause of the error.

I believe packed_dataset.take(1) returns a tuple of two element.

packed_dataset.take(1)
<TakeDataset shapes: ((None, 3), (None,)), types: (tf.float32, tf.int32)>

However, below causes the error.

(features, labels) = packed_dataset.take(1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-125-dceb31d47f78> in <module>
----> 1 features, labels = packed_dataset.take(1)

ValueError: not enough values to unpack (expected 2, got 1)


问:
Is it possible to automate MySQL using python?
I am a beginner to python and programming in general. But I've been wondering if it is possible to write a python script that would automate tasks on MySQL, like creating new database, user, table etc. For example I would ask the user for name input and after that I would want my script to automatically create a name_db database. I forgot to add that I need the commands not only to execute but to show on my cmd one after another like I wrote them manually. Is it possible to do? </p>

答:
Yes, I posted a link below demonstrating someone issuing sql queries using python code. This is performed using parameters:

https://towardsdatascience.com/a-simple-approach-to-templated-sql-queries-in-python-adc4f0dc511


问:
How do I match numbers and create 2-dimensional array?
I have an array like so [1.2, 1.3, 1.4, 2.2, 2.3, 3.0, 4.3, 4.4, 4.5, 4.6, 4.7]

How can I turn it into a 2-dimensional array that's based on matching numbers before the decimal?

ex.[[1.2, 1.3, 1.4], [2.2, 2.3], [3.0], [4.3, 4.4, 4.5, 4.6, 4.7]]

答:
You can use Array.reduce to do this, building an array using indexes based on the integer portion of each value:

arr = [1.2, 1.3, 1.4, 2.2, 2.3, 3.0, 4.3, 4.4, 4.5, 4.6, 4.7];

let res = arr.reduce((c, v) => {
  i = Math.trunc(v) - 1;
  c[i] = c[i] || [];
  c[i].push(v);
  return c;
}, []);

console.log(res);```
</div>
</div>
</p>

<p>If you could have values starting at 0, or gaps in the values, you can use a similar piece of code and then use <code>Object.values()</code> to just extract the filled in arrays:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>arr = [0.2, 1.3, 1.4, 2.2, 2.3, 3.0, 4.3, 4.4, 4.5, 6.6, 8.7];

res = arr.reduce((c, v) => {
  i = Math.trunc(v);
  c[i] = c[i] || [];
  c[i].push(v);
  return c;
}, []);
res = Object.values(res)
console.log(res);</code>```

Body:
You can use Array.reduce to do this, building an array using indexes based on the integer portion of each value:

arr = [1.2, 1.3, 1.4, 2.2, 2.3, 3.0, 4.3, 4.4, 4.5, 4.6, 4.7];

let res = arr.reduce((c, v) => {
  i = Math.trunc(v) - 1;
  c[i] = c[i] || [];
  c[i].push(v);
  return c;
}, []);

console.log(res);

If you could have values starting at 0, or gaps in the values, you can use a similar piece of code and then use Object.values() to just extract the filled in arrays:

arr = [0.2, 1.3, 1.4, 2.2, 2.3, 3.0, 4.3, 4.4, 4.5, 6.6, 8.7];

res = arr.reduce((c, v) => {
  i = Math.trunc(v);
  c[i] = c[i] || [];
  c[i].push(v);
  return c;
}, []);
res = Object.values(res)
console.log(res);


问:
Still not understanding .this after reading articles
I'm a JS/React beginner who has read a few articles on the this keyword on JS, but remain confused.
Namely, I've consulted Tyler McGinnis's React and The Complete Javascript on Udemy.

This keyword is a fairly complex topic imo, but from these two sources I know .this refers to the global scope by default, but refers to the object in question when it is defined within a method. I also know that .call/apply/bind can give us a hint on what the .this refers to.

My question is, when do you actually write the .this keyword when you are writing your programs? The sources above seemed to focus on understanding why others might've used the keyword, but not necessarily when you need to do it. Thus, I always get confused when tutorials seemingly randomly throw in a this/bind etc everywhere

In terms of specific examples, I have :
1. One in the context of states:

I've encountered apps before learning about the .this concept which do not use the .this keyword. No specific examples for this, but shouldn't you use .this most of the time then?

Apologies if this is a silly question -- sometimes I wonder whether it is better to analyze/dissect the rationale for each part in coding or just to learn coding as just the way things are much like a child learns a language naturally without questioning grammar rules

In this example, we are passing down a prop called onDelete, but I do not understand why we need to bind. Does this mean we are binding the passed down onDelete to props.id which was also passed down?

答:
The important part is you took the time to research. Personally I do not recommend using React to learn about this. When you extend a React component, your this prototype inherits from React.Component, so there's a lot of React-specific conventions there already. Instead, consider this example where I call this directly

function SimpleQueue({ size }) {
  this.size = size
  this.buffer = []
}

SimpleQueue.prototype.push = function(item) {
  this.buffer.push(item)
  if (this.buffer.length > this.size) {
    this.buffer.shift()
  }
  return this
}
```

<p><code>SimpleQueue</code> is just a simple queue implementation using an internal array. You can think of <code>this</code> as a reference to the current instance of <code>SimpleQueue</code>, whatever that may be. I use <code>this</code> specifically in the example above to access the internal array as <code>this.buffer</code>. I can then use an instance of a <code>SimpleQueue</code> like so</p>

<pre class="lang-js prettyprint-override"><code>const mySimpleQueue = new SimpleQueue({ size: 3 })
mySimpleQueue.push(1) // SimpleQueue { 1 }
mySimpleQueue.push(2) // SimpleQueue { 1, 2 }
mySimpleQueue.push(3) // SimpleQueue { 1, 2, 3 }
mySimpleQueue.push(4) // SimpleQueue { 2, 3, 4 }
</code>```

Note: my example does not use class, but it is the same because classes are syntactic sugar for the prototype-based programming model

Body:
The important part is you took the time to research. Personally I do not recommend using React to learn about this. When you extend a React component, your this prototype inherits from React.Component, so there's a lot of React-specific conventions there already. Instead, consider this example where I call this directly

function SimpleQueue({ size }) {
  this.size = size
  this.buffer = []
}

SimpleQueue.prototype.push = function(item) {
  this.buffer.push(item)
  if (this.buffer.length > this.size) {
    this.buffer.shift()
  }
  return this
}

SimpleQueue is just a simple queue implementation using an internal array. You can think of this as a reference to the current instance of SimpleQueue, whatever that may be. I use this specifically in the example above to access the internal array as this.buffer. I can then use an instance of a SimpleQueue like so

const mySimpleQueue = new SimpleQueue({ size: 3 })
mySimpleQueue.push(1) // SimpleQueue { 1 }
mySimpleQueue.push(2) // SimpleQueue { 1, 2 }
mySimpleQueue.push(3) // SimpleQueue { 1, 2, 3 }
mySimpleQueue.push(4) // SimpleQueue { 2, 3, 4 }

Note: my example does not use class, but it is the same because classes are syntactic sugar for the prototype-based programming model


问:
What does pipe `|` operator do in case expression of elm-lang?
I have this following code snippet in my Elm code:

```<code>type alias Model =
  { content : String
  }

update : Msg -> Model -> Model
update msg model =
  case msg of
    Change newContent ->
      { model | content = newContent }
</code>```

What does { model | content = newContent } do?
Does it assign (bind) the value of newContent to model as well as content? Is that why the |  operator is placed there?

答:
Read | as 'with'.

```<code>{ model 'with' content (set to) = newContent }
</code>```

Body:
I have this following code snippet in my Elm code:

type alias Model =
  { content : String
  }

update : Msg -> Model -> Model
update msg model =
  case msg of
    Change newContent ->
      { model | content = newContent }

What does { model | content = newContent } do?
Does it assign (bind) the value of newContent to model as well as content? Is that why the |  operator is placed there?

Body:
Read | as 'with'.

{ model 'with' content (set to) = newContent }